-
Notifications
You must be signed in to change notification settings - Fork 61
/
CSScomb.py
119 lines (97 loc) · 3.69 KB
/
CSScomb.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# coding: utf-8
import json
import os
import platform
import sublime
import sublime_plugin
from subprocess import Popen, PIPE
# monkeypatch `Region` to be iterable
sublime.Region.totuple = lambda self: (self.a, self.b)
sublime.Region.__iter__ = lambda self: self.totuple().__iter__()
COMB_PATH = os.path.join(sublime.packages_path(), os.path.dirname(os.path.realpath(__file__)), 'csscomb.js')
class CssCombCommand(sublime_plugin.TextCommand):
def run(self, edit):
syntax = self.get_syntax()
if not syntax:
return
config = self.get_config()
if not self.has_selection():
region = sublime.Region(0, self.view.size())
originalBuffer = self.view.substr(region)
combed = self.comb(originalBuffer, syntax, config)
if combed:
self.view.replace(edit, region, combed)
return
for region in self.view.sel():
if region.empty():
continue
originalBuffer = self.view.substr(region)
combed = self.comb(originalBuffer, syntax, config)
if combed:
self.view.replace(edit, region, combed)
def comb(self, css, syntax, config):
config = json.dumps(config)
folder = os.path.dirname(self.view.file_name())
try:
p = Popen(['node', COMB_PATH] + [syntax, config, folder],
stdout=PIPE, stdin=PIPE, stderr=PIPE,
env=self.get_env(), shell=self.is_windows())
except OSError:
raise Exception("Couldn't find Node.js. Make sure it's in your " +
'$PATH by running `node -v` in your command-line.')
stdout, stderr = p.communicate(input=css.encode('utf-8'))
if stdout:
return stdout.decode('utf-8')
else:
sublime.error_message('CSScomb error:\n%s' % stderr.decode('utf-8'))
def get_env(self):
env = None
if self.is_osx():
env = os.environ.copy()
env['PATH'] += self.get_node_path()
return env
def get_node_path(self):
return self.get_settings().get('node-path')
def get_settings(self):
settings = self.view.settings().get('CSScomb')
if settings is None:
settings = sublime.load_settings('CSScomb.sublime-settings')
return settings
def get_config(self):
settings = self.get_settings()
config = settings.get('config')
return config
def get_syntax(self):
if self.is_css():
return 'css'
if self.is_scss():
return 'scss'
if self.is_sass():
return 'sass'
if self.is_less():
return 'less'
if self.is_unsaved_buffer_without_syntax():
return 'css'
return False
def has_selection(self):
for sel in self.view.sel():
start, end = sel
if start != end:
return True
return False
def is_osx(self):
return platform.system() == 'Darwin'
def is_windows(self):
return platform.system() == 'Windows'
def is_unsaved_buffer_without_syntax(self):
return self.view.file_name() == None and self.is_plaintext() == True
def is_plaintext(self):
return self.view.scope_name(0).startswith('text.plain')
def is_css(self):
return self.view.scope_name(0).startswith('source.css')
def is_scss(self):
return self.view.scope_name(0).startswith('source.scss') or self.view.file_name().endswith('.scss')
def is_sass(self):
return self.view.scope_name(0).startswith('source.sass')
def is_less(self):
return self.view.scope_name(0).startswith('source.less')