diff options
Diffstat (limited to 'ranger/gui/widgets/browsercolumn.py')
-rw-r--r-- | ranger/gui/widgets/browsercolumn.py | 202 |
1 files changed, 123 insertions, 79 deletions
diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index 34806b7f..afe8e13b 100644 --- a/ranger/gui/widgets/browsercolumn.py +++ b/ranger/gui/widgets/browsercolumn.py @@ -1,4 +1,4 @@ -# -*- encoding: utf8 -*- +# -*- coding: utf-8 -*- # Copyright (C) 2009-2013 Roman Zimbelmann <hut@lavabit.com> # This software is distributed under the terms of the GNU GPL version 3. @@ -13,9 +13,12 @@ from .pager import Pager from ranger.fsobject import BAD_INFO from ranger.ext.widestring import WideString +from ranger.gui.color import * + class BrowserColumn(Pager): main_column = False display_infostring = False + display_vcsstate = True scroll_begin = 0 target = None last_redraw_time = -1 @@ -92,7 +95,7 @@ class BrowserColumn(Pager): def execute_curses_batch(self, line, commands): """Executes a list of "commands" which can be easily cached. - "commands" is a list of lists. Each element contains + "commands" is a list of lists. Each element contains a text and an attribute. First, the attribute will be set with attrset, then the text is printed. @@ -137,7 +140,7 @@ class BrowserColumn(Pager): self.need_redraw = True self.old_dir = self.target - if self.target: # don't garbage collect this directory please + if self.target: # don't garbage collect this directory please self.target.use() if self.target and self.target.is_directory \ @@ -225,7 +228,6 @@ class BrowserColumn(Pager): self._set_scroll_begin() copied = [f.path for f in self.fm.copy_buffer] - ellipsis = self.ellipsis[self.settings.unicode_ellipsis] selected_i = self.target.pointer for line in range(self.hei): @@ -246,100 +248,142 @@ class BrowserColumn(Pager): key = (self.wid, selected_i == i, drawn.marked, self.main_column, drawn.path in copied, tagged_marker, drawn.infostring, - self.fm.do_cut) + drawn.vcsfilestatus, drawn.vcsremotestatus, self.fm.do_cut) if key in drawn.display_data: self.execute_curses_batch(line, drawn.display_data[key]) self.color_reset() continue + text = drawn.basename + if drawn.marked and (self.main_column or self.settings.display_tags_in_all_columns): + text = " " + text + + # Computing predisplay data. predisplay contains a list of lists [string, colorlst] + # where string is a piece of string to display, and colorlst a list of contexts + # that we later pass to the colorscheme, to compute the curses attribute. + predisplay_left = [] + predisplay_right = [] + + predisplay_left = predisplay_left + self._draw_tagged_display(tagged, tagged_marker) + predisplay_right = predisplay_right + self._draw_vcsstring_display(drawn) + space = self.wid - self._total_len(predisplay_left) - self._total_len(predisplay_right) + + # If not enough space + if space <= 2: + predisplay_right = [] + predisplay_left = [] + + predisplay_left = predisplay_left + self._draw_text_display(text, space) + space = self.wid - self._total_len(predisplay_left) - self._total_len(predisplay_right) + + predisplay_right = self._draw_infostring_display(drawn, space) + predisplay_right + space = self.wid - self._total_len(predisplay_left) - self._total_len(predisplay_right) + + if space > 0: + predisplay_left.append([' ' * space, []]) + elif space < 0: + raise Exception("Error: there is not enough space to write the text. I have computed spaces wrong.") + + # Computing display data. Now we compute the display_data list ready to display in + # curses. It is a list of lists [string, attr] + + this_color = base_color + list(drawn.mimetype_tuple) + self._draw_directory_color(i, drawn, copied) display_data = [] drawn.display_data[key] = display_data - if self.display_infostring and drawn.infostring \ - and self.settings.display_size_in_main_column: - infostring = str(drawn.infostring) + " " - else: - infostring = "" + predisplay = predisplay_left + predisplay_right + for txt, color in predisplay: + attr = self.settings.colorscheme.get_attr(*(this_color + color)) + display_data.append([txt, attr]) - this_color = base_color + list(drawn.mimetype_tuple) - text = drawn.basename + self.execute_curses_batch(line, display_data) + self.color_reset() - space = self.wid - len(infostring) - if self.main_column: - space -= 2 - elif self.settings.display_tags_in_all_columns: - space -= 1 + def _total_len(self, predisplay): + return sum([len(WideString(s)) for s, L in predisplay]) - if i == selected_i: - this_color.append('selected') + def _draw_text_display(self, text, space): + wtext = WideString(text) + if len(wtext) > space: + wtext = wtext[:max(0, space - 1)] + self.ellipsis[self.settings.unicode_ellipsis] - if drawn.marked: - this_color.append('marked') - if self.main_column or self.settings.display_tags_in_all_columns: - text = " " + text + return [[str(wtext), []]] + def _draw_tagged_display(self, tagged, tagged_marker): + tagged_display = [] + if (self.main_column or self.settings.display_tags_in_all_columns) and self.wid > 2: if tagged: - this_color.append('tagged') - - if drawn.is_directory: - this_color.append('directory') + tagged_display.append([tagged_marker, ['tag_marker']]) else: - this_color.append('file') - - if drawn.stat: - mode = drawn.stat.st_mode - if mode & stat.S_IXUSR: - this_color.append('executable') - if stat.S_ISFIFO(mode): - this_color.append('fifo') - if stat.S_ISSOCK(mode): - this_color.append('socket') - if drawn.is_device: - this_color.append('device') - - if drawn.path in copied: - this_color.append('cut' if self.fm.do_cut else 'copied') - - if drawn.is_link: - this_color.append('link') - this_color.append(drawn.exists and 'good' or 'bad') - - attr = self.settings.colorscheme.get_attr(*this_color) - - if (self.main_column or self.settings.display_tags_in_all_columns) \ - and tagged and self.wid > 2: - this_color.append('tag_marker') - tag_attr = self.settings.colorscheme.get_attr(*this_color) - display_data.append([tagged_marker, tag_attr]) + tagged_display.append([" ", ['tag_marker']]) + return tagged_display + + def _draw_infostring_display(self, drawn, space): + infostring_display = [] + if self.display_infostring and drawn.infostring \ + and self.settings.display_size_in_main_column: + infostring = str(drawn.infostring) + " " + if len(infostring) <= space: + infostring_display.append([infostring, ['infostring']]) + return infostring_display + + def _draw_vcsstring_display(self, drawn): + vcsstring_display = [] + if self.settings.vcs_aware and (drawn.vcsfilestatus or drawn.vcsremotestatus): + if drawn.vcsfilestatus: + vcsstr, vcscol = self.vcsfilestatus_symb[drawn.vcsfilestatus] else: - text = " " + text - space += 1 - - wtext = WideString(text) - if len(wtext) > space: - wtext = wtext[:max(0, space - 1)] + ellipsis - text = str(wtext) - - display_data.append([text, attr]) - - padding = self.wid - len(wtext) - if tagged and (self.main_column or \ - self.settings.display_tags_in_all_columns): - padding -= 1 - if infostring: - if len(wtext) + 1 + len(infostring) > self.wid: - pass - else: - padding -= len(infostring) - padding = max(0, padding) - infostring = (" " * padding) + infostring - display_data.append([infostring, attr]) + vcsstr = " " + vcscol = [] + vcsstring_display.append([vcsstr, ['vcsfile'] + vcscol]) + + if drawn.vcsremotestatus: + vcsstr, vcscol = self.vcsremotestatus_symb[drawn.vcsremotestatus] else: - display_data.append([" " * max(0, padding), attr]) - self.execute_curses_batch(line, display_data) - self.color_reset() + vcsstr = " " + vcscol = [] + vcsstring_display.append([vcsstr, ['vcsremote'] + vcscol]) + elif self.target.has_vcschild: + vcsstring_display.append([" ", []]) + return vcsstring_display + + def _draw_directory_color(self, i, drawn, copied): + this_color = [] + if i == self.target.pointer: + this_color.append('selected') + + if drawn.marked: + this_color.append('marked') + + if self.fm.tags and drawn.realpath in self.fm.tags: + this_color.append('tagged') + + if drawn.is_directory: + this_color.append('directory') + else: + this_color.append('file') + + if drawn.stat: + mode = drawn.stat.st_mode + if mode & stat.S_IXUSR: + this_color.append('executable') + if stat.S_ISFIFO(mode): + this_color.append('fifo') + if stat.S_ISSOCK(mode): + this_color.append('socket') + if drawn.is_device: + this_color.append('device') + + if drawn.path in copied: + this_color.append('cut' if self.fm.do_cut else 'copied') + + if drawn.is_link: + this_color.append('link') + this_color.append(drawn.exists and 'good' or 'bad') + + return this_color def _get_scroll_begin(self): """Determines scroll_begin (the position of the first displayed file)""" |