|
本帖最后由 Mozilla 于 2020-5-3 16:02 编辑 . c7 W6 n' R- R3 e- w
* G! J0 ^3 G# W( Z+ hsublime_text3组件Sublime_plugin源代码免费分享!请不要翻译此页!
+ J$ a2 ~- C G$ n& B- import imp
* X, h0 N: `3 N" D5 L+ j - import importlib8 o3 f5 ~# _# c; a. A8 F
- import os" O# {" Q* a$ }& A$ l
- import sys
2 J2 ^" e$ P4 m( A# J - import threading' ^3 L5 i0 N$ G. W4 r- W, d
- import time, L% @: R" y6 h3 ~9 I
- import traceback
6 Q/ T w7 w$ K) [ - import zipfile
5 o3 z$ @7 ^6 N$ m% r
* a0 m* f1 l( A# C( q- import sublime
! [, d( ~( k, v - import sublime_api
0 L' @! n# D! q0 L+ t
9 S4 b$ Z# q7 @! s: p/ E
% G6 `; ]5 A. Y8 x- api_ready = False
8 r9 e N: r; |1 P! l# t
6 C* c9 ?1 Z$ j1 i. ^- application_command_classes = []5 V- m5 g% c7 d; a5 D; ?8 u& J
- window_command_classes = []8 ^ ]: |# I- I' v( z. Q
- text_command_classes = []+ R9 ~2 y' Y& b
- . ~0 F. h! |( q6 v
- view_event_listener_classes = []
5 r0 I0 p2 V9 ^8 p3 P" [3 Q! Y - view_event_listeners = {}3 V& o, w& K* V" g1 L' o5 w. f
7 ~8 L& a" s. X- all_command_classes = [
2 i' A6 y% P8 c+ q' f6 D | - application_command_classes,
, y0 H0 G6 A4 _2 U3 T5 k - window_command_classes,
: Q( f7 L; H- }" T5 | - text_command_classes]' r3 N$ C% c' _
- ( e7 H! p$ S6 k4 s) u
- all_callbacks = {
) w) w9 Q9 [' V: Q0 ~' a - 'on_new': [],5 C' J8 \! g6 @" N/ x* N1 s. s @
- 'on_clone': [],& M! `: ^/ C# V5 C+ z
- 'on_load': [],
! ]$ ` u/ [2 j. S, h0 K - 'on_pre_close': [],
' O+ Z4 I3 P4 }# A y8 U% O - 'on_close': [],9 U7 U }2 r$ T1 o7 X
- 'on_pre_save': [],
9 W% n$ V7 \8 D% S& {' R - 'on_post_save': [],
! d0 k. W' U2 s* ~& r - 'on_modified': [],
4 q8 g$ V; f" Y5 T - 'on_selection_modified': [],
1 W, Q0 Z3 Q3 }% H& O: h+ J- i3 R! M - 'on_activated': [],3 `* T* a4 h% G; b" Z6 e
- 'on_deactivated': [],' L" s6 J* s# p" u7 G4 ~- _
- 'on_query_context': [],
2 n2 [' q3 d( d0 y/ L) N - 'on_query_completions': [],
! x" o) \+ P- G4 r: h: y( z& q - 'on_hover': [],8 J/ e9 f" ? D, Z: m& b
- 'on_text_command': [],. C6 u7 ?# e T3 A' i. ?3 m( e
- 'on_window_command': [],
4 z2 W+ ]0 B8 D; D. \3 Q Z - 'on_post_text_command': [],, T$ M: j4 k4 y6 I9 j: n1 Q, g0 G
- 'on_post_window_command': [],
7 R C4 ?# y/ M& O4 w - 'on_modified_async': [],6 o% `! f# \) u) ^
- 'on_selection_modified_async': [],
* f( R! C& h" `, [$ T. I" K - 'on_pre_save_async': [],
: s# z/ _& p4 E9 Z2 S& X4 J - 'on_post_save_async': [],. k' O" v( ]& f$ V: `. B5 i
- 'on_activated_async': [],
5 k! D, y. _. i4 o- W L- b - 'on_deactivated_async': [],+ D5 z( h2 f9 y, W$ Z, E
- 'on_new_async': []," s/ Q/ V& V+ P) {
- 'on_load_async': [],5 ]3 I: _, H8 ?. z+ O( ?8 M
- 'on_clone_async': []}
, E2 i8 }6 {0 {- G1 l - * ?0 K: z6 w+ a4 J, D- W
- pending_on_activated_async_lock = threading.Lock()
3 y. O1 M6 y7 d2 o6 h" @ - ) N/ a4 T# z: Q$ N2 o" b) ]: T
- pending_on_activated_async_callbacks = {4 Q0 u( Q& j6 w# i
- 'EventListener': [],
# T- t6 a7 F9 J" E0 L$ x3 x - 'ViewEventListener': []}
( N. F6 A3 l7 }5 v$ z - k4 c# ^0 E# \
- profile = {}
6 n2 C9 K. H8 z% T - 1 y2 q5 {% \% w% [) D" U; G
- ; |: M+ A3 A! G4 E8 `" k
- def unload_module(module):" ]& {/ G Q, \) q" m
- if "plugin_unloaded" in module.__dict__:8 r! r; q y+ @4 `+ [+ g0 C& l
- module.plugin_unloaded(); E: r& H/ W& A: ]
- # Check unload_handler too, for backwards compat( P& u6 J) p4 y
- if "unload_handler" in module.__dict__:% J% z1 V- H, L
- module.unload_handler()
9 a7 @3 }8 o; U% N4 s' Z/ S - : R+ I5 b7 ~ Z- F, H; f
- # Unload the old plugins
1 s7 d6 y2 g1 f2 ?1 L+ y6 c; J - if "__plugins__" in module.__dict__:
$ U& R( C5 {& H, U* ~ - for view_id, listener_instances in view_event_listeners.items():) R3 X5 H2 _9 R* o, {0 J! p
- for vel in listener_instances[:]:& S. R: ~# P5 Q9 G
- if vel.__class__ in module.__plugins__:, Q) d* d8 `* p/ {) p* B/ O
- listener_instances.remove(vel)
& K: d% L8 z& e6 Y9 s7 |/ |, e4 ]
; a/ n ]* p% p9 t- for p in module.__plugins__:
- {! ]& O% Y( ?4 t - for cmd_cls_list in all_command_classes:
& l! ~4 n/ P5 `8 m- c, z9 G3 n3 }; P - try:
- Q$ _5 t$ s8 R! f T - cmd_cls_list.remove(p)! }% m' d) @5 Y* ?
- except ValueError:
# ]% ?" G# }- ^% ]1 b - pass
: g) i& Q' d Z# @# H1 J - for c in all_callbacks.values():
: o! ~/ n2 D ]( I/ K2 w, b7 A - try:
% }1 j/ N" e6 b& q. d& s. p - c.remove(p)+ K9 K3 b& D" l" f4 I1 l$ [
- except ValueError:
@8 P1 ^$ W7 n7 V, b7 x# ]2 k$ | - pass
* {% q- p8 u! q - # }3 R# k0 i0 G
- try:* w0 _6 i( z/ c/ c
- view_event_listener_classes.remove(p)
4 ^* S% H! [8 L. B3 ^, h- b- p - except ValueError:4 B t: T) \" W. L! H+ e" a
- pass
% D0 i b. J h - ! k! T; k! m$ P- ~
: F2 Y) Z- a' U- y' {% [$ l- def unload_plugin(modulename):
8 M8 \- h7 _) A' l* m/ y - print("unloading plugin", modulename)
: ]' U f; | J0 L
9 [$ A8 A$ e* {, u- was_loaded = modulename in sys.modules! M6 q7 p9 w% N( W* \
- if was_loaded:% M3 s$ T2 Z4 d
- m = sys.modules[modulename]
. ?$ G g3 s( r2 u4 { - unload_module(m)0 F1 W2 s P4 i8 c2 V4 _4 J
- del sys.modules[modulename]+ o7 D( C0 j7 l" F% B+ y$ i3 y
* p ]' y; H; L# k3 \8 ]0 L- 8 V/ D+ O5 k8 I- I# T8 Y
- def reload_plugin(modulename):
$ e# w; E- [# ?. V* d - print("reloading plugin", modulename)* U. B4 ~* ^" z P4 U1 f( M% X
- ; d/ v$ {; s6 K; s
- if modulename in sys.modules:
' D# R6 ?2 V: x# S3 v6 l; l - m = sys.modules[modulename]1 e3 B ~. R' B( h4 c' ~/ a
- unload_module(m)$ Q }/ E$ | Z2 d6 t [
- m = imp.reload(m)0 ]+ N3 W1 z( G& m0 }
- else:2 ] K: }/ Q: g& n+ q: V" w/ J
- m = importlib.import_module(modulename)
/ u9 I: H0 w. l0 L) m4 h - ! T+ R/ ~/ i2 Q. q B( Z% {$ r9 F' O1 K
- module_plugins = []) j& \- ~1 q5 E. G% V
- on_activated_targets = []; c6 G! [0 _2 N) F
- vel_on_activated_classes = []
# G' e( t8 e$ f1 O6 b - el_on_activated_async_targets = []
% |1 b* b- E; c9 U - vel_on_activated_async_targets = []
6 `9 w/ h: H7 |- i1 a' w1 r - module_view_event_listener_classes = []
3 Z" {, C5 k2 f* D2 G - for type_name in dir(m):3 S5 f) t3 r' K# X! \+ G, W+ n+ f
- try:1 g' e; X) I5 p9 D1 _
- t = m.__dict__[type_name]: O9 K& Z5 r4 o4 _2 b# N; S
- if t.__bases__:6 v# Q# G" l6 \/ l! t1 B
- is_plugin = False
% ~% B: k, y# J4 E. j+ M - if issubclass(t, ApplicationCommand):+ Q/ `5 o( L |+ ^( a' K) _
- application_command_classes.append(t) V ]9 f7 @' d. M) `
- is_plugin = True) Y0 l7 i" X* K4 S; B; \6 c N9 p
- if issubclass(t, WindowCommand):
/ n( G6 n( m" t2 q+ [, b - window_command_classes.append(t)" E' J9 z! R% n; Z* C2 T( ^
- is_plugin = True3 ]2 P3 p& ^9 m) J( `
- if issubclass(t, TextCommand):
9 ^3 }' A) B& p2 j7 E5 J( H - text_command_classes.append(t); H8 k( i2 W2 P2 H
- is_plugin = True
5 p* H5 }2 a( s7 T
4 }" M" Z& L* V- if is_plugin:- R c3 n7 ]& h/ W% H% c' B7 S! t3 Z4 R
- module_plugins.append(t)' N* Z9 M( v1 m8 V5 {' c6 T
# h, @" K" M. z! z o. `- r- if issubclass(t, EventListener):
* ?8 a" A: Z" Y! ~ - obj = t()5 K- v" |! j/ t) T! _- O9 B
- for p in all_callbacks.items():% v0 M. J7 Y, T. `, P1 ]
- if p[0] in dir(obj):
R5 U9 {& J' Y' k* e1 X2 x0 k1 G! { - p[1].append(obj)
) j6 n+ ?- S8 j0 z, \' r& n
- g2 E# }( }" l6 A/ g- if "on_activated" in dir(obj):
# d8 X5 r$ s: K- r n% K, g - on_activated_targets.append(obj)
# S1 o( B7 [2 I% B+ M# B - $ s% m) y1 t) b
- if "on_activated_async" in dir(obj):3 y, u T0 l2 }4 x* z, i6 n
- el_on_activated_async_targets.append(obj)& [: q% `8 o7 L
9 t! y9 p# F5 O" |( B+ T1 R) @- module_plugins.append(obj)% V& C0 P0 P4 k& W
- * h8 Y0 ~% |$ K; \+ U$ o
- if issubclass(t, ViewEventListener):+ X! {% a% Q9 C( ^6 ~- W8 t$ E
- view_event_listener_classes.append(t)
9 x9 _9 Q1 n- j* f. O! q9 K5 N - module_view_event_listener_classes.append(t)
5 U- `2 t- Y- P' U. k/ ]5 x$ l - if "on_activated" in dir(t):
# L- f+ \$ q8 V( m# U - vel_on_activated_classes.append(t)8 p8 }) c, n7 Z- z
- if "on_activated_async" in dir(t):
8 A' b8 V! k2 ]6 t - vel_on_activated_async_targets.append(t)
9 X7 Z+ o% l4 \) U" W - module_plugins.append(t)
5 k: `0 k1 l( |
0 H0 M% r# |6 p9 k- except AttributeError:) d: B8 X$ c- P+ T
- pass; E* k2 K0 T, U) [8 S: `% n3 e
7 z% ]4 q: x$ ]: a1 R7 b; T* C- if el_on_activated_async_targets or vel_on_activated_async_targets:0 d% U* F3 y ]
- with pending_on_activated_async_lock:9 z) P& e9 \+ ~; j# s$ H0 m
- pending_on_activated_async_callbacks['EventListener'].extend(8 D, C# R( R; Y$ _* {5 l/ n
- el_on_activated_async_targets
3 E5 j9 w) ]; h( G0 L3 ? - ). j. D5 f, X0 X2 O1 W
- pending_on_activated_async_callbacks['ViewEventListener'].extend(
* Y6 K* P- [2 h% i: `2 M8 e - vel_on_activated_async_targets0 v' i8 A8 Y% L) R7 _- l
- )
% ~6 I' M& D( X4 A: \
2 @3 ]: l$ r5 b% A- if len(module_plugins) > 0:9 D4 J5 i* I0 ?! E0 _# r9 G4 q
- m.__plugins__ = module_plugins
) U4 v3 I; z' Q/ p
3 ~/ `* R* `8 w" ~- if api_ready:) M- J( g) x6 m4 b
- if "plugin_loaded" in m.__dict__:8 C0 H- }. h% G$ @4 c8 N
- try:
' }& p5 l$ @6 ~1 K* s7 X" ` - m.plugin_loaded()1 u4 } ?7 I0 t* ]# K
- except:
$ E8 s) z( k% C - traceback.print_exc()
3 K" x' u/ u" r1 _" Y - : c$ @/ Q3 w x+ z; e M
- # Create any require ViewEventListener objects( J* U/ A& H) c$ ^! x5 B
- if len(module_view_event_listener_classes) > 0:9 M5 A/ m6 L; D2 v( Z0 U
- for w in sublime.windows():. f$ P$ w3 U( r- {0 I
- for v in w.views():5 G# y# s1 F5 x; {6 Y' W' e
- create_view_event_listeners(
O3 P. Y/ r$ s* a5 t4 Y - module_view_event_listener_classes, v)
. e6 t3 S* l+ n2 { - + W, C8 Q8 K+ T6 A
- # Synthesize any required on_activated calls2 Y' G# c) @+ Y1 t* f# e
- w = sublime.active_window() m5 ?3 g# a- k; q3 e' `
- if w:0 U( Z' i& n+ t! L# S5 }0 Z
- v = w.active_view()5 H; W4 X- ^1 p N3 J; F+ i
- if v:
; c4 U* g8 u# c - for el in on_activated_targets:4 }& y/ u) y D9 }
- try:( @4 d2 o* ~! F$ c9 ?$ d- k
- el.on_activated(v)! b# P: f& N( V0 G
- except:" f0 N2 r4 H* F& a# g# D" _
- traceback.print_exc()
6 _% I; v2 f7 b! ?( ?
6 |+ Y4 D, T0 G- for vel_cls in vel_on_activated_classes:) R0 ~5 a$ i/ o! s. r* b3 `
- vel = find_view_event_listener(v, vel_cls)
- p' {$ w5 r& v& A/ Z, N - if not vel:
: D Z' v0 g N5 Q& Q0 k7 n - continue
+ r, M: G- v6 O4 Z+ k3 L+ X - try:
% h( T% h9 k# ?) J( s - vel.on_activated()
$ a& B: e9 n2 j: [9 f, n' z& d - except:
) n7 M" s8 x& d2 N - traceback.print_exc()" i6 p; N6 I1 E8 l: X: T0 Y
- b6 z: H" O6 j% y- " i4 O& O8 H/ `0 d( {
- def synthesize_on_activated_async():( j; F9 y, X! o9 P! W/ b G" d/ ~
- if not api_ready:
2 a8 ^) o, D: B, q/ m4 b - return4 Q) g$ H' @& T, d$ _# ~
- o6 T; q2 j0 M; N
- with pending_on_activated_async_lock:
- L0 _9 n% b4 C# x' n - els = pending_on_activated_async_callbacks['EventListener']* A( ?; K) s [2 Z
- vels = pending_on_activated_async_callbacks['ViewEventListener']
7 z# H7 ^+ S. r' t S4 p - pending_on_activated_async_callbacks['EventListener'] = [] b4 n, {$ p) F0 f+ b) C+ z
- pending_on_activated_async_callbacks['ViewEventListener'] = []
! I' `. [. a/ K8 S" q7 p - ' {0 i, i% R" F: \1 f
- for el in els:
# W s5 | e+ x4 }, d# b - w = sublime.active_window()4 k2 l: D* G/ Q
- if not w:
. ^& d" s5 {" O" O0 G$ ? - continue) @) Z& e3 B0 T8 ~5 c* c
- v = w.active_view()6 |3 ^2 L8 Y: m1 X0 G. a$ k
- if not v:
0 u: O/ u% M* [. M - continue
6 _. Q; t! n: r$ X& ^! v8 H. q - try:- q; U# ^" L( U8 Y- h' Z
- el.on_activated_async(v)
' x' H: C) G+ r$ {3 f5 t - except:$ S( N, u" W8 n2 w. G
- traceback.print_exc()
9 o. S* ]; C/ r3 ~, \) ?, ] - 9 y2 P1 e" q% I( U$ @" m
- for vel_cls in vels:
. P4 F! P* l$ I' r: h9 U. M, ] - w = sublime.active_window() V4 z/ ^. c: B5 s8 z1 J$ S) g+ J8 F1 p
- if not w:
" ~& `6 ^2 l l) F. X. Y - continue
2 _2 k" { Z8 p" r0 ~3 Y - v = w.active_view()
% S" h! `0 a) k. u- _ - if not v:1 [ C) ?/ N" h; z# C `1 ]/ n; j" I
- continue/ b+ M& t1 k$ F9 S
- vel = find_view_event_listener(v, vel_cls)
1 @& [8 b" {, ] - if not vel:% _2 D( {7 _; \! q$ L2 _
- continue9 Z7 @% `0 ~ w: {
- try:7 {1 P3 x) K% b, D8 A5 [
- vel.on_activated_async()4 E2 D6 S) I: E9 B; H
- except:( H) ?; V/ H- E" z3 J
- traceback.print_exc()4 d& W8 g/ d5 r$ ~5 i5 E) p
- 9 L9 S- c0 R. ]8 h0 B) d
- . t! U/ T. Q" O' H7 C
- def create_application_commands():9 B) Y& B3 Q$ s
- cmds = []8 ?( [6 w5 O' D1 r5 z
- for class_ in application_command_classes:
# e; A7 U3 k* M8 |' T' Q9 z+ O - cmds.append(class_())- s# o: O; a2 T9 o( h2 ~( f7 S
- sublime_api.notify_application_commands(cmds)
+ t8 i6 a1 _$ j3 K# D - * T+ |- y; m5 D
4 }' U5 p w$ ]' s5 v' ]3 o8 W- def create_window_commands(window_id):$ x' j, D& k- ~
- window = sublime.Window(window_id)
3 S( \, D5 ] B$ v3 Q# ]8 M - cmds = []
' `3 s; N3 R% d0 }1 e - for class_ in window_command_classes:
6 r2 |' k5 g: P6 B( `; F6 ?( ^ - cmds.append(class_(window))( {# q. x1 e) A5 ~4 w
- return cmds1 r/ d" f8 w5 L, l J
, q8 p# h! R, l- 5 v o; k# c# Q5 ~) m& O- r6 x
- def create_text_commands(view_id):
$ L( _) h9 W# m4 n - view = sublime.View(view_id)
" \, d7 p7 h& i4 k - cmds = []
$ I. M4 I5 v, @; N& Z - for class_ in text_command_classes:
3 g8 z+ N& O* @( x b$ H8 V - cmds.append(class_(view))( G" u# t7 u2 P, |* `
- return cmds1 h8 C# g' p @2 u8 ?$ |) y4 ]( ^
- 7 N/ d" U4 H1 N1 x5 @. C# ~5 G
& x# O4 z) C, C5 U0 Z$ g- def on_api_ready():8 ]0 V; O$ D6 Y( N; x
- global api_ready
8 k) a# B' G) S" x! \6 i4 e, B - api_ready = True1 T+ B" L5 \! Z- l
- . R/ e" c4 L/ m: g
- for m in list(sys.modules.values()):
' y7 J& S8 \( C - if "plugin_loaded" in m.__dict__:! m* \! r8 C+ y& I
- try:/ L1 k! d- B: ]) G: {4 c5 e& u
- m.plugin_loaded()& I/ X3 Y# D3 [7 H- ]% F/ `! n0 n% Z
- except:
- H1 i5 F5 h/ W5 T0 y8 e - traceback.print_exc()
- w1 G {7 W/ J- @9 W% }. q q - " A# I# a9 ^ g8 k% p
- # Create ViewEventListener instances
4 J' d6 |! G* ?# c( m v3 [ - if len(view_event_listener_classes) > 0:
4 Y5 M" A' X! n' i - for w in sublime.windows():- ^+ T3 D+ M: N- C i2 C, S6 n
- for v in w.views():
- i: f) j8 o X; N - attach_view(v)
. \& e. [* I8 t- E/ p7 k- q
, H# K- Q& T% P, \4 ?- # Synthesize an on_activated call
I" o1 p* E# j# p - w = sublime.active_window()% Z# q" K3 X& w8 Y2 m" f
- if w:
9 ~9 \6 f M4 `$ q# i& I - view_id = sublime_api.window_active_view(w.window_id)$ K9 V: u* Y, \5 k
- if view_id != 0:6 z5 ~" s$ O; F/ @
- try:
- L* [" C' y6 a% h" a/ [7 m6 E - on_activated(view_id)
$ z; ~; g, p( I7 ^" n4 N& y, b - except:
9 S- u* J& ?5 W5 n1 a1 { - traceback.print_exc()
3 }& O6 j ~* _& ?8 f7 e9 e" t - . H! B2 `+ ^5 X5 \1 x
- " N# |* n; c* T0 O2 z
- def is_view_event_listener_applicable(cls, view):" M5 r' j) Y: w8 `
- if not cls.is_applicable(view.settings()):
1 E6 M$ [7 q( J% g+ ~ - return False, f9 N+ X# Q* C3 S2 ~
" Y8 o e3 i9 y, n$ w$ H1 N- if cls.applies_to_primary_view_only() and not view.is_primary():; H3 o, a, @! E" l+ s0 N7 p
- return False& h4 b4 p0 ?* V( w, u, b; t) N/ `
- + l8 x+ |. @7 L8 u, r
- return True
. i9 P8 b; A6 t
! r; O) d( t5 w- 5 }3 q( f) C$ l0 t, Q
- def create_view_event_listeners(classes, view):3 K2 i9 K. ~2 u
- if len(classes) > 0:
' q5 r8 {: A) @& r H I - if view.view_id not in view_event_listeners:4 v# ^1 r! j7 W0 U; I! l
- view_event_listeners[view.view_id] = []
T9 c5 R% t c - t$ _$ h# f6 [. J+ x* n
- for c in classes:
( B. B3 [: i9 d5 w' k0 X - if is_view_event_listener_applicable(c, view):% Z6 m1 ]- i" E3 H) J
- view_event_listeners[view.view_id].append(c(view))
5 a0 {" H. Q$ D" z
2 m, ~- K( j3 p, W6 o1 ^( m- / z8 W4 H9 k! U+ ^
- def check_view_event_listeners(view):
& o* Z! {7 U% h% |* m. E$ c# D - if len(view_event_listener_classes) > 0:5 w5 s" K& N) P- b/ f* g2 ]) ^5 r
- if view.view_id not in view_event_listeners:- m% X" S( v x h- c0 b" n
- view_event_listeners[view.view_id] = []) m, A! Y. m2 Y, f7 O/ e
- 1 d7 B$ b1 Z8 O9 f
- listeners = view_event_listeners[view.view_id]: J( f8 m0 j/ B4 M) \* D. I2 M. b$ I
8 c4 a' ~ P+ V8 `- O- for cls in view_event_listener_classes:) d: p0 ^8 `9 U0 G, {
- found = False
# T: z' D2 B, Z8 \+ e2 G* y - instance = None
3 ^" R9 t N/ ~3 x6 f1 L - for l in listeners:
/ g! o0 K4 ? f5 r! |+ h) W: u# x - if l.__class__ == cls:
/ X9 ~7 E+ j/ R7 g6 q+ n8 f - found = True
9 T, M2 O m+ @ - instance = l
( n, w9 Y6 a+ Q) ?! b7 r - break) I+ l4 n, H! Q8 N! l
- * D- t% i* n* ?3 j, }
- want = is_view_event_listener_applicable(cls, view)7 `( O% `+ z/ J. }4 Y2 c5 b0 |
- % Y' Y. r d- `% B& J }' a
- if want and not found:
; @/ q% u( M+ }) Q - listeners.append(cls(view))
/ a' j* e% d$ U7 v+ ` t - elif found and not want:4 i" x# f4 I1 a/ Z7 ]6 k
- listeners.remove(instance)
1 a, D/ _: c) G# g1 l H
( ?/ Y0 v, m8 u, p! R' |- - u8 k& v7 p% Z% l8 C- V, S! B
- def attach_view(view):: z; B+ ~/ P$ t* ] Y m
- check_view_event_listeners(view)
1 ?, f6 z: O$ X* q: R7 `$ E
, z; h0 I. {9 J, `- J- view.settings().add_on_change(
8 D: q) M, u( ]0 ^8 Y - "check_view_event_listeners",8 f# {& M. w) s" t9 S7 ~% L9 z
- lambda: check_view_event_listeners(view))
6 ?% V' f/ n$ @
# ?3 F1 y* y0 J' X. B
7 w _6 y2 J! X5 B$ J' G9 _4 K: i- check_all_view_event_listeners_scheduled = False
' K. d/ A: g/ _/ m; F+ i
8 M0 {$ \' v8 G$ b H3 w- 5 f4 H* @( K1 J3 R! x
- def check_all_view_event_listeners():$ q0 f9 t% h- L% P- Q
- global check_all_view_event_listeners_scheduled
8 F0 f! G9 P3 q' b; G; N( W4 D - check_all_view_event_listeners_scheduled = False
+ y8 Y( ~4 _1 L/ [( W; L. } - for w in sublime.windows():/ ]$ E5 e$ e, Z1 j
- for v in w.views():
* {. N* j8 O0 A2 v' | - check_view_event_listeners(v)3 E5 ]" ~: a- }; D1 H8 E! @& T1 c1 ^# e
- 5 W& D) u+ H$ r1 I1 n
3 Y% H2 O# y% J8 d Y8 C- def detach_view(view):
) b9 d8 d% r, ?2 {- D" N8 k. Y4 v% a - if view.view_id in view_event_listeners:
s/ W: T. |$ p* v4 `: v f - del view_event_listeners[view.view_id]
7 t! ^& _4 L7 j8 ?' ~ - 8 X' J- q1 D, X& n
- # A view has closed, which implies 'is_primary' may have changed, so see if- Y1 a( m% [$ ]! ?
- # any of the ViewEventListener classes need to be created.
' c9 F( M m* w& W; q. g - # Call this in a timeout, as 'view' will still be reporting itself as a
; u. Q v9 n2 m* e# i2 y - # primary at this stage
; P [# h+ j/ B' d* {: K. I, I+ e - global check_all_view_event_listeners_scheduled
) r2 D3 v; \& h4 ^% u1 O - if not check_all_view_event_listeners_scheduled:9 \& t3 C% P1 O- o/ Z! _, }/ \
- check_all_view_event_listeners_scheduled = True
. Q1 c9 O) g, O1 }* |' S# A1 l! F - sublime.set_timeout(check_all_view_event_listeners)
9 ~2 X8 m: C0 `& |4 }8 T5 l( M - " Q' l f, R& L- }4 `: k" E
: ^6 R8 Q$ C; o0 k2 K- def event_listeners_for_view(view):* h& S% A4 \3 }9 @& }, c; Y' x
- if view.view_id in view_event_listeners:. h, f+ }$ Z$ Y
- return view_event_listeners[view.view_id]! O; ^" A0 E& X, I8 ~' ^/ o
- else:* S6 b0 f+ R8 v3 U
- return []
# s. C- {0 h2 p R/ V0 r - 7 j2 i' }- ~7 I( }' P. s1 A
5 K$ m- ^1 R. T0 E" y- def find_view_event_listener(view, cls):
- a6 n! R1 p6 A1 C* C - if view.view_id in view_event_listeners:/ I7 c: O. l& U& A0 R6 m h
- for vel in view_event_listeners[view.view_id]:8 {* C- m8 D! _7 r* \# ?% n8 Q
- if vel.__class__ == cls:
" s+ O7 A, @% a& s3 o8 P% ` - return vel. g. m; D- M1 x8 z6 E. U9 B( M
- return None
* ^+ ?# b, p! ] e
4 D2 l/ C' R" W$ F/ I" g* K% j, j, j
1 x2 K) W0 T7 D* R- def on_new(view_id):
7 J' V. C8 d! ^# b* L. S; k7 u* q - v = sublime.View(view_id)1 w$ ^# _# ~9 m) ~
0 f9 Q* C4 O! _1 M4 M" H- attach_view(v)
! V% T* A' \' @- M/ f: \+ }6 W8 U
& x' p- C& O9 K: k1 S* y) I- for callback in all_callbacks['on_new']:7 G' Q& z: j) N# f+ c& `: D
- try:
1 |' g% c' A! Q& v: \* s( V2 K) {9 W - callback.on_new(v)
9 ^ r; V7 c. k% { - except:1 v! i X; _' H; q9 L' t+ ?
- traceback.print_exc()2 @1 N* O% T1 S
R1 E$ {' a7 F( x2 Z I. K4 m$ G
8 R; E6 T4 k8 K, L% M- def on_new_async(view_id):
: Q3 V0 T1 R( S* @! b% {7 ]- i# |) I - v = sublime.View(view_id)
7 |5 i# a( s8 y - for callback in all_callbacks['on_new_async']:
: L/ U2 ~% ?# g- ^$ u - try:5 r; o* r* e1 B4 V, K Q
- callback.on_new_async(v)
- o* m' |3 N9 b- h- w/ Q T - except:8 @& x+ f$ l$ ]) J5 b' R7 `
- traceback.print_exc()
% u8 _+ x9 E( m% @/ A) d- H - * m8 [7 Y; Z5 S2 O, Q; \4 B* H# W
- $ m; @- h0 \2 J4 c
- def on_clone(view_id):1 l' T) M# a& P6 m+ T# z
- v = sublime.View(view_id)
- }' L+ [6 l0 [/ V }- U
* Q7 m' Z3 j" P' v- attach_view(v)
: \4 c. U: q, v, [5 r - 8 v* X+ e6 {3 Z" X' {) i9 j# F$ U5 n
- for callback in all_callbacks['on_clone']:& F1 R! M: \0 A# r j/ ?/ I. Y
- try:
9 D0 ^# \0 p8 c( l2 O; y) t5 `+ b - callback.on_clone(v)
, P6 p: Y9 A% s, p0 J - except:
, u8 g) _! t1 I' x6 J) A e7 x! a. j: x9 T - traceback.print_exc()* n5 U8 r# C$ e/ } {# v: M3 E
2 L& T+ ~/ G5 e, \& U2 o6 Q- 9 p( c7 V1 X6 \4 m/ Y( n8 c: O
- def on_clone_async(view_id):/ Q1 |% T8 j+ e. N* X
- v = sublime.View(view_id)
8 r; o8 ]7 `: W! G( E( K5 U- _ - for callback in all_callbacks['on_clone_async']:
3 ] z( e) X6 z/ p - try:. m, S) J# g3 H: I
- callback.on_clone_async(v)5 t( v0 M8 J% t1 ]* `& g
- except:) l0 v5 s0 Y' W) F
- traceback.print_exc()& p" A7 [& l; d
1 m0 N# e% Q: G% |( Y- 4 @ E; I1 A9 a. ~5 ^
- class Summary(object):, w8 L$ W1 L0 b4 `8 n& p
- def __init__(self):
* }& f3 J+ R6 f( O+ w) z/ z* j - self.max = 0.0
/ E0 ?/ y4 Z. d. ^ - self.sum = 0.0$ B3 [4 C7 |$ C$ L
- self.count = 0
$ N1 e$ p% E |8 c) _
+ i q% U& L$ ]4 [! ~1 v- def record(self, x):
. ^1 B9 n* X' d+ n - self.count += 1
9 m3 h, e2 V/ I$ e! V - self.sum += x
# ~4 @8 ^% n# o% a/ d0 n - self.max = max(self.max, x)
1 T& I9 ~- ~. {' b
n+ _8 t A: ^: B# ?6 n. j- def __str__(self):
E: s9 d8 b; p1 x# @/ M& B - if self.count > 1:+ ~8 A/ K% a/ K8 o$ C& J" A% W
- return "{0:.3f}s total, mean: {1:.3f}s, max: {2:.3f}s".format(self.sum, self.sum / self.count, self.max)
5 Q, o, s+ A+ C - elif self.count == 1:( v( o4 Y/ ^4 A* ^
- return "{0:.3f}s total".format(self.sum)' k7 N$ `/ s$ c3 g9 ?' Y- i
- else:
: }, N' I2 S; S6 G2 b+ ~ - return "0s total"
U$ D% F! y5 y - ! Y7 F3 F/ `& \& W% V
( p7 g- b1 @8 m- def run_callback(event, callback, expr):% k7 K+ t& J( f2 S3 a
- t0 = time.time()
) V: m$ T2 r' t8 m: k2 ]( [' p' [6 X) W, G& O
% x; `; k7 x6 h/ c- try:. l4 w+ k% w( g O" B0 z# q5 B
- expr()
' J8 s4 f" U+ |* G+ L$ J- ~# J1 z* t - except:3 Z3 p9 [9 C- V" g x+ H2 j& L- E4 W6 ?$ O
- traceback.print_exc()- B$ K. _7 e8 c. k5 e
% H7 v( X6 X7 ^% P% N- elapsed = time.time() - t0
- _' ?, p5 _1 O0 q- y, b
/ B l4 O4 {1 p; n, k- if event not in profile:
% O& G% o2 {/ I( q- w5 u! m8 u - profile[event] = {}+ Q) W) j+ M! \/ P
- 7 ]! q3 G3 {' J/ i
- p = profile[event]
$ `3 V0 }/ ?$ D1 F2 E6 s7 V
" c8 [' M9 }) h4 B7 d- name = callback.__module__* \4 L( w0 {4 ]
- if name not in p:
0 R3 \- e" j0 J - p[name] = Summary()
3 R% P# W/ L1 V - . t* r& `+ k3 k
- p[name].record(elapsed)
1 v! v6 b: j* U - - j3 q6 D6 {2 e, F% \0 q
, o6 w; Q' O3 w" E2 u/ r% V9 v. D& T- def run_view_listener_callback(view, name):
/ c# }( N( A/ }/ h* | - for vel in event_listeners_for_view(view):! U) N; O' u' o3 u4 e
- if name in vel.__class__.__dict__:
5 w' z( ]) K! w! p. o4 M8 @* o& X - run_callback(name, vel, lambda: vel.__class__.__dict__[name](vel))
8 a0 x2 D5 v# R/ {+ U! W
3 S( D5 q# {* A& S) q$ ?5 T
) s; A/ C0 r2 b, _- def run_async_view_listener_callback(view, name):
J6 M' ~5 N5 _$ M% O5 m - for vel in event_listeners_for_view(view):
+ `, D; d$ A) C; i, d - if name in vel.__class__.__dict__:1 \6 i# _' j8 U+ N, I8 p: |
- try:( ^" g( U% |' A/ }3 S7 c
- vel.__class__.__dict__[name](vel)
. O8 R0 y( V6 g4 Z' X6 N - except:8 ]& Z. q* [9 O& @9 a
- traceback.print_exc()
9 d- \2 t2 `2 I - 0 y% ?# ?& \8 Z" N$ }: X6 H8 f
y5 T& @6 n9 l7 U8 g1 H" ^2 O7 C1 e- def on_load(view_id):) ?3 N s- K& O, G! r
- v = sublime.View(view_id)* S# {. d8 N; X0 D! k3 J6 @) `" R
) X5 h/ d' v$ {! j; i* O4 W- attach_view(v)
( H* x& e3 }$ x) z9 x - , Y# y# T0 o+ K1 |: y9 f3 @" X
- for callback in all_callbacks['on_load']:, H. J; o( A8 u5 t$ z# @4 N4 e) [8 k
- run_callback('on_load', callback, lambda: callback.on_load(v))
0 B$ t, l2 N5 q8 Q. Q/ O - run_view_listener_callback(v, 'on_load')
* ]5 |* D1 p! V+ A6 `7 x: ?7 J ^: K - 3 V- x1 g% v7 c0 p3 O
, l# b x0 Q% R# g" `- def on_load_async(view_id):
- d3 j( q7 O. k! w/ x - v = sublime.View(view_id)
$ v% S$ ?, ], V: K% N - for callback in all_callbacks['on_load_async']:
" J9 |+ V5 I; g- Y# ~2 F5 D* C - try:8 a( F$ K+ B& j w5 u) [
- callback.on_load_async(v)7 N+ f, y# m! g" U& L v+ f
- except:
6 x6 Y) D- w0 S0 Q1 ] - traceback.print_exc() A4 A# f, ~9 ?
- run_async_view_listener_callback(v, 'on_load_async')6 E+ u/ m& I+ O; D9 @3 Z0 t: g
- ! i9 k1 q7 x9 b
9 H- l+ o) O; u' C- def on_pre_close(view_id):4 V$ [9 N2 t2 U( H# I( Q6 E
- v = sublime.View(view_id)( G" h- Y* Y1 ~( }) r3 P$ g$ {$ A J
- for callback in all_callbacks['on_pre_close']:- ^/ C( N. h( ]6 ~& |: X7 n. F- \
- run_callback('on_pre_close', callback, lambda: callback.on_pre_close(v))" q M) y% J$ b* u" X9 N
- run_view_listener_callback(v, 'on_pre_close')
/ ?/ v$ i& ?) Z5 |: h4 |: R3 v- f
5 N% |1 A; [0 `& n' ?! P- ! y, @4 `$ q) g6 ]% C! O
- def on_close(view_id):
( F1 w* J! Z1 z: j c1 `% R - v = sublime.View(view_id)
# M) u. i. ?5 l; |0 Q; H - ; H( e2 Q# W2 x( J
- run_view_listener_callback(v, 'on_close')
& r/ Y. o3 R# q7 y) y1 q - detach_view(v)
' u1 m: `& s' x0 b$ b! t) r - . M3 A* A) o. k. M/ b
- for callback in all_callbacks['on_close']:
# N2 m. ^- x2 e! D2 L4 _7 [- e - run_callback('on_close', callback, lambda: callback.on_close(v))
9 r6 T# v+ H, D- }2 {
9 W Y9 m( M% h" r; C2 o0 I- 9 H$ k! T j, Q/ b
- def on_pre_save(view_id):' q0 I$ y$ z1 l: ~' m5 C
- v = sublime.View(view_id)
! U3 P( u( G R2 J5 s - for callback in all_callbacks['on_pre_save']:
3 u- T# z* @6 l+ W# I! J+ O% G - run_callback('on_pre_save', callback, lambda: callback.on_pre_save(v))
. e: U$ C' g, H - run_view_listener_callback(v, 'on_pre_save')
+ w( O4 j( p! d# u" Y
) ~+ Y. \* {5 E" f* v$ g9 f2 _- $ b" H0 k" a4 H/ u
- def on_pre_save_async(view_id):
" r- n4 {4 S E+ _ - v = sublime.View(view_id)# ?; U9 C' Q3 c
- for callback in all_callbacks['on_pre_save_async']:) I9 }& B% J$ M' ^7 S2 j
- try:
F; m& B. l8 P1 i. F3 W - callback.on_pre_save_async(v)
+ u+ p- S0 }$ ^1 o - except:, m9 V! ?6 l B; W8 ?, E( M0 ]
- traceback.print_exc()/ U# ?# R( g( L( s4 d
- run_async_view_listener_callback(v, 'on_pre_save_async')
$ c( X5 E6 i1 Y8 i9 ]# t# | - 9 A! ~. B7 h s, v! g S2 \! m
- n) b, Q9 V0 T- R2 i
- def on_post_save(view_id):
$ q6 g7 K" n* H( c# E - v = sublime.View(view_id)
. w( y& U& v: O5 Z1 _# | - for callback in all_callbacks['on_post_save']:
" J# `% e' m$ t/ \7 R - run_callback('on_post_save', callback, lambda: callback.on_post_save(v))
9 T. F, X8 X4 l' |6 t }4 I - run_view_listener_callback(v, 'on_post_save')- A& i; F# V, s, n7 R! Q5 y
% n0 X' b6 j7 V* J6 E; g* _- + u, z, v8 N" H" x
- def on_post_save_async(view_id):
1 n9 l- Y9 _$ P5 ?- O$ x) W* w; _ - v = sublime.View(view_id)% V/ y7 D$ P6 \. T9 e, g2 ]
- for callback in all_callbacks['on_post_save_async']:- \$ P9 C. R' @6 Z2 u8 h
- try:0 `& I) d) [. z1 j9 P: n5 n
- callback.on_post_save_async(v)) m7 Q0 B) @& t8 o
- except:
5 c( D, n6 t, u$ K - traceback.print_exc()
5 \' L: E0 S) {& {1 b2 p- h - run_async_view_listener_callback(v, 'on_post_save_async')
' E- x; A) F4 R# w4 `6 f0 F1 t
% T( j& S: ?1 y6 x# ~
1 O$ d2 S" P ]. E6 ?" e- def on_modified(view_id):
2 t+ f# L% n4 \/ M- S# d0 m* X - v = sublime.View(view_id)6 U) J% i# F& a! b3 ]
- for callback in all_callbacks['on_modified']:
3 s; }+ O1 l1 l) @& M$ J - run_callback('on_modified', callback, lambda: callback.on_modified(v))- {) p$ \( e1 f$ D& M
- run_view_listener_callback(v, 'on_modified')2 i' }$ F/ u. T+ m
9 p6 k6 ?! ^5 ` n5 f* R$ [% h
$ R" C( |9 E" P" I' ?- def on_modified_async(view_id):0 u. \# P: ]' Q8 {
- v = sublime.View(view_id); N; ~7 N$ Q. R+ Q$ G/ g
- for callback in all_callbacks['on_modified_async']:
6 S4 j, f$ j7 |) e) L2 U' X0 d( I - try:
2 L% W' z; Y. w - callback.on_modified_async(v)3 b6 r+ R* S) D) b5 c
- except: x' |6 o+ G! E. P4 ^. o6 M. j. s: K
- traceback.print_exc()
6 ]% D$ a* Q7 R0 M3 Z$ s - run_async_view_listener_callback(v, 'on_modified_async')6 V% W: _6 }$ u
p/ |5 g; A# n- x5 z; @- ( I9 W' h" A+ f6 y% d+ l1 E
- def on_selection_modified(view_id):2 O3 I w. I* y' x2 x9 e
- v = sublime.View(view_id)
7 A; j G- l! O) ^6 Y9 Q: M3 Q - for callback in all_callbacks['on_selection_modified']:) I0 l! Y, f& t& ^& r% U0 s9 p9 l
- run_callback('on_selection_modified', callback, lambda: callback.on_selection_modified(v))
" t' z& K4 l( `# R - run_view_listener_callback(v, 'on_selection_modified')
5 P$ x* m. y/ N Q9 L* q - 3 K0 d$ N+ | ?$ G _( m
- ) j' u, T- r' @! c# z) L
- def on_selection_modified_async(view_id):
; B7 w/ x. K+ u - v = sublime.View(view_id)
' U3 n1 E# a$ e( W$ c8 _ - for callback in all_callbacks['on_selection_modified_async']:
" Q: x9 P- Y+ L5 n - try:
1 S" X) @3 {" q `4 C, [ - callback.on_selection_modified_async(v)) ?% v2 K4 F" X, g6 M
- except:, _% v1 N; E1 O; P
- traceback.print_exc()
! H# @0 r! R$ ~3 k - run_async_view_listener_callback(v, 'on_selection_modified_async')6 n, I# O' W: O' |. P8 h, \2 U
- ; I& Y+ @+ a" @1 S( k7 o: K
- 9 q- ^9 T* ^1 v
- def on_activated(view_id):5 ]9 F! Q5 ~; E. n; x8 P
- v = sublime.View(view_id)
3 ]" ]1 ?/ ^4 C ~3 L - for callback in all_callbacks['on_activated']:8 H. B( \% A* b& A
- run_callback('on_activated', callback, lambda: callback.on_activated(v))) o' j) i$ _5 j6 k2 G3 G9 @
- run_view_listener_callback(v, 'on_activated')
! p6 f% u% H$ g - 2 }' t8 W0 A: a
- # y* ], l4 i+ E, E9 m% X) \ l) P" o
- def on_activated_async(view_id):" p( b! F( m* P$ y! |0 t! F# W
- v = sublime.View(view_id)
% ]# X0 J. a c - for callback in all_callbacks['on_activated_async']:, [+ @5 L5 [: u
- try:$ K) k ]9 z0 s
- callback.on_activated_async(v)
) j( u% \' s- [1 x, m! K' Q - except:
) P6 x' ^- w8 L1 }$ S4 `$ ] - traceback.print_exc()9 P, s+ e7 V! K' [% N
- run_async_view_listener_callback(v, 'on_activated_async') u$ B- x0 Q- B+ K4 `& l
- W4 j" }: X/ _4 D
, i# n8 P D7 h- }- def on_deactivated(view_id):
* z/ T Q9 b- y+ K! x - v = sublime.View(view_id)& s8 d7 B6 N5 o
- for callback in all_callbacks['on_deactivated']:
, e$ o! g% L, y* v' R; Y - run_callback('on_deactivated', callback, lambda: callback.on_deactivated(v))
' G1 C: S+ s) a$ L3 F- O4 V - run_view_listener_callback(v, 'on_deactivated')
+ V' L2 p/ ?" H* r
7 T p h: R( ]2 I- P$ p1 a7 k- 6 p( K$ |' B& `/ g% V$ ~0 {
- def on_deactivated_async(view_id):
( A3 _ j% S* A8 A) c4 l4 H - v = sublime.View(view_id)
. ]! @! W2 m) c8 r7 m6 n - for callback in all_callbacks['on_deactivated_async']:% O* J- l3 v. l1 I
- try:, a, ]7 d( h+ c$ K# x2 e8 I, I
- callback.on_deactivated_async(v)
1 ~- r2 b" I# j) G3 [5 s! J( N - except:
$ L( W) I1 Y! P% c5 k7 Z( ?$ H3 j - traceback.print_exc()( e, w/ B/ d/ z
- run_async_view_listener_callback(v, 'on_deactivated_async')* g* J. @+ ~ t/ \* z/ V; ]9 C6 R
' q2 M& I3 N ?: c% G+ ~6 c5 D- ( {$ _) {. B1 u. | w0 N
- def on_query_context(view_id, key, operator, operand, match_all):
1 N1 O1 j8 \& m2 n5 T6 N3 G" Q - v = sublime.View(view_id)
. W3 v( b7 @) }; D# T9 X - for callback in all_callbacks['on_query_context']:
4 O* d" F- u9 b B - try:
) U% e+ V' K0 R) P - val = callback.on_query_context(v, key, operator, operand, match_all)! w! S2 W0 A1 E9 ^* G
- if val:
% N% d7 k+ w0 F! K" q - return True) G- w4 V) G! {! I. N7 O* N6 T
- except:
) A8 T8 i3 N" \8 M( \ - traceback.print_exc(), K* j2 @- @2 s3 W% B
- 8 F9 q5 C& n. m7 Z8 W
- for vel in event_listeners_for_view(v):
3 n' Z5 O9 B1 C* G5 r' r- e - if 'on_query_context' in vel.__class__.__dict__:6 ~5 s9 U6 t: O
- try:
; X7 O5 a3 J! M - val = vel.on_query_context(key, operator, operand, match_all)
$ v, V* Z% W) q3 ~6 y) O* G2 E1 D - if val:
4 S; g8 d8 e/ r6 P/ j0 p9 @ - return True; p. S: s4 ]/ Y5 D0 L& w
- except:
: k: S" ~$ k7 q - traceback.print_exc()
# y, L! U/ P( P+ p5 s6 s3 z2 _
% M" M% B9 R: o# N: O, S- return False2 H, T( S* }3 D! O# B
8 i3 A& ]/ A0 H* B& d- 0 @- @$ T& \3 p
- def normalise_completion(c):
( c m5 H2 o0 ?7 f/ A - if len(c) == 1:
+ _4 f( z( u% P9 H" _. O% J/ \/ w - return (c[0], "", "")
! t5 P+ {( K5 r6 g* u4 Q# z - elif len(c) == 2:
8 w% `, [3 `# ~, Q( T - return (c[0], "", c[1])
8 l+ [; |5 p. o) @. n! @ - else:' @7 c5 E* e$ ?/ z5 G
- return c
, ^2 b* d, Z* C5 q
/ c( H% x6 ?% P
( m5 i$ j0 h$ v3 t: q- def on_query_completions(view_id, prefix, locations):
" {" x- m6 V& ~0 F - v = sublime.View(view_id)3 l/ c W" U. s5 l
- 2 y/ s2 e5 V" Q) w0 d4 r3 F
- completions = []
9 p8 s* x! P) P1 x4 _9 _ - flags = 0
9 h1 m" J( X0 y) g - for callback in all_callbacks['on_query_completions']:2 c5 r9 z0 X9 ?+ \
- try:( ] g% [( Z2 G) ]0 l% T& o- V
- res = callback.on_query_completions(v, prefix, locations)
2 U- S* J1 F) A+ s v# { - " A. b+ }" ?5 U6 }5 X; B. a
- if isinstance(res, tuple):
9 T5 y. U; W& u" {6 n, n - completions += [normalise_completion(c) for c in res[0]]+ c* i; j/ I1 v- V8 k5 L
- flags |= res[1]$ D s0 w, g, @9 b5 ^( Z
- elif isinstance(res, list):
1 @0 n& o- ^) C. T- W& }$ }" i; g1 N% } - completions += [normalise_completion(c) for c in res]
( c& r0 y$ H+ k6 ^9 d- A$ @- v# h - except:: u# l! ~: P2 h7 F& ^0 x% M9 u
- traceback.print_exc()% Z/ h' @' w' O: Y+ N3 C" y3 E
! D4 U+ e1 H* v* ]- for vel in event_listeners_for_view(v):- ~9 m( [4 {# F4 T6 f
- if 'on_query_completions' in vel.__class__.__dict__:
: `, Y7 I9 h7 r - try:
9 K9 a+ e$ o$ Q/ {. h3 [4 G - res = vel.on_query_completions(prefix, locations): k& A! y- P; t! A8 }( D
4 p; @ |( ^: q( K" v- if isinstance(res, tuple):! A! s) s7 s, ?5 Q4 P! T
- completions += [normalise_completion(c) for c in res[0]]7 X- N) j0 Q2 P& Z ^0 R
- flags |= res[1]
( g i. J1 l. q; f/ n. } - elif isinstance(res, list):3 i4 D9 i1 p& j" t3 g' b; {
- completions += [normalise_completion(c) for c in res]
- s# f# P. l' B0 Y - except:
! J, r0 e2 w8 ^# p4 Z - traceback.print_exc()( g r, I) W8 O- i0 l
, e- D- J2 J d$ T/ N- return (completions, flags)
4 S) }! |4 x. | - 3 O0 }% c5 t2 g8 |6 i8 m
- : F/ L$ [2 \6 i* g/ h/ x, V2 t( H$ Z
- def on_hover(view_id, point, hover_zone):
6 z# N) f# }2 q6 ^/ S8 ~ - v = sublime.View(view_id)( T1 @! m3 q3 K, e5 u
- for callback in all_callbacks['on_hover']:9 ^3 Z c0 k' V- X' d+ G
- run_callback('on_hover', callback, lambda: callback.on_hover(v, point, hover_zone))
7 c( q% I# q+ D - 1 o3 V) n* {* a9 k" ]8 C& M ?& N0 J
- for vel in event_listeners_for_view(v):' A7 @% m" F; _4 O# a) C- _, p
- if 'on_hover' in vel.__class__.__dict__:) a9 T; H1 z& g2 r `
- try:( X, o, \* X) `. I
- vel.on_hover(point, hover_zone)
: Z+ i! N g9 s0 ? - except:3 W* o* A2 v* o: b( V2 }
- traceback.print_exc()- q7 c2 t* N# C4 m5 Y/ o" j4 v) d! Z
4 i( ~2 B! S* q! u- Z- u
, S) L, j$ M) y& N5 P2 l- E- def on_text_command(view_id, name, args):
, B& \7 L* G0 w4 C& H$ {& y - v = sublime.View(view_id)# |. a6 |7 b' O" V, Z9 m# c
5 Y/ `2 A! v) ^7 U- for vel in event_listeners_for_view(v):
# w b# q, N1 z9 T3 o0 e* X# N - if 'on_text_command' in vel.__class__.__dict__:5 W# i) r, f2 E, Q9 ^2 H
- try:4 j; ^, P- k# E
- res = vel.on_text_command(name, args)! M5 {) N5 A; a8 r T0 ?' I4 i
- if isinstance(res, tuple):
1 c' X( m4 t: Q' I - return res' R# g& K6 I7 ]3 B: t$ m/ q
- elif res:
% q$ N1 Z8 A! B* N# G+ d9 y# l - return (res, None)
) z7 |- D! @% K4 B2 Q0 \$ w - except:' S9 ^4 v( s- b# J1 G4 C6 J) L% h
- traceback.print_exc()
$ V, S) Y6 e. M2 V
0 o9 S+ K7 Q% y- for callback in all_callbacks['on_text_command']:
" w" K% |' ~$ w) G5 L* O; [/ g; ~ - try:% x0 I0 {# O' b6 h. Q, q9 k
- res = callback.on_text_command(v, name, args)1 q/ t' }+ f, C, f3 F3 F+ z
- if isinstance(res, tuple): \# [, } w' h3 | e! d+ b# C1 U1 M
- return res
2 ?/ v4 G4 ] U# d4 A - elif res:% @1 ~! a! H* ]0 |4 X/ J; c
- return (res, None); m% `# {# z, q( ~
- except:
6 R1 B# l) [1 C7 S# J: \$ p* @- t - traceback.print_exc()
' t+ }$ A9 M; s% A3 G - & ]% p5 _; P o
- return ("", None), k/ V. y" Z# j! z' @
- { R) K8 ^1 |' h) i: C- 7 M& T% o z: m# P
- def on_window_command(window_id, name, args):
; ^& X: [. |' e+ \ - window = sublime.Window(window_id)
- ] i9 ]4 y( b( {/ O, V* A - for callback in all_callbacks['on_window_command']:
; ?# ^8 T/ z" k - try:
5 k' Y# R* c5 ]. H2 G- O8 c - res = callback.on_window_command(window, name, args)
0 ?) [. Z; j# p" k. O4 A - if isinstance(res, tuple):
4 N. l3 V$ c. V6 ~ - return res
/ H6 ~. H$ x8 [2 v7 h ] - elif res:/ S! n, Z7 c) L" [) @
- return (res, None)
b4 k2 m7 Z! c+ P+ v, Y; {$ ^ - except:
% l) G- W7 k' \; J- x; L! H2 v - traceback.print_exc()
N- l+ p o! B" _& D Y- K4 r
" t3 @. ^! ]; D/ |" v7 d; X5 z- return ("", None)
" {- B5 K& r" j# ~
9 {. g7 Q. n: A
0 }" L1 X4 ~# s& W" t, h0 e- def on_post_text_command(view_id, name, args):
2 `% M+ J: j0 l - v = sublime.View(view_id)& B, A- r; x+ L# l% {' H# S5 ~
- for callback in all_callbacks['on_post_text_command']:
$ _3 Q. I9 ^8 b* F; A+ Y - try:
- Z( N) u# X4 g - callback.on_post_text_command(v, name, args); c- B) j0 b5 a/ @
- except:: S2 q* i; _( X
- traceback.print_exc()# p4 n& Q* i! @
7 |( d7 P) V& G- B4 T- for vel in event_listeners_for_view(v):0 b" \( Y! s. a/ o5 s, c
- if 'on_post_text_command' in vel.__class__.__dict__:
* g7 }9 w! S0 p4 [7 \0 e, a8 f5 r6 ] - try:% t9 g: I8 v4 G, M. n
- vel.on_post_text_command(name, args)% b: w: i$ l; f) `
- except:
+ A4 v% f3 n/ n; ] - traceback.print_exc() |. {- z z/ C) K6 q" F( x
- ; w* ]1 _% i5 Y5 R" @: I! f
- ; P3 C4 P+ N# L/ B7 C
- def on_post_window_command(window_id, name, args):: y7 [$ n3 {/ @: t3 Z- [
- window = sublime.Window(window_id)% E. {5 Q% q1 h/ m4 i2 w) }8 x
- for callback in all_callbacks['on_post_window_command']:- Q: m2 r! S2 ^* c2 M% v1 U: {& \
- try:/ u4 N# v% L' U: N( {
- callback.on_post_window_command(window, name, args)
4 f0 ]$ s- o4 d% c z - except:- q, V% G0 V, C4 c+ `/ x
- traceback.print_exc()$ [2 y$ c( V2 [7 Y; U8 G
! `+ ?% x9 A. @0 Q, a; o: H- ( o4 M4 U8 I7 z3 k
- class CommandInputHandler(object):$ r6 z4 ]% T' C c
- def name(self):
& Q8 j5 M! m" C5 _0 O - clsname = self.__class__.__name__
2 ^ v3 g, v1 K/ W - name = clsname[0].lower()9 W# h8 Z4 H4 U+ v% r
- last_upper = False
: U$ ~! T; o4 L- k. a$ I - for c in clsname[1:]:
1 q# j( ?( T6 f: j/ h - if c.isupper() and not last_upper:
, e7 ?/ {, P. }( Y# W3 Y3 R - name += '_'
) [5 K: @, g5 t$ B! X5 D - name += c.lower()
+ [- t7 K/ n4 m2 E7 `9 e3 g - else:5 h; R% J2 Q s. h& _2 ?( s3 Z
- name += c
" c3 P* {" M5 r - last_upper = c.isupper()) }) y+ L+ z# Q6 g, {/ V" [
- if name.endswith("_input_handler"):
, t1 a" Y; ~8 c4 {. u/ Q4 ^$ w - name = name[0:-14]
/ V- a7 F* ?1 T2 A - return name$ z- v; N' F+ O$ g1 y6 g2 q
- ' i. m2 i+ J; [7 s Y) u/ Y& S! b
- def next_input(self, args):
% d! k) o1 u+ A" u - return None
1 @ [+ ^: ~1 m
4 R( A$ d3 B8 u% |& l* G7 S- def placeholder(self):
0 C1 b1 N2 t% d( f6 K - return ""' K2 G% D# g2 \" B& M
- ) j% O& Y/ ^- D7 r" G
- def initial_text(self):
) h3 X6 m. [% g& W' _+ L - return ""
( F8 A5 D1 P% o- o3 e0 w1 E - , }3 a/ l9 g1 ^1 @$ t ~, K
- def preview(self, arg):
# d7 Y% _. ^0 l, M - return ""
+ G& Y! J- o. \% C7 Q h - / m* L3 ?2 l# y/ E6 i* j
- def validate(self, arg):
- }% p8 m5 p, t/ L: F# s2 M - return True& l# m5 k# J/ ?2 Z. ]
- , J7 v0 @& o7 z
- def cancel(self):
0 z3 _5 s8 U* e K# ?; c - pass0 q( S, H. j! k
+ k" T. x Q$ H1 B z3 d; v- def confirm(self, arg):
1 Y0 B2 ] z8 }1 S% O+ O4 v; I - pass/ H8 B; R# x/ Y
- ' ~' B8 J; ?5 `! b; V( _
- def create_input_handler_(self, args):
! R' x6 {( C$ I& ?7 p - return self.next_input(args)
0 q/ x4 m `/ Y0 I
: |, W+ R* N+ t p5 c4 \- def preview_(self, v):
) W. f' b8 g' ^" |' a8 n' I - ret = self.preview(v)) ]; _# h' q0 Q
" T g( z! z0 H% ?( ^% W8 g8 s. _- if ret is None:6 g& t. w: C& S4 [: t- r
- return ("", 0)" q2 }" Y A; K. l, x- }
- elif isinstance(ret, sublime.Html):
# V* o l1 u, L7 v/ H. i! } - return (ret.data, 1): K; x2 f7 C% L5 n5 \% u7 D8 g
- else:+ r; [7 P2 A) i/ _
- return (ret, 0): n3 _2 ]0 [ o, C9 \, f$ S3 J
$ I( \9 t3 U: }. U- def validate_(self, v):
$ p6 s, z' v0 ?5 K8 g - return self.validate(v)
, g( F. z! W/ n3 d9 { - + I. U+ `8 p5 |! L/ Q' l
- def cancel_(self):
* I; c) o: J! z6 A - self.cancel()
# q$ D# S# M6 P: D: D0 s9 H1 G* x" n - 1 j# D- X& B) E# I5 C" g8 O
- def confirm_(self, v):& N6 |/ h P; D
- self.confirm(v)5 g9 ]/ A/ ]/ ~4 d( ~
- " V0 v& y0 ?2 d( f2 D
- ) H+ n# y% F: \7 @# j
- class BackInputHandler(CommandInputHandler):9 T, ]+ [# T0 W" R
- def name(self):5 G, ?2 j' O* \4 C5 q
- return "_Back"
_) j% t6 W7 X. }" X. _ - % E4 F3 F$ _0 ?! l' u& B
# R% b& ?7 M" k7 Y' b& @" x+ T- r- class TextInputHandler(CommandInputHandler):
' N+ h, X! w; h# F+ `5 Q - def description(self, text):
5 _5 j8 I5 _& j' F, D0 {: | - return text6 [+ G- c* l8 Q# T4 G1 s
- # W$ l) {" U: K# K+ d- V; m
- def setup_(self, args):8 f/ Y, v9 t' b3 v
- props = {1 w9 H7 T4 i/ [/ N( U, W# z
- "initial_text": self.initial_text(),
, c6 E5 S% z' c( t* o1 b0 Z/ W, R - "placeholder_text": self.placeholder(),( H+ z% V$ W- D7 i
- "type": "text",
9 L( w" X: o) S - }
: \+ R- v7 D5 ^# t
# V; ?# ?5 F2 f- E. h- return ([], props)
7 E! G u. j9 w( V - $ M9 ]' f, z" E% ~% } Y
- def description_(self, v, text):
+ k: ]6 U( N+ p) } - return self.description(text)
' ^! T/ F$ U. l - 5 Z# t! ^5 _! f o9 i3 O
- ) j4 {9 R2 _6 @7 m; Y% H/ X
- class ListInputHandler(CommandInputHandler):5 F$ D9 w! N7 i0 \
- def list_items(self):6 X9 c5 |5 U& g& K4 X! f; w- P5 Q3 R/ Q
- return []1 S2 F" B4 F& Y; ]% m
% q+ M l9 C/ j& H& S, u- def description(self, v, text):
" p$ d& p4 t0 o+ d4 x' d0 w* r: c - return text# a7 w2 |# g% t7 ^6 D j& V
+ t& J# w: P& s% j1 Q- def setup_(self, args):# S$ N$ W- M5 k ?4 F, }+ Q
- items = self.list_items()7 D. W' K5 B) A* e6 e; M
- 2 O3 D0 M5 `6 M+ A
- selected_item_index = -1
$ A& j. Y/ }7 M. g# F8 {8 |" b6 L
+ q% v& s9 [5 G3 b! K5 Z0 f- if isinstance(items, tuple):
( s# w% ^! b/ U- y+ u0 f - items, selected_item_index = items- ^6 i1 [, Z Z: v& D2 p( m
' s2 I) u- R% w: H- i: d- for i in range(len(items)):4 B" L4 H3 X2 Z. e
- it = items[i]7 w' A. \' y4 L ?- P/ ]: l
- if isinstance(it, str):1 c7 b3 [# x% q
- items[i] = (it, it)
9 a9 r' `0 ?/ P, n - ) v6 c/ u/ b2 \" P$ {9 p
- props = {
( W" L4 d, g0 Q w9 G( q - "initial_text": self.initial_text(),
, l' l: E+ l4 p - "placeholder_text": self.placeholder(),
- _. _1 ~5 o9 [+ ~ P - "selected": selected_item_index,
# _+ ?5 p! \" Q7 K, c' m5 N6 R: B0 i - "type": "list", c: Y; \; d1 Q) _
- }: O2 l) v( H6 S' _% O
; t* W. I, Z5 D$ q- return (items, props), J Q$ N) w' D! A3 i7 }- t' p0 Y
* s, w1 ?6 I. u- def description_(self, v, text):' m7 |0 h$ ^6 _. e/ A) h" @
- return self.description(v, text)3 s. a1 R4 U+ H- L% D- Q
- 5 {' C# Y: {: J/ C
- q/ T/ g7 l5 _& x
- class Command(object):
6 ]' x0 _7 n' K; |% z" s - def name(self):
% ]8 @4 e/ j4 J( m - clsname = self.__class__.__name__
" ^0 p" q) O/ q+ `1 T, U# _ - name = clsname[0].lower(). g# Y$ r$ J5 S3 {* m6 w# J
- last_upper = False
7 y; h8 g3 r- O1 N* k+ I- q - for c in clsname[1:]:
f/ z2 L- ~5 b6 s+ ^( d - if c.isupper() and not last_upper:
/ ?( g2 X) h/ z5 { - name += '_'
% r! g ^5 d/ K) r. d$ u* N - name += c.lower()) N- B6 k I* M, I$ |! U
- else:' j% V% g# Y$ k6 B
- name += c+ j% s" d* \! k. Z5 f" _8 o6 H( f
- last_upper = c.isupper()# w I1 l6 f- Z h9 Z
- if name.endswith("_command"):0 s! ] k- d, ~* p7 h$ k# _' H
- name = name[0:-8]% k. M5 h- k' ?0 U; |
- return name4 G2 X3 r# m8 c; j# c h7 S
' w* K) i6 l0 p$ v% I; i. k* N# L- def is_enabled_(self, args):
. n3 K/ L2 l" e0 s- ?7 |& U. }' F - ret = None
5 L9 Z. K& c2 C2 ^/ Z, Y - try:& G3 a N3 z4 R1 n' s) j
- args = self.filter_args(args)- V( A c5 j3 E* v5 C' r7 }0 G: x! P
- if args:- \( `* ~* }! Q) a, n, [
- ret = self.is_enabled(**args)
: \1 {1 \- d: d4 ]3 a - else:. }5 ` [: U$ ^% A
- ret = self.is_enabled()2 W0 w8 W/ H% a5 z
- except TypeError:# k" X; f+ g4 |1 M
- ret = self.is_enabled()2 N, r) J6 s0 k d
5 N- K- ~9 ~1 Z- if not isinstance(ret, bool):" R% `- ]; y, c7 R5 U
- raise ValueError("is_enabled must return a bool", self)+ q" k& R- H6 A1 O
- 3 [9 z, C) b& z6 Z/ b( Z* T
- return ret
* @# P4 N1 [* w0 r - : c: H+ q, H* b0 m& v7 V/ e1 d
- def is_enabled(self):
" i9 c9 D- T0 c& x% c' ] - return True2 v7 X% c! u& F/ b2 U+ b& M9 k
+ Q a' o* @# W0 b- def is_visible_(self, args):- r. {: s3 e; `3 O
- ret = None. p2 ^* s/ [0 }/ }* ^) @
- try:
6 B% U+ ~$ a) {& T8 i1 }1 a% g - args = self.filter_args(args)" q# J6 S% `- G) v0 e3 n5 P( `
- if args:! P+ @% m1 U0 A9 A% F. p% l
- ret = self.is_visible(**args). v9 t1 D5 `! k; F* ^0 T9 u4 @
- else:4 H B8 ^7 q8 e$ X& R9 i
- ret = self.is_visible()
& q2 f) b- p j/ x4 k8 ` - except TypeError:
& Z9 ?3 a& W4 e - ret = self.is_visible()! I+ d- ~3 e, A( V' ]# G+ y
4 j+ l! I& a6 `8 V, r; V- if not isinstance(ret, bool):, y! y# ^ ]" Y* [% H/ {4 }
- raise ValueError("is_visible must return a bool", self)6 F7 F0 v$ V3 o4 B* ]
- # p1 g3 b; x6 |% o5 e* I; ?
- return ret
! N( ?; m+ w( w8 U6 B0 u - }9 {! G. n; \* `- @* f1 J
- def is_visible(self):
) C6 X' t7 L- e$ I: ^ - return True
# R o3 E0 t$ C0 I3 q7 L9 L
* X3 G3 L) U9 X) p- def is_checked_(self, args):. e5 }3 S4 E" Z5 W0 K$ ]
- ret = None5 C+ `: e9 f) p
- try:
' ~/ D$ @5 T. g. ]" r2 x2 I- C - args = self.filter_args(args)
! a* G9 B: s& Y9 d- D - if args:
) l+ [1 O' \6 Z P$ r0 m- | - ret = self.is_checked(**args)
% u# A' S. n% N5 X: {3 Q" d9 B8 p' r - else:
4 u3 z0 o8 G2 v( z6 z' q3 n# e - ret = self.is_checked()6 L# V: V* t8 j6 q% N. b E
- except TypeError:* A8 T' n, q8 \
- ret = self.is_checked()! W: u$ v {3 ]& P( }5 g) Y: {
- b* f0 ^7 b6 P i9 H
- if not isinstance(ret, bool):
- e2 ^3 E# x; t6 x. @. r; h! ^- @+ T - raise ValueError("is_checked must return a bool", self)
" C0 ~9 }. } T" z: n - % A1 O) v4 U) g9 X5 D) E
- return ret
6 M1 F7 z. C' [ W& Y
$ V% P$ k6 h; H; {4 V" B" _% |- def is_checked(self):
* }: \! q1 z* f: h5 u- a - return False
) g2 t/ a4 C/ Z) p7 Y
2 k) F8 J" e' L; Z$ U: N( [1 C) H- def description_(self, args):
2 j% J7 e- g4 j1 a, E - try:
6 P& \% o) c$ o! j4 X4 Q, I - args = self.filter_args(args)* P2 J* X. F$ F. U c) v
- if args is not None:
$ T- K6 K- I+ S - return self.description(**args) q, B7 ]$ A, y$ O
- else: l- @- k& T$ _) {+ |: `4 v
- return self.description(): J7 N* T; t+ E' i6 o# y1 a/ p1 I
- except TypeError:+ f4 u: O- F( y
- return ""
# t) a: ^9 J# o* E) N* G4 D9 c - ' @2 _- G. e9 E; `4 {. c& b- q
- def description(self):
; o2 @0 b, [7 U& h - return ""
( w' c" ]1 Z0 B2 Y4 w# I - # v) H0 c( ]& l* l
- def filter_args(self, args):
+ `$ C# ~3 H/ j5 r! z+ V' e3 h - if args:1 M8 H* G# f; f, i5 @8 P& S
- if 'event' in args and not self.want_event():
0 r; ~ Y1 r5 @! m" R, \! X - args = args.copy()0 w: r2 Q; S' D( Q7 _& `$ `6 ]
- del args['event']! p2 C: |+ w w* h
- 6 ^, W1 @# f. m
- return args i" Z$ _1 ]) R1 @ R
- , v6 [/ d( p/ J! Y. U& D
- def want_event(self):
8 _7 b, A% o5 z4 H: G4 h. S - return False
( j, u6 {4 h# o& c
/ X' P* ?% S3 P( k1 N- def input(self, args):
% i9 n# Y% J$ T+ n) Z - return None+ q7 f5 G1 x! q8 |
- 0 i# ^" z4 {% V v) C8 ^: i* x
- def input_description(self):
! y# k3 C4 x) \$ b2 z* I- g6 j - return ""
0 T- e5 D6 v3 c- E6 F4 N
, w6 l" Q7 d" X8 k- def create_input_handler_(self, args):7 @3 `( _5 s# `/ R) ~1 H
- return self.input(args)! t( a* q* I) |0 f `5 H( }' r) w
- " c( N# i6 U3 v2 Q, \: t
- * G+ u8 q/ f. h# @- H* d/ y* J
- class ApplicationCommand(Command):
7 J3 ]3 ^5 i' i" Z O - def run_(self, edit_token, args):
1 v6 e0 u- `4 M% B+ f) L - args = self.filter_args(args)% h- O5 N3 q+ V$ v3 ?8 ~; S8 G9 y
- try:
0 a% l$ E( x' Z ?! W; l# a - if args:' I' k' ~7 ~; Q4 |; Z! c) h6 t8 s% T
- return self.run(**args)& _" E \5 Y; Y. L
- else:0 J7 T! _0 e- L' T
- return self.run()9 q, S& ~/ a+ t- B) p( G) V. ?
- except (TypeError) as e:/ Q( l% A0 C9 ~6 z0 W9 j. F8 _
- if 'required positional argument' in str(e):
0 z9 s2 Q. d% _ v- P1 [: a- l - if sublime_api.can_accept_input(self.name(), args):
. V5 A0 n4 l4 P2 ^ - sublime.active_window().run_command(4 e1 \, R0 N' a
- 'show_overlay',, X6 N7 I" l5 C) m# S( l/ \: t
- {
# U ^; G* g- g6 V - 'overlay': 'command_palette',
$ e& ~4 `- c; z& j - 'command': self.name(),. _. E. H' V2 E5 a- g$ f
- 'args': args
9 `" d- U+ a. v - }
$ e; Y. D k ~3 V4 E - )
. {* ~2 C1 E; j - return
! ^6 l( ]4 Q) N4 m# z - raise3 v- U/ V4 R' h m# w0 Y2 J
- / h! a8 R7 Q/ k: G* |( R* N+ G' w
- def run(self):
: A8 I; Y" x5 v: D" B - pass" k5 U! Q( X( u' K( k
3 C, d" z' ]) g- 5 z; f- m3 {3 P0 a
- class WindowCommand(Command):
6 c7 \2 q, ?3 ]4 }4 K - def __init__(self, window):; h; p4 N8 T& b3 b6 @2 W
- self.window = window' @: G. Z* I- _* x) ?
1 ]" t q+ ~4 _- def run_(self, edit_token, args):) l5 `5 g+ E* e i+ n% I
- args = self.filter_args(args)
) [" M* C' W( S% l* h - try:/ g& H( I! A* c& n$ w9 F
- if args:
& H# ?$ X* I1 p, q0 S - return self.run(**args)
+ [3 Z5 _8 t, b- h% H - else:
8 ]) H% f9 N4 v) \ - return self.run()
6 b t5 \. I% |9 F# C" k6 ?# B' O - except (TypeError) as e: L0 @5 u4 m( ^" T c: l( Q
- if 'required positional argument' in str(e):
! U% k# J3 a$ T& z& e7 ]/ ~( f5 a - if sublime_api.window_can_accept_input(self.window.id(), self.name(), args):
! ^" \# J" F4 u" J: n6 N - sublime_api.window_run_command(
6 _) H1 `5 e$ Q- G& K% C - self.window.id(),1 e& k! B/ V6 B: P) q& u% F; t
- 'show_overlay',# e* a/ M' u" u) s# v0 |0 m
- {
' Q0 |" U2 v) D1 ~5 G0 R" e - 'overlay': 'command_palette',
1 k# h* \- i% i' X - 'command': self.name(),
3 h9 U7 c- Y8 Y, L+ b9 ? - 'args': args! H2 G" j5 g. ?, L
- }
# L2 T% P0 b7 S! [9 _ - )
' B4 x* X/ Y/ A/ k3 D - return# F9 p2 Y9 n1 k( ]6 D
- raise
% x( M- b" z- }/ h8 v, v1 U - 3 g9 Q0 D$ n6 b
- def run(self):
. t6 S2 q: Y/ |3 M+ | - pass
. t$ W& t6 Z+ M, C- _1 ]1 l: H0 o9 H% [$ R - " }- P- [, ^. C
) O9 f* C& P6 K2 ~" D& [1 T- class TextCommand(Command):$ t/ q& g5 ? J9 M
- def __init__(self, view):
1 a+ e8 M$ @$ O/ z G! u+ _4 [$ _ - self.view = view
8 R }+ l4 @# K4 ]7 r: ?9 b
) g# `' N& j- m' l4 ]; F) f- def run_(self, edit_token, args):
. W( Y* B3 i" w2 N# u - args = self.filter_args(args)
$ c0 h# L) f! | - try:
- x1 r. O$ I+ I0 M" q - if args:
% ?! ?) `, L. t6 x; t- D. T - edit = self.view.begin_edit(edit_token, self.name(), args). |5 `# h$ b$ n- Q3 D0 [
- try:
/ B. o, k5 I5 v @% M - return self.run(edit, **args)
4 V" ]- q0 T. \9 J9 c& [9 A& D2 q - finally:
, i' I/ F) J: B6 f1 C& y3 v - self.view.end_edit(edit). T9 d3 _1 i Y) a/ a, {) W. l
- else:
; E, m: f2 H9 W8 u% c* C( D - edit = self.view.begin_edit(edit_token, self.name())
4 w& \) Z. S; E( ^9 \: u - try:
5 ]- C, H; P$ ]' Y1 L - return self.run(edit)# I9 h3 z! W6 Z* J4 r: Z5 [% w* l
- finally:! b. Z7 y- M* W8 H
- self.view.end_edit(edit)" `5 A5 o) \. c# X6 m
- except (TypeError) as e: l+ B- }' T/ B; x' f p1 ^4 n
- if 'required positional argument' in str(e):
: ?* V) o, a7 S - if sublime_api.view_can_accept_input(self.view.id(), self.name(), args):
3 F9 M) |; T' M9 |4 J0 v - sublime_api.window_run_command(9 E7 T: S6 Z& r' F* ?9 Q% r
- sublime_api.view_window(self.view.id()),; D" j, @& {7 a/ o
- 'show_overlay',
4 J2 B W i1 t# N; m3 Q% b$ U5 I" U - {4 d* }' E7 T# b7 L
- 'overlay': 'command_palette',
+ W; d1 L7 q7 V3 i/ N6 R- Y+ c - 'command': self.name(),1 O6 y( z/ Z2 g1 O1 d" N) b: ~( O1 G) K
- 'args': args6 i; Q0 \& _2 `& f, O, V$ ?
- }
, K0 T! Z6 @! p5 [0 K9 m - )
" M3 T; {/ M7 H, \0 ]2 _: A - return0 z/ u% v M, v. t
- raise
4 Y) o! L! ^4 h9 Z1 Q: h! Y0 a
. s6 l, ~2 X& R+ `9 p- def run(self, edit):
% w% w( J2 W0 [- l) G - pass) }% u; Y2 z7 I$ K s- E) i
- H( `, z. R6 D9 }
( g8 I! H) ]) t% W( @- class EventListener(object):
- O/ d- F! T# `8 o1 E! Z' m, B- @ - pass5 S/ m x% ]+ n0 a
- " Z2 \( I j6 g0 |% W/ ?, m1 }& n4 C
* M+ X1 ?4 `4 b4 K4 N- class ViewEventListener(object):
6 T$ I$ A# s+ F6 _( A/ I; A - @classmethod
7 s. y4 T( D( g7 W - def is_applicable(cls, settings):
: d0 o% @- E$ ?; X1 M4 J L - return True4 i- C1 E- j/ ?! {4 _
% E# B. ~- c0 k" Z; H- @classmethod1 m- ]6 [/ g' P# b! [+ [ L
- def applies_to_primary_view_only(cls): l" {5 r2 U. e1 b$ i
- return True# M* G' r: g6 y, v# ?3 H
- 6 j4 e3 c, L& D0 C
- def __init__(self, view):/ s) V: L) P9 U0 C2 _5 v5 u
- self.view = view
' G8 m' a+ |$ H6 K* R) z& U: [
# z1 p$ \: L R4 z- 9 z# s# w. G* Z$ A( u2 G- K
- class MultizipImporter(object):
/ n: T! v. B/ B- A* Z - def __init__(self):
2 S3 \4 A) O0 D7 q! C - self.loaders = []
" j, q1 e/ X/ M/ L% i - self.file_loaders = []
) x/ C0 k2 e+ @# k
% Z' {# R' p0 ?$ B- def find_module(self, fullname, path=None):
# |5 t# e# C! ]% q0 q& f - if not path:
: F, s. |# T0 G" e/ B - for l in self.loaders:
' e% `9 u' R+ r% @9 ]; d - if l.name == fullname:1 k9 N9 c5 @- M; Y' x. q
- return l
. q# }. _+ }# w# ?6 [" \7 d; p# V - - L' k& T6 ^- N" K0 b
- for l in self.loaders:/ w* O e' r' F+ N4 h* R$ Q
- if path == [l.zippath]:) k+ S& r5 Q. I
- if l.has(fullname):. w! j2 @- \. m7 Y9 M0 U
- return l
w3 Z* K% p$ S; X- m - 9 _" Z$ i: X3 |# i
- return None% `! ?0 c0 E5 r3 U/ E3 G
( k$ R) d# E+ t/ [- 6 ]2 r# p% m$ Y m" T4 `
- class ZipLoader(object):
4 J% G* R8 ]# q+ F0 w - def __init__(self, zippath):( D+ c( s( V+ I( w& a* o Q' @# W
- self.zippath = zippath
' _- c7 H M1 y- Q% Z; v3 P) f - self.name = os.path.splitext(os.path.basename(zippath))[0]
9 k2 f- k6 f8 l1 u! v# W) u - self._scan_zip()
. B/ j! }. {- ?8 i4 H' N$ P: m - 5 Y* R1 s" ?2 @& D* t( D
- def has(self, fullname):
6 `3 g3 _) w7 g# e! p - name, key = fullname.split('.', 1)
8 E; y- U3 B w8 J - if name == self.name and key in self.contents:
8 B4 K% l# Q" o3 ~ - return True$ z. x, Z# Q+ N& k" V
- # G8 }0 {3 \& \2 J; c4 }7 a* n
- override_file = os.path.join(override_path, os.sep.join(fullname.split('.')) + '.py')
) p; U) A' M, ?" z# U& n) N - if os.path.isfile(override_file):* L- @ @6 Y; ~5 ]
- return True( z7 c5 J1 N4 j% l/ b h& p" I2 j
s2 B, F8 i5 C0 _: A9 R! y- override_package = os.path.join(override_path, os.sep.join(fullname.split('.')))
1 i9 }; Z8 p I; X; C1 C - if os.path.isdir(override_package):
0 k/ o5 s) A7 x/ ^7 w S - return True
3 B3 K' B- ^4 y* R - 2 m$ q! F+ n+ P5 F+ j& b6 y
- return False. J \$ W8 j" C5 l
- $ p1 h! Y" Y# \- _
- def load_module(self, fullname):5 ^5 r$ @3 n7 Y7 s, Z, V
- # Only if a module is being reloaded and hasn't been scanned recently
7 S: {$ a, B0 F3 n - # do we force a refresh of the contents of the .sublime-package. This
% ^' ^ r, o, k. x: J) z - # allows proper code upgrades using Package Control.. e" Q$ R% W# V( M9 S& l+ _
- if fullname in imp._RELOADING:" v7 F _1 t' p; P8 z# w
- if self.refreshed < time.time() - 5:* E3 j8 t X/ n
- self._scan_zip()( V+ t% l2 _* {3 R! E( U. L8 X4 I, I
7 ]& T5 L6 o+ o. ]- source, source_path, is_pkg = self._read_source(fullname)
& I! y- l, G1 L! n
& L1 x2 e/ V4 m4 a- if source is None:
& z, s: P! g7 w$ ^ - raise ImportError("No module named '%s'" % fullname)
& L+ ]! s8 O- r; H8 ^
1 n2 s$ E4 u G0 g- is_new = False/ F3 X6 Z1 M8 H. o0 Y! J1 n2 s
- if fullname in sys.modules:
1 L& o L, _2 o" b - mod = sys.modules[fullname]; S5 K4 S( e2 V
- old_mod_file = mod.__file__
- b5 e3 P) h; a9 c& Q" t - else:
+ H; K' _; [% V% E - is_new = True
2 c: l8 w; e' C: b - mod = sys.modules.setdefault(fullname, imp.new_module(fullname))
|1 `6 y) M8 m8 `5 T9 U - mod.__name__ = fullname( U# V( g2 J7 a& c
- mod.__path__ = [self.zippath]4 j- i! U/ I% E
- mod.__loader__ = self) m+ F4 I( _) Q8 I
- ; p( U9 g0 A* ^# n: s) p! W
- mod.__file__ = source_path9 a* c! t0 q P3 l5 V8 O
- ' x S% Y; s& O/ I4 h
- if is_pkg:
1 m! i. j8 K* ]0 L9 w- Q) ^ - mod.__package__ = mod.__name__: q8 X# `$ I3 @ k8 a% X; p
- else:9 [: U/ Q& w+ i: p7 @
- mod.__package__ = fullname.rpartition('.')[0]9 Q3 C5 e9 U: U0 A% l+ S% V& d3 D; `
: r3 z" p# i! L" l- try:) R; V. J# q( M/ R, s
- exec(compile(source, source_path, 'exec'), mod.__dict__)
1 j( W6 z- K, N/ b% f: j - return mod
" I3 N3 Z% T% O3 ?$ \/ D
+ ~, O" a2 l% \5 a$ K( `: j! X! y- except:0 \8 i- ` x% W) ?. F
- if is_new:
5 W% G9 N( t4 ~3 @7 `5 C - del sys.modules[fullname]
8 V/ p' Q0 {5 u) c - else:
Q2 ^2 L. g* T; X; O0 D - mod.__file__ = old_mod_file
' H( U( p; n3 N, d8 I - raise$ ?; r0 z8 y% v
! l. o/ g6 i. s1 V# C( W) l7 e- def get_source(self, fullname):
, n6 B* c9 Z" K. h! B' K - name, key = fullname.split('.', 1)
" Q$ H4 Y4 J& A% U, y - if name != self.name:, T4 N; l2 T& N1 S g
- return None
1 K2 O: T ] O: k" @/ H - source, _, _ = self._read_source(fullname)
& y9 o% D0 ?0 E( b3 @/ k8 |+ U - return source) u, C% e, n2 A2 f8 O$ L9 f8 ^. M6 ~
p! w" b4 `8 `- R; b$ j& Z4 T3 K& F- def _read_source(self, fullname):
$ ^5 h* G, @3 z u: i5 J - name_parts = fullname.split('.')% O) c# `: E/ N6 ^' K
- override_basename = os.path.join(override_path, *name_parts)
& D7 E- V+ n$ V) l& w' g: N - override_py = override_basename + '.py'
9 \: T3 u/ M) b& ^ - override_init = os.path.join(override_basename, '__init__.py')
2 q1 ?$ f A& A% Q$ S - # C8 X# `& b" u5 ~' t4 k! e" G9 u& l
- if os.path.isfile(override_py):
; N$ X0 f' H) N9 ^ V - try:* h6 ?. I) L. ?; F! U& Q
- with open(override_py, 'r', encoding='utf-8') as f:
& o# `/ t/ {! B9 f - return (f.read(), override_py, False)2 X+ o6 ^" ~8 V; T* s8 V4 t8 `
- except (Exception) as e:
3 a( | Z5 Y1 V5 b) H - print(override_py, 'could not be read:', e)3 C' O! S9 \2 J& e$ J* m1 D
; E* Q5 N" {1 M( V& y* m. ^- if os.path.isfile(override_init):+ d V( f% p/ v% A8 N' G! z
- try:& W, U9 C& f. f$ h/ o/ r$ q
- with open(override_init, 'r', encoding='utf-8') as f:
9 P, N3 O$ v* M9 V. c: F - return (f.read(), override_init, True)
0 G" R0 l4 {5 `5 p" V' U - except (Exception) as e:
% ?' ^4 ^- t/ z6 s1 w% O7 I" R! y - print(override_init, 'could not be read:', e)
o/ r; k n* k9 E. |. x# e- b& c6 K - % S T: y( c: i( v* Q
- key = '.'.join(name_parts[1:])4 x+ l, z( U" |: R
- if key in self.contents:% r/ _, m# s& ~ Y3 _9 s/ _. {
- source = self.contents[key]
6 \) i/ O! P3 @# Y - source_path = os.path.join(self.zippath, self.filenames[key]).rstrip(os.sep)0 o6 f- m( Z( S4 F3 C6 p
- is_pkg = key in self.packages
0 }: c4 h; _* Z! q+ ~ - return (source, source_path, is_pkg)' s2 D% o) |' @# @7 j
- . }8 b+ _' x0 r! R2 C
- # This allows .py overrides to exist in subfolders that: a9 S" G5 k' Z) Z% S9 B/ `/ C; P+ |
- # 1. Do not exist in the .sublime-package file& R5 x: g: b% m. _' L, o
- # 2. Do not contain an __init__.py
- r; H& c) {, }" j" S - if os.path.isdir(override_basename):
; v6 g% r) d( |$ d* I- |. M - return ('', override_basename, True)
: ~) h) ?) w3 d g7 J
9 g$ {& r2 J; \4 a4 t. P1 E! q- return (None, None, False)% A6 B' f0 O, v! \1 k
) B9 I9 M" S4 k# P- def _scan_zip(self):% [# y0 O" a S, f& o9 Y
- self.contents = {"": ""}2 O: M2 [+ N) f. O% K. P+ f4 m' u1 `
- self.filenames = {"": ""}
; x! p8 G& V/ w2 V - self.packages = {""}
4 n: s! Y/ ^1 \ - self.refreshed = time.time()
4 g. |& J( b" ~/ z/ k' w - 3 s; D3 C/ Z* U/ P3 {; @" t2 m$ |
- try:% t3 C6 g; }( t
- with zipfile.ZipFile(self.zippath, 'r') as z:
) ?# k% L+ y) C) ]1 q4 } - files = [i.filename for i in z.infolist()]) Z% n# K! Z* H. L% |- U
3 n/ e j1 H8 D/ \/ V6 G- for f in files:
. O* M0 q, r3 q+ T5 x/ n9 b - base, ext = os.path.splitext(f)
% U3 L! X7 C4 F; _& Y7 d: g - if ext != ".py":9 E+ o- J0 h* P
- continue
4 x- u5 b9 a2 w, M9 _
1 O4 V4 N8 X. S# D5 K0 ^% l- paths = base.split('/')
5 P. H4 c9 J; l - if len(paths) > 0 and paths[len(paths) - 1] == "__init__":5 x: D& n6 U9 q+ s
- paths.pop()
0 c M/ _) T% U N - self.packages.add('.'.join(paths))
: @1 |) R; S; n, o/ `
( |1 ^9 ?- N9 W- m" M. i9 W- try:
* ]/ Y g' w- `' ?% `) W/ H, L - pkg_path = '.'.join(paths)* t& P3 c0 {. }: Y; {9 S
- self.contents[pkg_path] = z.read(f).decode('utf-8')
" ?) a# d& _! H( z - self.filenames[pkg_path] = f
( d( g; {( X* o; g - except UnicodeDecodeError:2 y L$ q" x5 |- u0 j% d/ e
- print(f, "in", self.zippath, "is not utf-8 encoded, unable to load plugin")$ i' y" v7 a, U5 o
- continue
* O$ X# @! _( ^# P/ c2 e
, S/ a( }; v' p- while len(paths) > 1:% t9 Z: ~4 `3 [" d6 r
- paths.pop()3 E' N# _) ^: h9 I6 o% b
- parent = '.'.join(paths)
$ B" j( z4 {$ b; d0 G( m - if parent not in self.contents:
2 F1 X+ F* g: _8 r* Q6 m - self.contents[parent] = ""
3 [* Z f5 L& W( i/ ]. i - self.filenames[parent] = parent) h: h7 }1 ^5 k+ u' @
- self.packages.add(parent)- o( C; ^ T% ?2 w! L
- except (Exception) as e:
/ J! |" g0 X2 p9 @( J) h - print("Error loading %s:" % self.zippath, e)
$ i$ r5 N* s2 ^, Q
: F+ j, i- k: {
' M1 q6 U K/ @1 B0 |0 t- override_path = None- j6 q. ]- H# R) B* k, ?
- multi_importer = MultizipImporter()# ?4 a% k" v# |5 F% K! Y5 M
- sys.meta_path.insert(0, multi_importer)
2 B$ z. b/ X- O' H5 N - $ b( l S1 O7 _" K- N
- ( L- v4 z9 |8 a0 I3 U3 h! N
- def update_compressed_packages(pkgs):
/ r/ x; j0 ^& d6 \ - multi_importer.loaders = []
& q E6 o/ _9 `$ ?( {- i - for p in pkgs:1 w5 A5 A- E4 w- j5 C* y
- try:3 ?' |. T. u, M; A8 w
- multi_importer.loaders.append(ZipLoader(p))5 `/ y" }( J- ^; V- B F
- except (FileNotFoundError, zipfile.BadZipFile) as e:" a% n$ N1 V% `) O/ G; u" t
- print("error loading " + p + ": " + str(e))
' E, k7 I7 i+ H
6 O2 v" H. v& g& {. L5 h* u
8 E, }/ G6 l7 @- def set_override_path(path):
' T' h: k; Q6 ` - global override_path$ ]' b5 x/ I% f' s7 y3 w6 ~
- override_path = path1 s: \/ }; a1 m- p
复制代码 2 C- N/ H* O1 d2 K5 q. U: m+ G1 }
, u% z; | A5 Z J+ h
$ i$ Z$ c: N4 v8 W r L: @/ \; ]# z q z- P
|
|