diff --git a/powerline/config_files/colors.json b/powerline/config_files/colors.json index 5975572c..3bbb90f2 100644 --- a/powerline/config_files/colors.json +++ b/powerline/config_files/colors.json @@ -77,6 +77,22 @@ "green_yellow_red": [ [190, 184, 178, 172, 166, 160], ["8ae71c", "8ce71c", "8fe71c", "92e71c", "95e71d", "98e71d", "9ae71d", "9de71d", "a0e71e", "a3e71e", "a6e71e", "a8e71e", "abe71f", "aee71f", "b1e71f", "b4e71f", "b6e720", "b9e720", "bce720", "bfe720", "c2e821", "c3e721", "c5e621", "c7e521", "c9e522", "cbe422", "cde322", "cfe222", "d1e223", "d3e123", "d5e023", "d7df23", "d9df24", "dbde24", "dddd24", "dfdc24", "e1dc25", "e3db25", "e5da25", "e7d925", "e9d926", "e9d626", "e9d426", "e9d126", "e9cf27", "e9cc27", "e9ca27", "e9c727", "e9c528", "e9c228", "e9c028", "e9bd28", "e9bb29", "e9b829", "e9b629", "e9b329", "e9b12a", "e9ae2a", "e9ac2a", "e9a92a", "eaa72b", "eaa42b", "eaa22b", "ea9f2b", "ea9d2c", "ea9b2c", "ea982c", "ea962c", "ea942d", "ea912d", "ea8f2d", "ea8d2d", "ea8a2e", "ea882e", "ea862e", "ea832e", "ea812f", "ea7f2f", "ea7c2f", "ea7a2f", "eb7830", "eb7530", "eb7330", "eb7130", "eb6f31", "eb6c31", "eb6a31", "eb6831", "eb6632", "eb6332", "eb6132", "eb5f32", "eb5d33", "eb5a33", "eb5833", "eb5633", "eb5434", "eb5134", "eb4f34", "eb4d34", "ec4b35"] + ], + "green_yellow_orange_red": [ + [2, 3, 9, 1], + ["719e07", "739d06", "759c06", "779c06", "799b06", "7b9a05", "7d9a05", "7f9905", "819805", "839805", "859704", "879704", "899604", "8b9504", "8d9504", "8f9403", "919303", "949303", "969203", "989102", "9a9102", "9c9002", "9e9002", "a08f02", "a28e01", "a48e01", "a68d01", "a88c01", "aa8c01", "ac8b00", "ae8a00", "b08a00", "b28900", "b58900", "b58700", "b68501", "b78302", "b78102", "b87f03", "b97d04", "b97b04", "ba7905", "bb7806", "bb7606", "bc7407", "bd7208", "bd7008", "be6e09", "bf6c0a", "bf6a0a", "c0690b", "c1670c", "c1650c", "c2630d", "c3610e", "c35f0e", "c45d0f", "c55b10", "c55a10", "c65811", "c75612", "c75412", "c85213", "c95014", "c94e14", "ca4c15", "cb4b16", "cb4a16", "cc4917", "cc4818", "cd4719", "cd4719", "ce461a", "ce451b", "cf441c", "cf441c", "d0431d", "d0421e", "d1411f", "d1411f", "d24020", "d23f21", "d33e22", "d33e22", "d43d23", "d43c24", "d53b25", "d53b25", "d63a26", "d63927", "d73828", "d73828", "d83729", "d8362a", "d9352b", "d9352b", "da342c", "da332d", "db322e", "dc322f"] + ], + "yellow_red": [ + [220, 178, 172, 166, 160], + ["ffd700", "fdd500", "fbd300", "fad200", "f8d000", "f7cf00", "f5cd00", "f3cb00", "f2ca00", "f0c800", "efc700", "edc500", "ebc300", "eac200", "e8c000", "e7bf00", "e5bd00", "e3bb00", "e2ba00", "e0b800", "dfb700", "ddb500", "dbb300", "dab200", "d8b000", "d7af00", "d7ad00", "d7ab00", "d7aa00", "d7a800", "d7a700", "d7a500", "d7a300", "d7a200", "d7a000", "d79f00", "d79d00", "d79b00", "d79a00", "d79800", "d79700", "d79500", "d79300", "d79200", "d79000", "d78f00", "d78d00", "d78b00", "d78a00", "d78800", "d78700", "d78500", "d78300", "d78200", "d78000", "d77f00", "d77d00", "d77b00", "d77a00", "d77800", "d77700", "d77500", "d77300", "d77200", "d77000", "d76f00", "d76d00", "d76b00", "d76a00", "d76800", "d76700", "d76500", "d76300", "d76200", "d76000", "d75f00", "d75b00", "d75700", "d75300", "d74f00", "d74c00", "d74800", "d74400", "d74000", "d73c00", "d73900", "d73500", "d73100", "d72d00", "d72900", "d72600", "d72200", "d71e00", "d71a00", "d71600", "d71300", "d70f00", "d70b00", "d70700"] + ], + "yellow_orange_red": [ + [3, 9, 1], + ["b58900", "b58700", "b58600", "b68501", "b68401", "b78202", "b78102", "b88003", "b87f03", "b87d03", "b97c04", "b97b04", "ba7a05", "ba7805", "bb7706", "bb7606", "bc7507", "bc7307", "bc7207", "bd7108", "bd7008", "be6e09", "be6d09", "bf6c0a", "bf6b0a", "c06a0b", "c0680b", "c0670b", "c1660c", "c1650c", "c2630d", "c2620d", "c3610e", "c3600e", "c35e0e", "c45d0f", "c45c0f", "c55b10", "c55910", "c65811", "c65711", "c75612", "c75412", "c75312", "c85213", "c85113", "c94f14", "c94e14", "ca4d15", "ca4c15", "cb4b16", "cb4a16", "cb4a17", "cc4917", "cc4918", "cc4818", "cd4819", "cd4719", "cd471a", "ce461a", "ce461b", "ce451b", "cf451c", "cf441c", "cf441d", "d0431d", "d0431e", "d0421e", "d1421f", "d1411f", "d14120", "d24020", "d24021", "d23f21", "d33f22", "d33e22", "d33e23", "d43d23", "d43d24", "d43c24", "d53c25", "d53b25", "d53b26", "d63a26", "d63a27", "d63927", "d73928", "d73828", "d73829", "d83729", "d8372a", "d8362a", "d9362b", "d9352b", "d9352c", "da342c", "da342d", "da332d", "db332e"] + ], + "blue_red": [ + [39, 74, 68, 67, 103, 97, 96, 132, 131, 167, 203, 197], + ["19b4fe", "1bb2fc", "1db1fa", "1faff8", "22aef6", "24adf4", "26abf2", "29aaf0", "2ba9ee", "2da7ec", "30a6ea", "32a5e8", "34a3e6", "36a2e4", "39a0e2", "3b9fe1", "3d9edf", "409cdd", "429bdb", "449ad9", "4798d7", "4997d5", "4b96d3", "4d94d1", "5093cf", "5292cd", "5490cb", "578fc9", "598dc7", "5b8cc6", "5e8bc4", "6089c2", "6288c0", "6487be", "6785bc", "6984ba", "6b83b8", "6e81b6", "7080b4", "727eb2", "757db0", "777cae", "797aac", "7b79ab", "7e78a9", "8076a7", "8275a5", "8574a3", "8772a1", "89719f", "8c709d", "8e6e9b", "906d99", "926b97", "956a95", "976993", "996791", "9c668f", "9e658e", "a0638c", "a3628a", "a56188", "a75f86", "a95e84", "ac5c82", "ae5b80", "b05a7e", "b3587c", "b5577a", "b75678", "ba5476", "bc5374", "be5273", "c05071", "c34f6f", "c54e6d", "c74c6b", "ca4b69", "cc4967", "ce4865", "d14763", "d34561", "d5445f", "d7435d", "da415b", "dc4059", "de3f58", "e13d56", "e33c54", "e53a52", "e83950", "ea384e", "ec364c", "ee354a", "f13448", "f33246", "f53144", "f83042", "fa2e40"] ] } } diff --git a/powerline/config_files/colorschemes/tmux/default.json b/powerline/config_files/colorschemes/tmux/default.json index 67be9993..35686d32 100644 --- a/powerline/config_files/colorschemes/tmux/default.json +++ b/powerline/config_files/colorschemes/tmux/default.json @@ -7,19 +7,18 @@ "time": { "fg": "gray10", "bg": "gray2", "attr": ["bold"] }, "time:divider": { "fg": "gray5", "bg": "gray2" }, "email_alert": { "fg": "white", "bg": "brightred", "attr": ["bold"] }, + "email_alert_gradient": { "fg": "white", "bg": "yellow_orange_red", "attr": ["bold"] }, "hostname": { "fg": "black", "bg": "gray10", "attr": ["bold"] }, "weather": { "fg": "gray8", "bg": "gray0" }, - "weather_temp_cold": { "fg": "steelblue", "bg": "gray0" }, - "weather_temp_hot": { "fg": "darkorange3", "bg": "gray0" }, + "weather_temp_gradient": { "fg": "blue_red", "bg": "gray0" }, "weather_condition_hot": { "fg": "khaki1", "bg": "gray0" }, "weather_condition_snowy": { "fg": "skyblue1", "bg": "gray0" }, "weather_condition_rainy": { "fg": "skyblue1", "bg": "gray0" }, "uptime": { "fg": "gray8", "bg": "gray0" }, "external_ip": { "fg": "gray8", "bg": "gray0" }, "network_load": { "fg": "gray8", "bg": "gray0" }, + "network_load_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0" }, "system_load": { "fg": "gray8", "bg": "gray0" }, - "system_load_good": { "fg": "lightyellowgreen", "bg": "gray0" }, - "system_load_bad": { "fg": "gold3", "bg": "gray0" }, - "system_load_ugly": { "fg": "orangered", "bg": "gray0" } + "system_load_gradient": { "fg": "green_yellow_orange_red", "bg": "gray0" } } } diff --git a/powerline/config_files/colorschemes/vim/solarized.json b/powerline/config_files/colorschemes/vim/solarized.json index 9a55a237..2eb4c36d 100644 --- a/powerline/config_files/colorschemes/vim/solarized.json +++ b/powerline/config_files/colorschemes/vim/solarized.json @@ -23,6 +23,7 @@ "file_vcs_status_M": { "fg": "yellow", "bg": "darkgreencopper" }, "file_vcs_status_A": { "fg": "green", "bg": "darkgreencopper" }, "line_percent": { "fg": "oldlace", "bg": "lightskyblue4" }, + "line_percent_gradient": { "fg": "green_yellow_orange_red", "bg": "lightskyblue4" }, "line_current": { "fg": "gray13", "bg": "lightyellow", "attr": ["bold"] }, "line_current_symbol": { "fg": "gray13", "bg": "lightyellow" }, "col_current": { "fg": "azure4", "bg": "lightyellow" } @@ -60,6 +61,7 @@ "file_vcs_status_M": { "fg": "yellow", "bg": "lightyellow" }, "file_vcs_status_A": { "fg": "green", "bg": "lightyellow" }, "line_percent": { "fg": "oldlace", "bg": "gray61" }, + "line_percent_gradient": { "fg": "oldlace", "bg": "gray61" }, "line_current": { "fg": "gray13", "bg": "oldlace", "attr": ["bold"] }, "line_current_symbol": { "fg": "gray13", "bg": "oldlace" }, "col_current": { "fg": "azure4", "bg": "oldlace" } diff --git a/powerline/config_files/colorschemes/wm/default.json b/powerline/config_files/colorschemes/wm/default.json index 90bd6cc4..d71d4e3c 100644 --- a/powerline/config_files/colorschemes/wm/default.json +++ b/powerline/config_files/colorschemes/wm/default.json @@ -7,10 +7,10 @@ "time": { "fg": "gray10", "bg": "gray2", "attr": ["bold"] }, "time:divider": { "fg": "gray5", "bg": "gray2" }, "email_alert": { "fg": "white", "bg": "brightred", "attr": ["bold"] }, + "email_alert_gradient": { "fg": "white", "bg": "yellow_orange_red", "attr": ["bold"] }, "hostname": { "fg": "black", "bg": "gray10", "attr": ["bold"] }, "weather": { "fg": "gray8", "bg": "gray0" }, - "weather_temp_cold": { "fg": "steelblue", "bg": "gray0" }, - "weather_temp_hot": { "fg": "darkorange3", "bg": "gray0" }, + "weather_temp_gradient": { "fg": "blue_red", "bg": "gray0" }, "weather_condition_hot": { "fg": "khaki1", "bg": "gray0" }, "weather_condition_snowy": { "fg": "skyblue1", "bg": "gray0" }, "weather_condition_rainy": { "fg": "skyblue1", "bg": "gray0" }, diff --git a/powerline/lint/__init__.py b/powerline/lint/__init__.py index 6267e2f9..f7f3c451 100644 --- a/powerline/lint/__init__.py +++ b/powerline/lint/__init__.py @@ -687,7 +687,7 @@ def hl_exists(hl_group, data, context, echoerr, allow_gradients=False): for colorscheme, cconfig in data['colorscheme_configs'][ext].items(): if hl_group not in cconfig.get('groups', {}): r.append(colorscheme) - elif not allow_gradients: + elif not allow_gradients or allow_gradients == 'force': group_config = cconfig['groups'][hl_group] hadgradient = False for ckey in ('fg', 'bg'): @@ -704,14 +704,14 @@ def hl_exists(hl_group, data, context, echoerr, allow_gradients=False): hadgradient = True if allow_gradients is False and not hascolor and hasgradient: echoerr(context='Error while checking highlight group in theme (key {key})'.format(key=context_key(context)), - context_mark=hl_group.mark, + context_mark=getattr(hl_group, 'mark', None), problem='group {0} is using gradient {1} instead of a color'.format(hl_group, color), problem_mark=color.mark) r.append(colorscheme) continue if allow_gradients == 'force' and not hadgradient: echoerr(context='Error while checking highlight group in theme (key {key})'.format(key=context_key(context)), - context_mark=hl_group.mark, + context_mark=getattr(hl_group, 'mark', None), problem='group {0} should have at least one gradient color, but it has no'.format(hl_group), problem_mark=group_config.mark) r.append(colorscheme) diff --git a/powerline/segments/common.py b/powerline/segments/common.py index 551a1dd4..a0c54c2a 100644 --- a/powerline/segments/common.py +++ b/powerline/segments/common.py @@ -342,7 +342,7 @@ class WeatherSegment(ThreadedSegment): self.temp = temp self.icon_names = icon_names - def render(self, icons=None, unit='C', temperature_format=None, **kwargs): + def render(self, icons=None, unit='C', temp_format=None, temp_coldest=-30, temp_hottest=40, **kwargs): if not hasattr(self, 'icon_names'): return None @@ -354,8 +354,14 @@ class WeatherSegment(ThreadedSegment): else: icon = weather_conditions_icons[self.icon_names[-1]] - temperature_format = temperature_format or ('{temp:.0f}' + temp_units[unit]) + temp_format = temp_format or ('{temp:.0f}' + temp_units[unit]) temp = temp_conversions[unit](self.temp) + if self.temp <= temp_coldest: + gradient_level = 0 + elif self.temp >= temp_hottest: + gradient_level = 100 + else: + gradient_level = (self.temp - temp_coldest) * 100.0 / (temp_hottest - temp_coldest) groups = ['weather_condition_' + icon_name for icon_name in self.icon_names] + ['weather_conditions', 'weather'] return [ { @@ -364,10 +370,11 @@ class WeatherSegment(ThreadedSegment): 'divider_highlight_group': 'background:divider', }, { - 'contents': temperature_format.format(temp=temp), - 'highlight_group': ['weather_temp_cold' if int(self.temp) < 0 else 'weather_temp_hot', 'weather_temp', 'weather'], + 'contents': temp_format.format(temp=temp), + 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'draw_divider': False, 'divider_highlight_group': 'background:divider', + 'gradient_level': gradient_level, }, ] @@ -388,18 +395,26 @@ weather conditions. location query for your current location, e.g. ``oslo, norway`` :param dict icons: dict for overriding default icons, e.g. ``{'heavy_snow' : u'❆'}`` -:param str temperature_format: +:param str temp_format: format string, receives ``temp`` as an argument. Should also hold unit. +:param float temp_coldest: + coldest temperature. Any temperature below it will have gradient level equal + to zero. +:param float temp_hottest: + hottest temperature. Any temperature above it will have gradient level equal + to 100. Temperatures between ``temp_coldest`` and ``temp_hottest`` receive + gradient level that indicates relative position in this interval + (``100 * (cur-coldest) / (hottest-coldest)``). Divider highlight group used: ``background:divider``. -Highlight groups used: ``weather_conditions`` or ``weather``, ``weather_temp_cold`` or ``weather_temp_hot`` or ``weather_temp`` or ``weather``. +Highlight groups used: ``weather_conditions`` or ``weather``, ``weather_temp_gradient`` (gradient) or ``weather``. Also uses ``weather_conditions_{condition}`` for all weather conditions supported by Yahoo. ''') def system_load(format='{avg:.1f}', threshold_good=1, threshold_bad=2): - '''Return normalized system load average. + '''Return system load average. Highlights using ``system_load_good``, ``system_load_bad`` and ``system_load_ugly`` highlighting groups, depending on the thresholds @@ -408,13 +423,19 @@ def system_load(format='{avg:.1f}', threshold_good=1, threshold_bad=2): :param str format: format string, receives ``avg`` as an argument :param float threshold_good: - threshold for "good load" highlighting + threshold for gradient level 0: any normalized load average below this + value will have this gradient level. :param float threshold_bad: - threshold for "bad load" highlighting + threshold for gradient level 100: any normalized load average above this + value will have this gradient level. Load averages between + ``threshold_good`` and ``threshold_bad`` receive gradient level that + indicates relative position in this interval: + (``100 * (cur-good) / (bad-good)``). + Note: both parameters are checked against normalized load averages. Divider highlight group used: ``background:divider``. - Highlight groups used: ``system_load_good`` or ``system_load``, ``system_load_bad`` or ``system_load``, ``system_load_ugly`` or ``system_load``. It is recommended to define all highlight groups. + Highlight groups used: ``system_load_gradient`` (gradient) or ``system_load``. ''' global cpu_count try: @@ -425,16 +446,17 @@ def system_load(format='{avg:.1f}', threshold_good=1, threshold_bad=2): for avg in os.getloadavg(): normalized = avg / cpu_num if normalized < threshold_good: - hl = 'system_load_good' + gradient_level = 0 elif normalized < threshold_bad: - hl = 'system_load_bad' + gradient_level = (normalized - threshold_good) * 100.0 / (threshold_bad - threshold_good) else: - hl = 'system_load_ugly' + gradient_level = 100 ret.append({ 'contents': format.format(avg=avg), - 'highlight_group': [hl, 'system_load'], + 'highlight_group': ['system_load_gradient', 'system_load'], 'draw_divider': False, 'divider_highlight_group': 'background:divider', + 'gradient_level': gradient_level, }) ret[0]['draw_divider'] = True ret[0]['contents'] += ' ' @@ -616,7 +638,7 @@ class NetworkLoadSegment(KwThreadedSegment): idata['last'] = (monotonic(), _get_bytes(interface)) return idata - def render_one(self, idata, format='⬇ {recv:>8} ⬆ {sent:>8}', suffix='B/s', si_prefix=False, **kwargs): + def render_one(self, idata, recv_format='⬇ {value:>8}', sent_format='⬆ {value:>8}', suffix='B/s', si_prefix=False, **kwargs): if not idata or 'prev' not in idata: return None @@ -627,13 +649,28 @@ class NetworkLoadSegment(KwThreadedSegment): if None in (b1, b2) or measure_interval == 0: return None - return [{ - 'contents': format.format( - recv=humanize_bytes((b2[0] - b1[0]) / measure_interval, suffix, si_prefix), - sent=humanize_bytes((b2[1] - b1[1]) / measure_interval, suffix, si_prefix), - ), + r = [] + for i, key in zip((0, 1), ('recv', 'sent')): + format = locals()[key + '_format'] + value = (b2[i] - b1[i]) / measure_interval + max_key = key + '_max' + is_gradient = max_key in kwargs + hl_groups = ['network_load_' + key, 'network_load'] + if is_gradient: + hl_groups[:0] = (group + '_gradient' for group in hl_groups) + r.append({ + 'contents': format.format(value=humanize_bytes(value, suffix, si_prefix)), 'divider_highlight_group': 'background:divider', - }] + 'highlight_group': hl_groups, + }) + if is_gradient: + max = kwargs[max_key] + if value >= max: + r[-1]['gradient_level'] = 100 + else: + r[-1]['gradient_level'] = value * 100.0 / max + + return r network_load = with_docstring(NetworkLoadSegment(), @@ -649,8 +686,20 @@ falls back to reading string appended to each load string :param bool si_prefix: use SI prefix, e.g. MB instead of MiB -:param str format: - format string, receives ``recv`` and ``sent`` as arguments +:param str recv_format: + format string, receives ``value`` as argument +:param str sent_format: + format string, receives ``value`` as argument +:param float recv_max: + maximum number of received bytes per second. Is only used to compute + gradient level +:param float sent_max: + maximum number of sent bytes per second. Is only used to compute gradient + level + +Divider highlight group used: ``background:divider``. + +Highlight groups used: ``network_load_sent_gradient`` (gradient) or ``network_load_recv_gradient`` (gradient) or ``network_load_gradient`` (gradient), ``network_load_sent`` or ``network_load_recv`` or ``network_load``. ''') @@ -685,12 +734,23 @@ class EmailIMAPSegment(KwThreadedSegment): return None except imaplib.IMAP4.error as e: unread_count = str(e) + return unread_count + + @staticmethod + def render_one(unread_count, max_msgs=None, **kwargs): if not unread_count: return None - return [{ - 'highlight_group': 'email_alert', - 'contents': str(unread_count), - }] + elif type(unread_count) != int or not max_msgs: + return [{ + 'contents': str(unread_count), + 'highlight_group': 'email_alert', + }] + else: + return [{ + 'contents': str(unread_count), + 'highlight_group': ['email_alert_gradient', 'email_alert'], + 'gradient_level': unread_count * 100.0 / max_msgs, + }] email_imap_alert = with_docstring(EmailIMAPSegment(), @@ -706,8 +766,12 @@ email_imap_alert = with_docstring(EmailIMAPSegment(), e-mail server port :param str folder: folder to check for e-mails +:param int max_msgs: + Maximum number of messages. If there are more messages then max_msgs then it + will use gradient level equal to 100, otherwise gradient level is equal to + ``100 * msgs_num / max_msgs``. If not present gradient is not computed. -Highlight groups used: ``email_alert``. +Highlight groups used: ``email_alert_gradient`` (gradient), ``email_alert``. ''') diff --git a/powerline/segments/vim.py b/powerline/segments/vim.py index f0ae931f..1ceca510 100644 --- a/powerline/segments/vim.py +++ b/powerline/segments/vim.py @@ -247,15 +247,15 @@ def line_percent(segment_info, gradient=False): :param bool gradient: highlight the percentage with a color gradient (by default a green to red gradient) - Highlight groups used: ``line_percent_gradient`` (gradient) or ``line_percent``. + Highlight groups used: ``line_percent_gradient`` (gradient), ``line_percent``. ''' line_current = segment_info['window'].cursor[0] line_last = len(segment_info['buffer']) - percentage = int(line_current * 100 // line_last) + percentage = line_current * 100.0 / line_last if not gradient: - return str(percentage) + return str(int(round(percentage))) return [{ - 'contents': str(percentage), + 'contents': str(int(round(percentage))), 'highlight_group': ['line_percent_gradient', 'line_percent'], 'gradient_level': percentage, }] diff --git a/tests/lib/__init__.py b/tests/lib/__init__.py index fab70e9b..8d72fb4e 100644 --- a/tests/lib/__init__.py +++ b/tests/lib/__init__.py @@ -24,7 +24,7 @@ def urllib_read(query_url): elif query_url.startswith('http://freegeoip.net/json/'): return '{"city": "Meppen", "region_code": "06", "region_name": "Niedersachsen", "areacode": "", "ip": "82.145.55.16", "zipcode": "49716", "longitude": 7.3167, "country_name": "Germany", "country_code": "DE", "metrocode": "", "latitude": 52.6833}' elif query_url.startswith('http://query.yahooapis.com/v1/public/'): - return r'{"query":{"count":1,"created":"2013-03-02T13:20:22Z","lang":"en-US","results":{"weather":{"rss":{"version":"2.0","geo":"http://www.w3.org/2003/01/geo/wgs84_pos#","yweather":"http://xml.weather.yahoo.com/ns/rss/1.0","channel":{"title":"Yahoo! Weather - Russia, RU","link":"http://us.rd.yahoo.com/dailynews/rss/weather/Russia__RU/*http://weather.yahoo.com/forecast/RSXX1511_c.html","description":"Yahoo! Weather for Russia, RU","language":"en-us","lastBuildDate":"Sat, 02 Mar 2013 4:58 pm MSK","ttl":"60","location":{"city":"Russia","country":"Russia","region":""},"units":{"distance":"km","pressure":"mb","speed":"km/h","temperature":"C"},"wind":{"chill":"-11","direction":"0","speed":""},"atmosphere":{"humidity":"94","pressure":"1006.1","rising":"0","visibility":""},"astronomy":{"sunrise":"10:04 am","sunset":"7:57 pm"},"image":{"title":"Yahoo! Weather","width":"142","height":"18","link":"http://weather.yahoo.com","url":"http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif"},"item":{"title":"Conditions for Russia, RU at 4:58 pm MSK","lat":"59.45","long":"108.83","link":"http://us.rd.yahoo.com/dailynews/rss/weather/Russia__RU/*http://weather.yahoo.com/forecast/RSXX1511_c.html","pubDate":"Sat, 02 Mar 2013 4:58 pm MSK","condition":{"code":"30","date":"Sat, 02 Mar 2013 4:58 pm MSK","temp":"-11","text":"Partly Cloudy"},"description":"
\nCurrent Conditions:
\nPartly Cloudy, -11 C
\n
Forecast:
\nSat - Partly Cloudy. High: -9 Low: -19
\nSun - Partly Cloudy. High: -12 Low: -18
\n
\nFull Forecast at Yahoo! Weather

\n(provided by The Weather Channel)
","forecast":[{"code":"29","date":"2 Mar 2013","day":"Sat","high":"-9","low":"-19","text":"Partly Cloudy"},{"code":"30","date":"3 Mar 2013","day":"Sun","high":"-12","low":"-18","text":"Partly Cloudy"}],"guid":{"isPermaLink":"false","content":"RSXX1511_2013_03_03_7_00_MSK"}}}}}}}}' + return r'{"query":{"count":1,"created":"2013-03-02T13:20:22Z","lang":"en-US","results":{"weather":{"rss":{"version":"2.0","geo":"http://www.w3.org/2003/01/geo/wgs84_pos#","yweather":"http://xml.weather.yahoo.com/ns/rss/1.0","channel":{"title":"Yahoo! Weather - Russia, RU","link":"http://us.rd.yahoo.com/dailynews/rss/weather/Russia__RU/*http://weather.yahoo.com/forecast/RSXX1511_c.html","description":"Yahoo! Weather for Russia, RU","language":"en-us","lastBuildDate":"Sat, 02 Mar 2013 4:58 pm MSK","ttl":"60","location":{"city":"Russia","country":"Russia","region":""},"units":{"distance":"km","pressure":"mb","speed":"km/h","temperature":"C"},"wind":{"chill":"-9","direction":"0","speed":""},"atmosphere":{"humidity":"94","pressure":"1006.1","rising":"0","visibility":""},"astronomy":{"sunrise":"10:04 am","sunset":"7:57 pm"},"image":{"title":"Yahoo! Weather","width":"142","height":"18","link":"http://weather.yahoo.com","url":"http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif"},"item":{"title":"Conditions for Russia, RU at 4:58 pm MSK","lat":"59.45","long":"108.83","link":"http://us.rd.yahoo.com/dailynews/rss/weather/Russia__RU/*http://weather.yahoo.com/forecast/RSXX1511_c.html","pubDate":"Sat, 02 Mar 2013 4:58 pm MSK","condition":{"code":"30","date":"Sat, 02 Mar 2013 4:58 pm MSK","temp":"-9","text":"Partly Cloudy"},"description":"
\nCurrent Conditions:
\nPartly Cloudy, -9 C
\n
Forecast:
\nSat - Partly Cloudy. High: -9 Low: -19
\nSun - Partly Cloudy. High: -12 Low: -18
\n
\nFull Forecast at Yahoo! Weather

\n(provided by The Weather Channel)
","forecast":[{"code":"29","date":"2 Mar 2013","day":"Sat","high":"-9","low":"-19","text":"Partly Cloudy"},{"code":"30","date":"3 Mar 2013","day":"Sun","high":"-12","low":"-18","text":"Partly Cloudy"}],"guid":{"isPermaLink":"false","content":"RSXX1511_2013_03_03_7_00_MSK"}}}}}}}}' else: raise NotImplementedError diff --git a/tests/test.sh b/tests/test.sh index 4c6704f5..a8439ac7 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -7,7 +7,7 @@ for file in tests/test_*.py ; do FAILED=1 fi done -if ! ${PYTHON} scripts/powerline-lint ; then +if ! ${PYTHON} scripts/powerline-lint -p powerline/config_files ; then FAILED=1 fi exit $FAILED diff --git a/tests/test_segments.py b/tests/test_segments.py index 6eedcbae..b085bfdd 100644 --- a/tests/test_segments.py +++ b/tests/test_segments.py @@ -143,40 +143,48 @@ class TestCommon(TestCase): with replace_module_attr(common, 'urllib_read', urllib_read): self.assertEqual(common.weather(), [ {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': '☁ '}, - {'draw_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_cold', 'weather_temp', 'weather'], 'contents': '-11°C'} + {'draw_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 30.0} + ]) + self.assertEqual(common.weather(temp_coldest=0, temp_hottest=100), [ + {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': '☁ '}, + {'draw_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 0} + ]) + self.assertEqual(common.weather(temp_coldest=-100, temp_hottest=-50), [ + {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': '☁ '}, + {'draw_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 100} ]) self.assertEqual(common.weather(icons={'cloudy': 'o'}), [ {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'o '}, - {'draw_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_cold', 'weather_temp', 'weather'], 'contents': '-11°C'} + {'draw_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 30.0} ]) self.assertEqual(common.weather(icons={'partly_cloudy_day': 'x'}), [ {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': 'x '}, - {'draw_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_cold', 'weather_temp', 'weather'], 'contents': '-11°C'} + {'draw_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9°C', 'gradient_level': 30.0} ]) self.assertEqual(common.weather(unit='F'), [ {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': '☁ '}, - {'draw_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_cold', 'weather_temp', 'weather'], 'contents': '12°F'} + {'draw_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '16°F', 'gradient_level': 30.0} ]) self.assertEqual(common.weather(unit='K'), [ {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': '☁ '}, - {'draw_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_cold', 'weather_temp', 'weather'], 'contents': '262K'} + {'draw_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '264K', 'gradient_level': 30.0} ]) - self.assertEqual(common.weather(temperature_format='{temp:.1e}C'), [ + self.assertEqual(common.weather(temp_format='{temp:.1e}C'), [ {'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_condition_partly_cloudy_day', 'weather_condition_cloudy', 'weather_conditions', 'weather'], 'contents': '☁ '}, - {'draw_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_cold', 'weather_temp', 'weather'], 'contents': '-1.1e+01C'} + {'draw_divider': False, 'divider_highlight_group': 'background:divider', 'highlight_group': ['weather_temp_gradient', 'weather_temp', 'weather'], 'contents': '-9.0e+00C', 'gradient_level': 30.0} ]) def test_system_load(self): with replace_module_module(common, 'os', getloadavg=lambda: (7.5, 3.5, 1.5)): with replace_module_attr(common, 'cpu_count', lambda: 2): self.assertEqual(common.system_load(), - [{'contents': '7.5 ', 'highlight_group': ['system_load_ugly', 'system_load'], 'draw_divider': True, 'divider_highlight_group': 'background:divider'}, - {'contents': '3.5 ', 'highlight_group': ['system_load_bad', 'system_load'], 'draw_divider': False, 'divider_highlight_group': 'background:divider'}, - {'contents': '1.5', 'highlight_group': ['system_load_good', 'system_load'], 'draw_divider': False, 'divider_highlight_group': 'background:divider'}]) + [{'contents': '7.5 ', 'highlight_group': ['system_load_gradient', 'system_load'], 'draw_divider': True, 'divider_highlight_group': 'background:divider', 'gradient_level': 100}, + {'contents': '3.5 ', 'highlight_group': ['system_load_gradient', 'system_load'], 'draw_divider': False, 'divider_highlight_group': 'background:divider', 'gradient_level': 75.0}, + {'contents': '1.5', 'highlight_group': ['system_load_gradient', 'system_load'], 'draw_divider': False, 'divider_highlight_group': 'background:divider', 'gradient_level': 0}]) self.assertEqual(common.system_load(format='{avg:.0f}', threshold_good=0, threshold_bad=1), - [{'contents': '8 ', 'highlight_group': ['system_load_ugly', 'system_load'], 'draw_divider': True, 'divider_highlight_group': 'background:divider'}, - {'contents': '4 ', 'highlight_group': ['system_load_ugly', 'system_load'], 'draw_divider': False, 'divider_highlight_group': 'background:divider'}, - {'contents': '2', 'highlight_group': ['system_load_bad', 'system_load'], 'draw_divider': False, 'divider_highlight_group': 'background:divider'}]) + [{'contents': '8 ', 'highlight_group': ['system_load_gradient', 'system_load'], 'draw_divider': True, 'divider_highlight_group': 'background:divider', 'gradient_level': 100}, + {'contents': '4 ', 'highlight_group': ['system_load_gradient', 'system_load'], 'draw_divider': False, 'divider_highlight_group': 'background:divider', 'gradient_level': 100}, + {'contents': '2', 'highlight_group': ['system_load_gradient', 'system_load'], 'draw_divider': False, 'divider_highlight_group': 'background:divider', 'gradient_level': 75.0}]) def test_cpu_load_percent(self): with replace_module_module(common, 'psutil', cpu_percent=lambda **kwargs: 52.3): @@ -201,16 +209,31 @@ class TestCommon(TestCase): common.network_load.sleep(0) common.network_load.sleep(0) self.assertEqual(common.network_load(), [ - {'divider_highlight_group': 'background:divider', 'contents': '⬇ 1 KiB/s ⬆ 2 KiB/s'} + {'divider_highlight_group': 'background:divider', 'contents': '⬇ 1 KiB/s', 'highlight_group': ['network_load_recv', 'network_load']}, + {'divider_highlight_group': 'background:divider', 'contents': '⬆ 2 KiB/s', 'highlight_group': ['network_load_sent', 'network_load']}, ]) - self.assertEqual(common.network_load(format='r {recv} s {sent}'), [ - {'divider_highlight_group': 'background:divider', 'contents': 'r 1 KiB/s s 2 KiB/s'} + self.assertEqual(common.network_load(recv_format='r {value}', sent_format='s {value}'), [ + {'divider_highlight_group': 'background:divider', 'contents': 'r 1 KiB/s', 'highlight_group': ['network_load_recv', 'network_load']}, + {'divider_highlight_group': 'background:divider', 'contents': 's 2 KiB/s', 'highlight_group': ['network_load_sent', 'network_load']}, ]) - self.assertEqual(common.network_load(format='r {recv} s {sent}', suffix='bps'), [ - {'divider_highlight_group': 'background:divider', 'contents': 'r 1 Kibps s 2 Kibps'} + self.assertEqual(common.network_load(recv_format='r {value}', sent_format='s {value}', suffix='bps'), [ + {'divider_highlight_group': 'background:divider', 'contents': 'r 1 Kibps', 'highlight_group': ['network_load_recv', 'network_load']}, + {'divider_highlight_group': 'background:divider', 'contents': 's 2 Kibps', 'highlight_group': ['network_load_sent', 'network_load']}, ]) - self.assertEqual(common.network_load(format='r {recv} s {sent}', si_prefix=True), [ - {'divider_highlight_group': 'background:divider', 'contents': 'r 1 kB/s s 2 kB/s'} + self.assertEqual(common.network_load(recv_format='r {value}', sent_format='s {value}', si_prefix=True), [ + {'divider_highlight_group': 'background:divider', 'contents': 'r 1 kB/s', 'highlight_group': ['network_load_recv', 'network_load']}, + {'divider_highlight_group': 'background:divider', 'contents': 's 2 kB/s', 'highlight_group': ['network_load_sent', 'network_load']}, + ]) + self.assertEqual(common.network_load(recv_format='r {value}', sent_format='s {value}', recv_max=0), [ + {'divider_highlight_group': 'background:divider', 'contents': 'r 1 KiB/s', 'highlight_group': ['network_load_recv_gradient', 'network_load_gradient', 'network_load_recv', 'network_load'], 'gradient_level': 100}, + {'divider_highlight_group': 'background:divider', 'contents': 's 2 KiB/s', 'highlight_group': ['network_load_sent', 'network_load']}, + ]) + class ApproxEqual(object): + def __eq__(self, i): + return abs(i - 50.0) < 1 + self.assertEqual(common.network_load(recv_format='r {value}', sent_format='s {value}', sent_max=4800), [ + {'divider_highlight_group': 'background:divider', 'contents': 'r 1 KiB/s', 'highlight_group': ['network_load_recv', 'network_load']}, + {'divider_highlight_group': 'background:divider', 'contents': 's 2 KiB/s', 'highlight_group': ['network_load_sent_gradient', 'network_load_gradient', 'network_load_sent', 'network_load'], 'gradient_level': ApproxEqual()}, ]) def test_virtualenv(self): @@ -306,11 +329,11 @@ class TestVim(TestCase): segment_info = vim_module._get_segment_info() segment_info['buffer'][0:-1] = [str(i) for i in range(100)] try: - self.assertEqual(vim.line_percent(segment_info=segment_info), '0') + self.assertEqual(vim.line_percent(segment_info=segment_info), '1') vim_module._set_cursor(50, 0) - self.assertEqual(vim.line_percent(segment_info=segment_info), '49') + self.assertEqual(vim.line_percent(segment_info=segment_info), '50') self.assertEqual(vim.line_percent(segment_info=segment_info, gradient=True), - [{'contents': '49', 'highlight_group': ['line_percent_gradient', 'line_percent'], 'gradient_level': 49}]) + [{'contents': '50', 'highlight_group': ['line_percent_gradient', 'line_percent'], 'gradient_level': 50 * 100.0 / 101}]) finally: vim_module._bw(segment_info['bufnr']) diff --git a/tools/colors_find.py b/tools/colors_find.py old mode 100644 new mode 100755 index d93bf455..6ba1489d --- a/tools/colors_find.py +++ b/tools/colors_find.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python import sys import os diff --git a/tools/generate_gradients.py b/tools/generate_gradients.py old mode 100644 new mode 100755 index 46f418ca..1fd4a137 --- a/tools/generate_gradients.py +++ b/tools/generate_gradients.py @@ -1,12 +1,18 @@ +#!/usr/bin/env python import sys import json from powerline.colorscheme import cterm_to_hex from itertools import groupby +try: + from __builtin__ import unicode +except ImportError: + unicode = str -if len(sys.argv) == 1: + +if len(sys.argv) == 1 or sys.argv[1] == '--help': sys.stderr.write(''' - Usage: generate_gradients.py colors itemnum[ "show"] + Usage: generate_gradients.py colors itemnum[ "show" [ min max num]] colors: JSON list with either cterm ([200, 42, 6]) or RGB (["abcdef", "feffef"]) colors. @@ -15,7 +21,16 @@ if len(sys.argv) == 1: "show": static string, determines whether gradient sample should be printed to stdout as well. + + min, max: floating point values. + num: integer + + all of the above are used to generate sample gradient for given + range (just like the above gradients shown with "show", but with + different scale (controlled by min and max) and, possibly, + different length (controlled by num)). ''') + sys.exit(1) def linear_gradient(start_value, stop_value, start_offset, stop_offset, offset): @@ -69,13 +84,13 @@ def print_color(color): if type(color) is int: colstr = '5;' + str(color) else: - colstr = '2;' + ';'.join((str(i) for i in color)) + colstr = '2;' + ';'.join((str(int(round(i))) for i in color)) sys.stdout.write('\033[48;' + colstr + 'm ') -def print_colors(colors): - for i in range(101): - color = colors[int(round(i * (len(colors) - 1) / 100))] +def print_colors(colors, num=100): + for i in range(num + 1): + color = colors[int(round(i * (len(colors) - 1) / num))] print_color(color) sys.stdout.write('\033[0m\n') @@ -90,9 +105,9 @@ gradient = [gr_func(y) for y in range(0, m - 1)] r = [get_rgb(*color) for color in gradient] r2 = [find_color(color, cterm_to_hex)[0] for color in gradient] r3 = [i[0] for i in groupby(r2)] -print json.dumps(r) -print json.dumps(r2) -print json.dumps(r3) +print(json.dumps(r)) +print(json.dumps(r2)) +print(json.dumps(r3)) if len(sys.argv) > 3 and sys.argv[3] == 'show': print_colors(gradient) print_colors(r2) @@ -103,3 +118,14 @@ if len(sys.argv) > 3 and sys.argv[3] == 'show': nums = (''.join((str(i) for i in range(10)))) sys.stdout.write(''.join(((('\033[1m' if j % 2 else '\033[0m') + nums) for j in range(10)))) sys.stdout.write('\033[0m0\n') + if len(sys.argv) > 6: + vmin = float(sys.argv[4]) + vmax = float(sys.argv[5]) + num = int(sys.argv[6]) + print_colors(gradient, num) + s = '' + while len(s) < num: + curpc = len(s) + 1 if s else 0 + curval = vmin + curpc * (vmax - vmin) / 100.0 + s += str(curval) + ' ' + print(s)