-
Notifications
You must be signed in to change notification settings - Fork 129
/
pick_color_command.py
157 lines (127 loc) · 5.71 KB
/
pick_color_command.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
"""A ST3 commands for converting colors between formats."""
import os
import stat
import subprocess
import threading
from ast import literal_eval
try:
from . import st_helper
from . import path
from .color_converter import ColorConverter
from .color_searcher import ColorSearcher
from .color_selection_listener import search_colors_in_selection
from .load_resource import copy_resource, get_binary_resource_size
from .regex_compiler import compile_regex
from .settings import Settings, COLOR_HIGHLIGHTER_SETTINGS_NAME
except ValueError:
import st_helper
import path
from color_converter import ColorConverter
from color_searcher import ColorSearcher
from color_selection_listener import search_colors_in_selection
from load_resource import copy_resource, get_binary_resource_size
from regex_compiler import compile_regex
from settings import Settings, COLOR_HIGHLIGHTER_SETTINGS_NAME
if st_helper.running_in_st():
import sublime # pylint: disable=import-error
import sublime_plugin # pylint: disable=import-error
else:
from . import sublime
from . import sublime_plugin
class ColorHighlighterPickColor(sublime_plugin.TextCommand):
"""Convert currently selected colors to a next color format."""
def run(self, edit): # pylint: disable=unused-argument
"""
Run the command.
Arguments:
- edit - an edit object.
"""
_run_async(self._open_color_picker)
def _open_color_picker(self):
_init_color_picker()
settings = Settings(sublime.load_settings(COLOR_HIGHLIGHTER_SETTINGS_NAME))
formats = [value for value in sorted(settings.regex_compiler.formats.keys())]
color_converter = ColorConverter(formats)
colors = [value for value in _get_colors(self.view, settings, formats, color_converter)]
replace_colors = len(colors) > 0
if replace_colors:
initial_color = colors[0][1][1:]
else:
initial_color = "FFFFFFFF"
popen = subprocess.Popen(
[path.color_picker_file(path.ABSOLUTE), initial_color],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
output, error = popen.communicate()
output = output.decode("utf-8")
error = error.decode("utf-8")
if error is not None and error:
print("Color Picker error:\n" + error)
if output == "CANCEL":
if settings.debug:
print("ColorHighlighter: action=run_command name=color_highlighter_pick_color result=canceled")
return
replace_data = []
if replace_colors:
for (region, _, format_name) in colors:
new_color = color_converter.from_color((output, format_name))
if settings.debug:
print(("ColorHighlighter: action=run_command name=color_highlighter_pick_color result=replace " +
"region=%s format=%s color=%s") % (region.region(), format_name, new_color))
replace_data.append((region.region(), new_color))
else:
for region in self.view.sel():
if settings.debug:
print(("ColorHighlighter: action=run_command name=color_highlighter_pick_color result=insert " +
"region=%s color=%s") % (region, output))
replace_data.append((region, output))
self.view.run_command("color_highlighter_impl_replace_color", {"replace_data": str(replace_data)})
def _get_colors(view, settings, formats, color_converter):
color_searcher = ColorSearcher(compile_regex(settings.regex_compiler), color_converter)
for (region, color, match) in search_colors_in_selection(view, color_searcher):
format_name = _get_format_name(match, formats)
yield region, color, format_name
def _get_format_name(match, formats):
for name in formats:
if match.get(name, None) is not None:
return name
raise Exception("Unreachable code.")
class ColorHighlighterImplReplaceColor(sublime_plugin.TextCommand):
"""Replace texts in a list of regions."""
def run(self, edit, replace_data):
"""
Run the command.
Arguments:
- edit - an edit object.
- replace_data - string representation of a list of (region, color) pairs.
"""
regions_to_replace = literal_eval(replace_data)
offset = 0
for (region, color) in sorted(regions_to_replace):
self.view.replace(edit, sublime.Region(offset + region[0], offset + region[1]), color)
offset -= (region[1] - region[0])
offset += len(color)
def _run_async(callback):
if st_helper.is_st3():
sublime.set_timeout_async(callback, 0)
else:
_RunAsync(callback).start()
class _RunAsync(threading.Thread):
def __init__(self, callback):
self.callback = callback
threading.Thread.__init__(self)
def run(self):
self.callback()
def _create_if_not_exists(path_to_create):
if not os.path.exists(path_to_create):
os.mkdir(path_to_create)
def _init_color_picker():
_create_if_not_exists(path.data_path(path.ABSOLUTE))
_create_if_not_exists(path.color_picker_path(path.ABSOLUTE))
color_picker_file = path.color_picker_file(path.ABSOLUTE)
color_picker_resource = path.color_picker_binary(path.RELATIVE)
if (os.path.exists(color_picker_file) and
os.path.getsize(color_picker_file) == get_binary_resource_size(color_picker_resource)):
return
copy_resource(color_picker_resource, color_picker_file)
chmod_flags = stat.S_IXUSR | stat.S_IXGRP | stat.S_IRUSR | stat.S_IRUSR | stat.S_IWUSR | stat.S_IWGRP
os.chmod(color_picker_file, chmod_flags)