diff options
author | Wojciech Siewierski <wojciech.siewierski@onet.pl> | 2015-02-22 01:33:57 +0100 |
---|---|---|
committer | Wojciech Siewierski <wojciech.siewierski@onet.pl> | 2015-02-22 01:42:15 +0100 |
commit | 19ee5a7427059c8f570cc050acca1e1e6305bd8c (patch) | |
tree | c72062b9b5f82e2d6a09cbcb47510505fe6fc18b | |
parent | a3cd6b0cf3e6b05e7058544b8503872ff7ac2881 (diff) | |
download | ranger-19ee5a7427059c8f570cc050acca1e1e6305bd8c.tar.gz |
linemode refactoring; custom linemodes possible
-rw-r--r-- | ranger/config/commands.py | 6 | ||||
-rw-r--r-- | ranger/container/fsobject.py | 7 | ||||
-rw-r--r-- | ranger/core/actions.py | 4 | ||||
-rw-r--r-- | ranger/core/linemode.py | 91 | ||||
-rw-r--r-- | ranger/gui/widgets/browsercolumn.py | 42 |
5 files changed, 114 insertions, 36 deletions
diff --git a/ranger/config/commands.py b/ranger/config/commands.py index 55f6442b..6e2ba26d 100644 --- a/ranger/config/commands.py +++ b/ranger/config/commands.py @@ -390,7 +390,7 @@ class setintag(setlocal): class default_linemode(Command): def execute(self): import re - from ranger.container.fsobject import POSSIBLE_LINEMODES + from ranger.core.linemode import REGISTERED_LINEMODES if len(self.args) < 2: self.fm.notify("Usage: default_linemode [path=<regexp> | tag=<tag(s)>] <linemode>", bad=True) @@ -410,9 +410,9 @@ class default_linemode(Command): # Extract and validate the line mode from the command line linemode = self.rest(1) - if linemode not in POSSIBLE_LINEMODES: + if linemode not in REGISTERED_LINEMODES: self.fm.notify("Invalid linemode: %s; should be %s" % - (linemode, "/".join(POSSIBLE_LINEMODES)), bad=True) + (linemode, "/".join(REGISTERED_LINEMODES)), bad=True) # Add the prepared entry to the fm.default_linemodes entry = [method, argument, linemode] diff --git a/ranger/container/fsobject.py b/ranger/container/fsobject.py index 08161c3c..32b1dc8b 100644 --- a/ranger/container/fsobject.py +++ b/ranger/container/fsobject.py @@ -12,14 +12,13 @@ DOCUMENT_BASENAMES = ('bugs', 'bugs', 'changelog', 'copying', 'credits', BAD_INFO = '?' -POSSIBLE_LINEMODES = ("filename", "metatitle", "permissions") -DEFAULT_LINEMODE = "filename" - import re from grp import getgrgid from os import lstat, stat, getcwd from os.path import abspath, basename, dirname, realpath, splitext, extsep, relpath from pwd import getpwuid +from ranger.core.linemode import REGISTERED_LINEMODES +from ranger.core.linemode import DEFAULT_LINEMODE from ranger.core.shared import FileManagerAware, SettingsAware from ranger.ext.shell_escape import shell_escape from ranger.ext.spawn import spawn @@ -112,7 +111,7 @@ class FileSystemObject(FileManagerAware, SettingsAware): # Set the line mode from fm.default_linemodes for method, argument, linemode in self.fm.default_linemodes: - if linemode in POSSIBLE_LINEMODES: + if linemode in REGISTERED_LINEMODES: if method == "always": self._linemode = linemode break diff --git a/ranger/core/actions.py b/ranger/core/actions.py index 1167dab5..aa10e34f 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -27,7 +27,7 @@ from ranger.core.tab import Tab from ranger.container.file import File from ranger.core.loader import CommandLoader, CopyLoader from ranger.container.settings import ALLOWED_SETTINGS -from ranger.container.fsobject import POSSIBLE_LINEMODES, DEFAULT_LINEMODE +from ranger.core.linemode import REGISTERED_LINEMODES, DEFAULT_LINEMODE MACRO_FAIL = "<\x01\x01MACRO_HAS_NO_VALUE\x01\01>" @@ -167,7 +167,7 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): if mode == "normal": mode = DEFAULT_LINEMODE - if mode not in POSSIBLE_LINEMODES: + if mode not in REGISTERED_LINEMODES: self.notify("Unhandled linemode: `%s'" % mode, bad=True) return diff --git a/ranger/core/linemode.py b/ranger/core/linemode.py new file mode 100644 index 00000000..8b5084b0 --- /dev/null +++ b/ranger/core/linemode.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- + +from abc import * + +DEFAULT_LINEMODE = "filename" +REGISTERED_LINEMODES = dict() + +def register_linemode(*linemodes): + """Register a linemode in a dictionary of available linemodes.""" + for linemode in linemodes: + REGISTERED_LINEMODES[linemode.name] = linemode() + +def lookup_linemode(name): + """Lookup the linemode instance by its name""" + return REGISTERED_LINEMODES[name] + + +class LinemodeBase(object): + """Supplies the file line contents for BrowserColumn. + + Attributes: + name (required!) - Name by which the linemode is referred to by the user + + uses_metadata - True if metadata should to be loaded for this linemode + + required_metadata - + If any of these metadata fields are absent, fall back to + the default linemode + """ + __metaclass__ = ABCMeta + + uses_metadata = False + required_metadata = [] + + name = abstractproperty() + + @abstractmethod + def filetitle(self, file, metadata): + """The left-aligned part of the line.""" + raise NotImplementedError + + @abstractmethod + def infostring(self, file, metadata): + """The right-aligned part of the line.""" + raise NotImplementedError + + +class DefaultLinemode(LinemodeBase): + name = "filename" + + def filetitle(self, file, metadata): + return file.drawn_basename + + def infostring(self, file, metadata): + # Should never be called for this linemode, implemented in BrowserColumn + raise NotImplementedError + + +class TitleLinemode(LinemodeBase): + name = "metatitle" + uses_metadata = True + required_metadata = ["title"] + + def filetitle(self, file, metadata): + name = metadata.title or file.basename + if metadata.year: + return "%s - %s" % (metadata.year, name) + else: + return name + + def infostring(self, file, metadata): + if metadata.authors: + authorstring = metadata.authors + if ',' in authorstring: + authorstring = authorstring[0:authorstring.find(",")] + return authorstring + return "" + + +class PermissionsLinemode(LinemodeBase): + name = "permissions" + + def filetitle(self, file, metadata): + return "%s %s %s %s" % (file.get_permission_string(), + file.user, file.group, file.drawn_basename) + + def infostring(self, file, metadata): + return "" + + +register_linemode(DefaultLinemode, PermissionsLinemode, TitleLinemode) diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index 564e9a5f..427a323d 100644 --- a/ranger/gui/widgets/browsercolumn.py +++ b/ranger/gui/widgets/browsercolumn.py @@ -12,6 +12,8 @@ from . import Widget from .pager import Pager from ranger.ext.widestring import WideString +from ranger.core import linemode + from ranger.gui.color import * class BrowserColumn(Pager): @@ -250,38 +252,25 @@ class BrowserColumn(Pager): # Extract linemode-related information from the drawn object metadata = None - use_linemode = drawn._linemode - if use_linemode == "metatitle": + current_linemode = linemode.lookup_linemode(drawn._linemode) + if current_linemode.uses_metadata: metadata = self.fm.metadata.get_metadata(drawn.path) - if not metadata.title: - use_linemode = "filename" + if not all(getattr(metadata, tag) + for tag in current_linemode.required_metadata): + current_linemode = linemode.lookup_linemode(linemode.DEFAULT_LINEMODE) metakey = hash(repr(sorted(metadata.items()))) if metadata else 0 key = (self.wid, selected_i == i, drawn.marked, self.main_column, drawn.path in copied, tagged_marker, drawn.infostring, drawn.vcsfilestatus, drawn.vcsremotestatus, self.fm.do_cut, - use_linemode, metakey) + current_linemode.name, metakey) if key in drawn.display_data: self.execute_curses_batch(line, drawn.display_data[key]) self.color_reset() continue - - # Deal with the line mode - text = "" - if use_linemode == "metatitle": - assert metadata.title, "Ensure that metadata.title is set!" - if metadata.year: - text = "%s - %s" % (metadata.year, metadata.title) - else: - text = metadata.title - if use_linemode == "filename": - text = drawn.drawn_basename - elif use_linemode == "permissions": - text = "%s %s %s %s" % (drawn.get_permission_string(), - drawn.user, drawn.group, drawn.drawn_basename) - + text = current_linemode.filetitle(drawn, metadata) if drawn.marked and (self.main_column or \ self.settings.display_tags_in_all_columns): @@ -312,14 +301,13 @@ class BrowserColumn(Pager): # info string infostring = [] infostringlen = 0 - if use_linemode == "filename": + if current_linemode.name == "filename": infostring = self._draw_infostring_display(drawn, space) - elif use_linemode == "metatitle": - if metadata.authors: - authorstring = metadata.authors - if ',' in authorstring: - authorstring = authorstring[0:authorstring.find(",")] - infostring.append([" " + authorstring + " ", ["infostring"]]) + else: + infostringdata = current_linemode.infostring(drawn, metadata) + if infostringdata: + infostring.append([" " + infostringdata + " ", + ["infostring"]]) if infostring: infostringlen = self._total_len(infostring) if space - infostringlen > 2: |