From 3e0aa7a0ae37768dbe19f07ae086d3ded0064d19 Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 3 Dec 2014 16:45:37 +0100 Subject: allow setting a "linemode" for each file/directory --- ranger/container/directory.py | 4 ++++ ranger/container/file.py | 2 ++ ranger/container/fsobject.py | 6 ++++++ ranger/core/actions.py | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+) diff --git a/ranger/container/directory.py b/ranger/container/directory.py index c6987a76..c331053a 100644 --- a/ranger/container/directory.py +++ b/ranger/container/directory.py @@ -567,6 +567,10 @@ class Directory(FileSystemObject, Accumulator, Loadable): """Is the directory empty?""" return self.files is None or len(self.files) == 0 + def _set_linemode_of_children(self, mode): + for f in self.files: + f._set_linemode(mode) + def __nonzero__(self): """Always True""" return True diff --git a/ranger/container/file.py b/ranger/container/file.py index ab677125..7297dc30 100644 --- a/ranger/container/file.py +++ b/ranger/container/file.py @@ -43,6 +43,8 @@ class File(FileSystemObject): preview_known = False preview_loading = False + _linemode = "filename" + @property def firstbytes(self): try: diff --git a/ranger/container/fsobject.py b/ranger/container/fsobject.py index 6f206d0d..1bdbcde7 100644 --- a/ranger/container/fsobject.py +++ b/ranger/container/fsobject.py @@ -80,6 +80,9 @@ class FileSystemObject(FileManagerAware, SettingsAware): basename_is_rel = False + # the line mode may be "filename", "details" or "title" + _linemode = "filename" + def __init__(self, path, preload=None, path_is_abs=False, basename_is_rel=False): if not path_is_abs: path = abspath(path) @@ -373,3 +376,6 @@ class FileSystemObject(FileManagerAware, SettingsAware): self.vcs_outdated = True return True return False + + def _set_linemode(self, mode): + self._linemode = mode diff --git a/ranger/core/actions.py b/ranger/core/actions.py index ba6b3658..f3f1f04c 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -151,6 +151,42 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): """Redraw the window""" self.ui.redraw_window() + def linemode(self, mode, directory=None, depth=0): + """ + Change what is displayed as a filename. + + "mode" may be: "filename", "details", "title" + "directory" specifies the directory. None means the current directory + "depth" specifies the recursion depth + """ + + assert mode in ("filename", "details", "title") + + if directory is None: + directory = self.fm.thisdir + + directories = set([directory]) + bucket = set() + + current_depth = 0 + + while True: + if current_depth >= depth: + for direct in directories: + direct._set_linemode_of_children(mode) + break + + else: + for direct in directories: + direct._set_linemode_of_children(mode) + for file_ in direct.files: + if file_.is_directory: + bucket.add(file_) + + directories, bucket = bucket, directories + bucket.clear() + current_depth += 1 + def open_console(self, string='', prompt=None, position=None): """Open the console""" self.change_mode('normal') -- cgit 1.4.1-2-gfad0 From 58c2185f5fc5a5af1a7eccb727db61f2050cc66f Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 3 Dec 2014 17:06:39 +0100 Subject: added fsobject.user and fsobject.group lazy_properties --- ranger/container/fsobject.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/ranger/container/fsobject.py b/ranger/container/fsobject.py index 1bdbcde7..59aea478 100644 --- a/ranger/container/fsobject.py +++ b/ranger/container/fsobject.py @@ -13,8 +13,10 @@ DOCUMENT_BASENAMES = ('bugs', 'bugs', 'changelog', 'copying', 'credits', BAD_INFO = '?' 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.shared import FileManagerAware, SettingsAware from ranger.ext.shell_escape import shell_escape from ranger.ext.spawn import spawn @@ -132,6 +134,19 @@ class FileSystemObject(FileManagerAware, SettingsAware): def safe_basename(self): return self.basename.translate(_safe_string_table) + @lazy_property + def user(self): + try: + return getpwuid(self.stat.st_uid)[0] + except: + return str(self.stat.st_uid) + + @lazy_property + def group(self): + try: + return getgrgid(self.stat.st_gid)[0] + except: + return str(self.stat.st_gid) for attr in ('video', 'audio', 'image', 'media', 'document', 'container'): exec("%s = lazy_property(" -- cgit 1.4.1-2-gfad0 From 60c5722e81c75da152efcaeef84e54fd83b8c78d Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 3 Dec 2014 17:09:07 +0100 Subject: implement "permissions" linemode --- ranger/container/fsobject.py | 2 +- ranger/core/actions.py | 4 ++-- ranger/gui/widgets/browsercolumn.py | 21 ++++++++++++++------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/ranger/container/fsobject.py b/ranger/container/fsobject.py index 59aea478..fb3356a4 100644 --- a/ranger/container/fsobject.py +++ b/ranger/container/fsobject.py @@ -82,7 +82,7 @@ class FileSystemObject(FileManagerAware, SettingsAware): basename_is_rel = False - # the line mode may be "filename", "details" or "title" + # the line mode may be "filename", "permissions" or "title" _linemode = "filename" def __init__(self, path, preload=None, path_is_abs=False, basename_is_rel=False): diff --git a/ranger/core/actions.py b/ranger/core/actions.py index f3f1f04c..4d9d4121 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -155,12 +155,12 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): """ Change what is displayed as a filename. - "mode" may be: "filename", "details", "title" + "mode" may be: "filename", "permissions", "title" "directory" specifies the directory. None means the current directory "depth" specifies the recursion depth """ - assert mode in ("filename", "details", "title") + assert mode in ("filename", "permissions", "title") if directory is None: directory = self.fm.thisdir diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index 0edb9c8d..9e177a52 100644 --- a/ranger/gui/widgets/browsercolumn.py +++ b/ranger/gui/widgets/browsercolumn.py @@ -250,14 +250,20 @@ class BrowserColumn(Pager): 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) + drawn.vcsfilestatus, drawn.vcsremotestatus, self.fm.do_cut, + drawn._linemode) if key in drawn.display_data: self.execute_curses_batch(line, drawn.display_data[key]) self.color_reset() continue - text = drawn.basename + if drawn._linemode == "filename": + text = drawn.basename + elif drawn._linemode == "permissions": + text = "%s %s %s %s" % (drawn.get_permission_string(), + drawn.user, drawn.group, drawn.basename) + if drawn.marked and (self.main_column or \ self.settings.display_tags_in_all_columns): text = " " + text @@ -285,11 +291,12 @@ class BrowserColumn(Pager): space -= vcsstringlen # info string - infostring = self._draw_infostring_display(drawn, space) - infostringlen = self._total_len(infostring) - if space - infostringlen > 2: - predisplay_right = infostring + predisplay_right - space -= infostringlen + if drawn._linemode == "filename": + infostring = self._draw_infostring_display(drawn, space) + infostringlen = self._total_len(infostring) + if space - infostringlen > 2: + predisplay_right = infostring + predisplay_right + space -= infostringlen textstring = self._draw_text_display(text, space) textstringlen = self._total_len(textstring) -- cgit 1.4.1-2-gfad0 From 6196b9b089808ed085492860cc89e5ad6013897f Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 3 Dec 2014 18:12:40 +0100 Subject: implement a paper manager --- ranger/core/fm.py | 2 ++ ranger/ext/papermanager.py | 55 +++++++++++++++++++++++++++++++++++++ ranger/gui/widgets/browsercolumn.py | 19 +++++++++++-- 3 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 ranger/ext/papermanager.py diff --git a/ranger/core/fm.py b/ranger/core/fm.py index d567bf24..885068e5 100644 --- a/ranger/core/fm.py +++ b/ranger/core/fm.py @@ -20,6 +20,7 @@ from ranger.gui.ui import UI from ranger.container.bookmarks import Bookmarks from ranger.core.runner import Runner from ranger.ext.img_display import ImageDisplayer +from ranger.ext.papermanager import PaperManager from ranger.ext.rifle import Rifle from ranger.container.directory import Directory from ranger.ext.signals import SignalDispatcher @@ -59,6 +60,7 @@ class FM(Actions, SignalDispatcher): self.loader = Loader() self.copy_buffer = set() self.do_cut = False + self.papermanager = PaperManager() try: self.username = pwd.getpwuid(os.geteuid()).pw_name diff --git a/ranger/ext/papermanager.py b/ranger/ext/papermanager.py new file mode 100644 index 00000000..a013585f --- /dev/null +++ b/ranger/ext/papermanager.py @@ -0,0 +1,55 @@ +# Copyright (C) 2014 Roman Zimbelmann +# This software is distributed under the terms of the GNU GPL version 3. + +import csv +from os.path import join, dirname, exists, basename + +from ranger.ext.openstruct import OpenStruct + +class PaperManager(object): + def __init__(self): + self.metadata_cache = dict() + self.metafile_cache = dict() + + def reset(self): + self.metadata_cache.clear() + self.metafile_cache.clear() + + def get_paper_info(self, filename): + try: + return self.metadata_cache[filename] + except KeyError: + result = OpenStruct(title=None, year=None, filename=filename) + metafile = join(dirname(filename), ".paperinfo") + + # get entries of the metadata file + if metafile in self.metafile_cache: + entries = self.metafile_cache[metafile] + else: + if exists(metafile): + reader = csv.reader(open(metafile, "r"), + skipinitialspace=True) + + entries = list(entry for entry in reader if len(entry) == 3) + self.metafile_cache[metafile] = entries + else: + # No metadata file + entries = [] + + # Find the relevant entry in the metadata file + valid = (filename, basename(filename)) + for entry in entries: + if entry[0] in valid: + self._fill_ostruct_with_data(result, entry) + break + + # Cache the value + self.metadata_cache[filename] = result + return result + + def _fill_ostruct_with_data(self, ostruct, dataset): + filename, year, title = dataset + if year: + ostruct.year = year + if title: + ostruct.title = title diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index 9e177a52..c96a2d73 100644 --- a/ranger/gui/widgets/browsercolumn.py +++ b/ranger/gui/widgets/browsercolumn.py @@ -258,12 +258,25 @@ class BrowserColumn(Pager): self.color_reset() continue - if drawn._linemode == "filename": + + # Deal with the line mode + use_linemode = drawn._linemode + if use_linemode == "title": + paperinfo = self.fm.papermanager.get_paper_info(drawn.path) + if paperinfo.title: + if paperinfo.year: + text = "%s - %s" % (paperinfo.year, paperinfo.title) + else: + text = paperinfo.title + else: + use_linemode = "filename" + if use_linemode == "filename": text = drawn.basename - elif drawn._linemode == "permissions": + elif use_linemode == "permissions": text = "%s %s %s %s" % (drawn.get_permission_string(), drawn.user, drawn.group, drawn.basename) + if drawn.marked and (self.main_column or \ self.settings.display_tags_in_all_columns): text = " " + text @@ -291,7 +304,7 @@ class BrowserColumn(Pager): space -= vcsstringlen # info string - if drawn._linemode == "filename": + if use_linemode == "filename": infostring = self._draw_infostring_display(drawn, space) infostringlen = self._total_len(infostring) if space - infostringlen > 2: -- cgit 1.4.1-2-gfad0 From a941f97054a659cdf0f958ce1e5b7c99fed718fe Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 3 Dec 2014 18:18:58 +0100 Subject: properly redraw --- ranger/core/actions.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ranger/core/actions.py b/ranger/core/actions.py index 4d9d4121..0596e1a6 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -187,6 +187,10 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): bucket.clear() current_depth += 1 + # Ask the browsercolumns to redraw + for col in self.ui.browser.columns: + col.need_redraw = True + def open_console(self, string='', prompt=None, position=None): """Open the console""" self.change_mode('normal') -- cgit 1.4.1-2-gfad0 From 7417def6db0b5e9113335bd35e75ce1135e59253 Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 3 Dec 2014 18:28:00 +0100 Subject: core.actions: map linemode "normal" to "filemode" --- ranger/core/actions.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ranger/core/actions.py b/ranger/core/actions.py index 0596e1a6..26223b5f 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -155,12 +155,16 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): """ Change what is displayed as a filename. - "mode" may be: "filename", "permissions", "title" - "directory" specifies the directory. None means the current directory - "depth" specifies the recursion depth + - "mode" may be: "filename", "permissions", "title", the mode "normal" + is mapped to "filename". + - "directory" specifies the directory. None means the current directory + - "depth" specifies the recursion depth """ - assert mode in ("filename", "permissions", "title") + assert mode in ("normal", "filename", "permissions", "title") + + if mode == "normal": + mode = "filename" if directory is None: directory = self.fm.thisdir -- cgit 1.4.1-2-gfad0 From a13ad907a0453d89a86d6a98ccc72b2b8ae05a5b Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 3 Dec 2014 18:33:55 +0100 Subject: rename "title" linemode to "papertitle" --- ranger/container/fsobject.py | 2 +- ranger/core/actions.py | 4 ++-- ranger/gui/widgets/browsercolumn.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ranger/container/fsobject.py b/ranger/container/fsobject.py index fb3356a4..e5e0983e 100644 --- a/ranger/container/fsobject.py +++ b/ranger/container/fsobject.py @@ -82,7 +82,7 @@ class FileSystemObject(FileManagerAware, SettingsAware): basename_is_rel = False - # the line mode may be "filename", "permissions" or "title" + # the line mode may be "filename", "permissions" or "papertitle" _linemode = "filename" def __init__(self, path, preload=None, path_is_abs=False, basename_is_rel=False): diff --git a/ranger/core/actions.py b/ranger/core/actions.py index 26223b5f..3d74e03a 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -155,13 +155,13 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): """ Change what is displayed as a filename. - - "mode" may be: "filename", "permissions", "title", the mode "normal" + - "mode" may be: "filename", "permissions", "papertitle", the mode "normal" is mapped to "filename". - "directory" specifies the directory. None means the current directory - "depth" specifies the recursion depth """ - assert mode in ("normal", "filename", "permissions", "title") + assert mode in ("normal", "filename", "permissions", "papertitle") if mode == "normal": mode = "filename" diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index c96a2d73..137c30a4 100644 --- a/ranger/gui/widgets/browsercolumn.py +++ b/ranger/gui/widgets/browsercolumn.py @@ -261,7 +261,7 @@ class BrowserColumn(Pager): # Deal with the line mode use_linemode = drawn._linemode - if use_linemode == "title": + if use_linemode == "papertitle": paperinfo = self.fm.papermanager.get_paper_info(drawn.path) if paperinfo.title: if paperinfo.year: -- cgit 1.4.1-2-gfad0 From 1bf835096a9e864fa46c009973b690acf4aee59d Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 3 Dec 2014 18:34:06 +0100 Subject: added keybindings for changing linemode --- ranger/config/rc.conf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index 23cd2e10..107995da 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -232,6 +232,11 @@ map r chain draw_possible_programs; console open_with map f console find map cd console cd +# Change the line mode +map Mf linemode filename +map Mp linemode permissions +map Mt linemode papertitle + # Tagging / Marking map t tag_toggle map ut tag_remove -- cgit 1.4.1-2-gfad0 From 8d1b25656c488314073f4d317fa4d794b253f723 Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 3 Dec 2014 18:47:17 +0100 Subject: ext.papermanager: added docstring --- ranger/ext/papermanager.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/ranger/ext/papermanager.py b/ranger/ext/papermanager.py index a013585f..69b3095c 100644 --- a/ranger/ext/papermanager.py +++ b/ranger/ext/papermanager.py @@ -1,6 +1,19 @@ # Copyright (C) 2014 Roman Zimbelmann # This software is distributed under the terms of the GNU GPL version 3. +""" +A Paper Manager that reads metadata information about papers from a file. + +The file is named .paperinfo and is formatted as comma-separated values. + +The columns are: +1. Filename +2. Date +3. Title +4. Authors +5. URL +""" + import csv from os.path import join, dirname, exists, basename @@ -19,7 +32,8 @@ class PaperManager(object): try: return self.metadata_cache[filename] except KeyError: - result = OpenStruct(title=None, year=None, filename=filename) + result = OpenStruct(filename=filename, title=None, year=None, + authors=None, url=None) metafile = join(dirname(filename), ".paperinfo") # get entries of the metadata file @@ -30,7 +44,7 @@ class PaperManager(object): reader = csv.reader(open(metafile, "r"), skipinitialspace=True) - entries = list(entry for entry in reader if len(entry) == 3) + entries = list(entry for entry in reader if len(entry) == 5) self.metafile_cache[metafile] = entries else: # No metadata file @@ -48,8 +62,8 @@ class PaperManager(object): return result def _fill_ostruct_with_data(self, ostruct, dataset): - filename, year, title = dataset - if year: - ostruct.year = year - if title: - ostruct.title = title + filename, year, title, authors, url = dataset + if year: ostruct.year = year + if title: ostruct.title = title + if authors: ostruct.authors = authors + if url: ostruct.url = url -- cgit 1.4.1-2-gfad0 From 8bd812c02a1e08aaba2a6a8ca924c41c525bea40 Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 3 Dec 2014 19:17:54 +0100 Subject: ext.papermanager: turn result.authors into a list --- ranger/ext/papermanager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ranger/ext/papermanager.py b/ranger/ext/papermanager.py index 69b3095c..4e53bcc7 100644 --- a/ranger/ext/papermanager.py +++ b/ranger/ext/papermanager.py @@ -65,5 +65,5 @@ class PaperManager(object): filename, year, title, authors, url = dataset if year: ostruct.year = year if title: ostruct.title = title - if authors: ostruct.authors = authors + if authors: ostruct.authors = authors.split(",") if url: ostruct.url = url -- cgit 1.4.1-2-gfad0 From 45a43d9cdaf0fc6bb85c3b188743ac0b3617b2a9 Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 3 Dec 2014 19:18:17 +0100 Subject: widgets.browsercolumn: better drawing of paper info --- ranger/gui/widgets/browsercolumn.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index 137c30a4..8367afa6 100644 --- a/ranger/gui/widgets/browsercolumn.py +++ b/ranger/gui/widgets/browsercolumn.py @@ -260,6 +260,7 @@ class BrowserColumn(Pager): # Deal with the line mode + paperinfo = None use_linemode = drawn._linemode if use_linemode == "papertitle": paperinfo = self.fm.papermanager.get_paper_info(drawn.path) @@ -304,8 +305,14 @@ class BrowserColumn(Pager): space -= vcsstringlen # info string + infostring = [] + infostringlen = 0 if use_linemode == "filename": infostring = self._draw_infostring_display(drawn, space) + elif use_linemode == "papertitle": + if paperinfo: + infostring.append([" " + paperinfo.authors[0] + " ", ["infostring"]]) + if infostring: infostringlen = self._total_len(infostring) if space - infostringlen > 2: predisplay_right = infostring + predisplay_right -- cgit 1.4.1-2-gfad0 From 1f144a8a067eb23267f2f7eb5be0a725b97e8a68 Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 3 Dec 2014 19:28:13 +0100 Subject: ext.papermanager: move pagerinfo file name into variable --- ranger/ext/papermanager.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ranger/ext/papermanager.py b/ranger/ext/papermanager.py index 4e53bcc7..69332b21 100644 --- a/ranger/ext/papermanager.py +++ b/ranger/ext/papermanager.py @@ -14,6 +14,8 @@ The columns are: 5. URL """ +PAGERINFO_FILE_NAME = ".pagerinfo" + import csv from os.path import join, dirname, exists, basename @@ -34,7 +36,7 @@ class PaperManager(object): except KeyError: result = OpenStruct(filename=filename, title=None, year=None, authors=None, url=None) - metafile = join(dirname(filename), ".paperinfo") + metafile = join(dirname(filename), PAGERINFO_FILE_NAME) # get entries of the metadata file if metafile in self.metafile_cache: -- cgit 1.4.1-2-gfad0 From 104c5a37894cb993b1e7993e3b04fca61baff347 Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 3 Dec 2014 20:23:28 +0100 Subject: reset papermanager cache when resetting fm --- ranger/core/actions.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ranger/core/actions.py b/ranger/core/actions.py index 3d74e03a..13bf4dd3 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -51,6 +51,8 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): self.garbage_collect(-1) self.enter_dir(old_path) self.change_mode('normal') + if self.papermanager: + self.papermanager.reset() def change_mode(self, mode): if mode == self.mode: -- cgit 1.4.1-2-gfad0 From 13b6d8413630c00fb1fb7f55cc416bca5ce2425c Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 3 Dec 2014 21:29:37 +0100 Subject: added pagermanager_deep_search option --- ranger/config/rc.conf | 4 ++++ ranger/container/settings.py | 1 + ranger/ext/papermanager.py | 52 ++++++++++++++++++++++++++------------------ 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index 107995da..34ee2fad 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -174,6 +174,10 @@ set show_selection_in_titlebar true # increases CPU load. set idle_delay 2000 +# In the paper manger mode, should ranger try to find the ".paperinfo" file in +# directories above the current directory? +set papermanager_deep_search true + # =================================================================== # == Local Options # =================================================================== diff --git a/ranger/container/settings.py b/ranger/container/settings.py index f75c274f..ad42b13f 100644 --- a/ranger/container/settings.py +++ b/ranger/container/settings.py @@ -31,6 +31,7 @@ ALLOWED_SETTINGS = { 'mouse_enabled': bool, 'open_all_images': bool, 'padding_right': bool, + 'papermanager_deep_search': bool, 'preview_directories': bool, 'preview_files': bool, 'preview_images': bool, diff --git a/ranger/ext/papermanager.py b/ranger/ext/papermanager.py index 69332b21..ff6ffb73 100644 --- a/ranger/ext/papermanager.py +++ b/ranger/ext/papermanager.py @@ -14,7 +14,8 @@ The columns are: 5. URL """ -PAGERINFO_FILE_NAME = ".pagerinfo" +PAPERINFO_FILE_NAME = ".paperinfo" +DEEP_SEARCH_DEFAULT = True import csv from os.path import join, dirname, exists, basename @@ -25,6 +26,7 @@ class PaperManager(object): def __init__(self): self.metadata_cache = dict() self.metafile_cache = dict() + self.deep_search = DEEP_SEARCH_DEFAULT def reset(self): self.metadata_cache.clear() @@ -36,33 +38,41 @@ class PaperManager(object): except KeyError: result = OpenStruct(filename=filename, title=None, year=None, authors=None, url=None) - metafile = join(dirname(filename), PAGERINFO_FILE_NAME) - # get entries of the metadata file - if metafile in self.metafile_cache: - entries = self.metafile_cache[metafile] - else: - if exists(metafile): - reader = csv.reader(open(metafile, "r"), - skipinitialspace=True) - - entries = list(entry for entry in reader if len(entry) == 5) - self.metafile_cache[metafile] = entries - else: - # No metadata file - entries = [] - - # Find the relevant entry in the metadata file valid = (filename, basename(filename)) - for entry in entries: - if entry[0] in valid: - self._fill_ostruct_with_data(result, entry) - break + for metafile in self._get_metafile_names(filename): + for entry in self._get_metafile_content(metafile): + if entry[0] in valid: + self._fill_ostruct_with_data(result, entry) + self.metadata_cache[filename] = result + return result # Cache the value self.metadata_cache[filename] = result return result + def _get_metafile_content(self, metafile): + if metafile in self.metafile_cache: + return self.metafile_cache[metafile] + else: + if exists(metafile): + reader = csv.reader(open(metafile, "r"), + skipinitialspace=True) + + entries = list(entry for entry in reader if len(entry) == 5) + self.metafile_cache[metafile] = entries + return entries + else: + return [] + + def _get_metafile_names(self, path): + base = dirname(path) + yield join(base, PAPERINFO_FILE_NAME) + if self.deep_search: + dirs = base.split("/")[1:] + for i in reversed(range(len(dirs))): + yield join("/" + "/".join(dirs[0:i]), PAPERINFO_FILE_NAME) + def _fill_ostruct_with_data(self, ostruct, dataset): filename, year, title, authors, url = dataset if year: ostruct.year = year -- cgit 1.4.1-2-gfad0 From be79683c98602082b16c6ef0194a22c6f904a572 Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 3 Dec 2014 21:55:42 +0100 Subject: config/commands.py: add papermanager commands --- ranger/config/commands.py | 47 ++++++++++++++++++++++++++++++++++++++++++++++ ranger/ext/papermanager.py | 3 +++ 2 files changed, 50 insertions(+) diff --git a/ranger/config/commands.py b/ranger/config/commands.py index 953e2cc3..39334659 100644 --- a/ranger/config/commands.py +++ b/ranger/config/commands.py @@ -1281,3 +1281,50 @@ class flat(Command): self.fm.thisdir.flat = level self.fm.thisdir.load_content() + +# Papermanager commands +# -------------------------------- +class paper_title(Command): + """ + :paper_title + + Tells the paper manager to set/update the title of the current file + """ + _key = "title" + + def execute(self): + update_dict = dict() + update_dict[self._key] = self.rest(1) + self.fm.papermanager.set_paper_info(self.fm.thisfile.path, update_dict) + + def tab(self): + paperinfo = self.fm.papermanager.get_paper_info(self.fm.thisfile.path) + if paperinfo[self._key]: + return self.arg(0) + " " + paperinfo[self._key] + + +class paper_authors(paper_title): + """ + :paper_authors <authors> + + Tells the paper manager to set/update the authors of the current file + """ + _key = "authors" + + +class paper_url(paper_title): + """ + :paper_url <authors> + + Tells the paper manager to set/update the url of the current file + """ + _key = "url" + + +class paper_year(paper_title): + """ + :paper_year <authors> + + Tells the paper manager to set/update the year of the current file + """ + _key = "year" diff --git a/ranger/ext/papermanager.py b/ranger/ext/papermanager.py index ff6ffb73..0a3e73ac 100644 --- a/ranger/ext/papermanager.py +++ b/ranger/ext/papermanager.py @@ -51,6 +51,9 @@ class PaperManager(object): self.metadata_cache[filename] = result return result + def set_paper_info(self, filename, update_dict): + pass + def _get_metafile_content(self, metafile): if metafile in self.metafile_cache: return self.metafile_cache[metafile] -- cgit 1.4.1-2-gfad0 From db7ad38a95381cc7cf2f3739acc745c7b4ab8f5a Mon Sep 17 00:00:00 2001 From: hut <hut@lepus.uberspace.de> Date: Wed, 3 Dec 2014 22:03:07 +0100 Subject: ext.papermanager: don't transform pagerinfo.authors --- ranger/ext/papermanager.py | 2 +- ranger/gui/widgets/browsercolumn.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ranger/ext/papermanager.py b/ranger/ext/papermanager.py index 0a3e73ac..6c422659 100644 --- a/ranger/ext/papermanager.py +++ b/ranger/ext/papermanager.py @@ -80,5 +80,5 @@ class PaperManager(object): filename, year, title, authors, url = dataset if year: ostruct.year = year if title: ostruct.title = title - if authors: ostruct.authors = authors.split(",") + if authors: ostruct.authors = authors if url: ostruct.url = url diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index 8367afa6..3757af4b 100644 --- a/ranger/gui/widgets/browsercolumn.py +++ b/ranger/gui/widgets/browsercolumn.py @@ -311,7 +311,10 @@ class BrowserColumn(Pager): infostring = self._draw_infostring_display(drawn, space) elif use_linemode == "papertitle": if paperinfo: - infostring.append([" " + paperinfo.authors[0] + " ", ["infostring"]]) + authorstring = paperinfo.authors + if ',' in authorstring: + authorstring = authorstring[0:authorstring.find(",")] + infostring.append([" " + authorstring + " ", ["infostring"]]) if infostring: infostringlen = self._total_len(infostring) if space - infostringlen > 2: -- cgit 1.4.1-2-gfad0 From d0c71b43671de40930438acde622cec1943c214b Mon Sep 17 00:00:00 2001 From: hut <hut@lepus.uberspace.de> Date: Wed, 3 Dec 2014 23:38:48 +0100 Subject: ext.papermanager: implemented writing to .paperinfo --- ranger/ext/papermanager.py | 78 +++++++++++++++++++++++++++++++++++-- ranger/gui/widgets/browsercolumn.py | 2 +- 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/ranger/ext/papermanager.py b/ranger/ext/papermanager.py index 6c422659..932505c9 100644 --- a/ranger/ext/papermanager.py +++ b/ranger/ext/papermanager.py @@ -52,15 +52,87 @@ class PaperManager(object): return result def set_paper_info(self, filename, update_dict): - pass + result = None + found = False + valid = (filename, basename(filename)) + first_metafile = None + + if not self.deep_search: + metafile = next(self._get_metafile_names(filename)) + return self._set_pager_info_raw(filename, update_dict, metafile) + + for i, metafile in enumerate(self._get_metafile_names(filename)): + if i == 0: + first_metafile = metafile + + csvfile = None + try: + csvfile = open(metafile, "r") + except: + # .paperinfo file doesn't exist... look for another one. + pass + else: + reader = csv.reader(csvfile, skipinitialspace=True) + for row in reader: + name, year, title, authors, url = row + if name in valid: + return self._set_pager_info_raw(filename, update_dict, + metafile) + finally: + if csvfile: + csvfile.close() + + # No .paperinfo file found, so let's create a new one in the same path + # as the given file. + if first_metafile: + return self._set_pager_info_raw(filename, update_dict, first_metafile) + + def _set_pager_info_raw(self, filename, update_dict, metafile): + valid = (filename, basename(filename)) + + try: + with open(metafile, "r") as infile: + reader = csv.reader(infile, skipinitialspace=True) + rows = list(reader) + except IOError: + rows = [] + + with open(metafile, "w") as outfile: + writer = csv.writer(outfile) + found = False + + # Iterate through all rows and write them back to the file. + for row in rows: + if not found and row[0] in valid: + # When finding the row that corresponds to the given filename, + # update the items with the information from update_dict. + self._fill_row_with_ostruct(row, update_dict) + found = True + writer.writerow(row) + + # If the row was never found, create a new one. + if not found: + row = [basename(filename), None, None, None, None] + self._fill_row_with_ostruct(row, update_dict) + writer.writerow(row) + + def _fill_row_with_ostruct(self, row, update_dict): + for key, value in update_dict.items(): + if key == "year": + row[1] = value + elif key == "title": + row[2] = value + elif key == "authors": + row[3] = value + elif key == "url": + row[4] = value def _get_metafile_content(self, metafile): if metafile in self.metafile_cache: return self.metafile_cache[metafile] else: if exists(metafile): - reader = csv.reader(open(metafile, "r"), - skipinitialspace=True) + reader = csv.reader(open(metafile, "r"), skipinitialspace=True) entries = list(entry for entry in reader if len(entry) == 5) self.metafile_cache[metafile] = entries diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index 3757af4b..12523648 100644 --- a/ranger/gui/widgets/browsercolumn.py +++ b/ranger/gui/widgets/browsercolumn.py @@ -310,7 +310,7 @@ class BrowserColumn(Pager): if use_linemode == "filename": infostring = self._draw_infostring_display(drawn, space) elif use_linemode == "papertitle": - if paperinfo: + if paperinfo and paperinfo.authors: authorstring = paperinfo.authors if ',' in authorstring: authorstring = authorstring[0:authorstring.find(",")] -- cgit 1.4.1-2-gfad0 From 0f15efb7a8893ed8161a42ef0a21094b98ee4dc5 Mon Sep 17 00:00:00 2001 From: hut <hut@lepus.uberspace.de> Date: Wed, 3 Dec 2014 23:39:03 +0100 Subject: ext.papermanager: added comments --- ranger/ext/papermanager.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/ranger/ext/papermanager.py b/ranger/ext/papermanager.py index 932505c9..15fc13a5 100644 --- a/ranger/ext/papermanager.py +++ b/ranger/ext/papermanager.py @@ -141,6 +141,11 @@ class PaperManager(object): return [] def _get_metafile_names(self, path): + # Iterates through the paths of all .paperinfo files that could + # influence the metadata of the given file. + # When deep_search is deactivated, this only yields the .paperinfo file + # in the same directory as the given file. + base = dirname(path) yield join(base, PAPERINFO_FILE_NAME) if self.deep_search: @@ -149,8 +154,10 @@ class PaperManager(object): yield join("/" + "/".join(dirs[0:i]), PAPERINFO_FILE_NAME) def _fill_ostruct_with_data(self, ostruct, dataset): + # Copy data from a CSV row to a dict/ostruct + filename, year, title, authors, url = dataset - if year: ostruct.year = year - if title: ostruct.title = title - if authors: ostruct.authors = authors - if url: ostruct.url = url + if year: ostruct['year'] = year + if title: ostruct['title'] = title + if authors: ostruct['authors'] = authors + if url: ostruct['url'] = url -- cgit 1.4.1-2-gfad0 From 30513c6585b685afc157efcb979c722731885e50 Mon Sep 17 00:00:00 2001 From: hut <hut@lepus.uberspace.de> Date: Wed, 3 Dec 2014 23:40:53 +0100 Subject: ext.papermanager: moved and commented a function --- ranger/ext/papermanager.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/ranger/ext/papermanager.py b/ranger/ext/papermanager.py index 15fc13a5..c01ea784 100644 --- a/ranger/ext/papermanager.py +++ b/ranger/ext/papermanager.py @@ -116,17 +116,6 @@ class PaperManager(object): self._fill_row_with_ostruct(row, update_dict) writer.writerow(row) - def _fill_row_with_ostruct(self, row, update_dict): - for key, value in update_dict.items(): - if key == "year": - row[1] = value - elif key == "title": - row[2] = value - elif key == "authors": - row[3] = value - elif key == "url": - row[4] = value - def _get_metafile_content(self, metafile): if metafile in self.metafile_cache: return self.metafile_cache[metafile] @@ -161,3 +150,15 @@ class PaperManager(object): if title: ostruct['title'] = title if authors: ostruct['authors'] = authors if url: ostruct['url'] = url + + def _fill_row_with_ostruct(self, row, update_dict): + # Copy data from a dict/ostruct into a CSV row + for key, value in update_dict.items(): + if key == "year": + row[1] = value + elif key == "title": + row[2] = value + elif key == "authors": + row[3] = value + elif key == "url": + row[4] = value -- cgit 1.4.1-2-gfad0 From 90f9bac4803325270f13e7ab5a53bfe8221809b1 Mon Sep 17 00:00:00 2001 From: hut <hut@lepus.uberspace.de> Date: Wed, 3 Dec 2014 23:56:26 +0100 Subject: core.fm: propagate papermanager_deep_search setting --- ranger/core/fm.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ranger/core/fm.py b/ranger/core/fm.py index 885068e5..fbdc5a6a 100644 --- a/ranger/core/fm.py +++ b/ranger/core/fm.py @@ -61,6 +61,9 @@ class FM(Actions, SignalDispatcher): self.copy_buffer = set() self.do_cut = False self.papermanager = PaperManager() + self.settings.signal_bind('setopt.papermanager_deep_search', + lambda signal: setattr(signal.fm.papermanager, 'deep_search', + signal.value)) try: self.username = pwd.getpwuid(os.geteuid()).pw_name -- cgit 1.4.1-2-gfad0 From 2d7dc04212c5e9afa06257dc28f7b45f13dcbebd Mon Sep 17 00:00:00 2001 From: hut <hut@lepus.uberspace.de> Date: Thu, 4 Dec 2014 00:27:36 +0100 Subject: config/commands.py: added :paper command This uses a hacky workaround for command chaining using global varibales which should be turned into proper OOP code at some point. I don't have the time to redesign ranger/gui/widgets/console.py at this point. --- ranger/config/commands.py | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/ranger/config/commands.py b/ranger/config/commands.py index 39334659..1685898b 100644 --- a/ranger/config/commands.py +++ b/ranger/config/commands.py @@ -1284,7 +1284,35 @@ class flat(Command): # Papermanager commands # -------------------------------- -class paper_title(Command): +class paper(Command): + """ + :paper + + This command opens a series of commands on the console that will ask the + user to input metadata about the current file. This is used by the paper + manager module of ranger and can be later displayed in ranger, for example + by setting the option "linemode" to "papertitle". + """ + def execute(self): + # TODO: This sets a pseudo-global variable containing a stack of + # commands that should be opened in the console next. It's a + # work-around for ranger's lack of inherent console command chaining + # and will hopefully be implemented properly in the future. + paper._paper_console_chain = ["url", "year", "authors", "title"] + + self._process_command_stack() + + def _process_command_stack(self): + if paper._paper_console_chain: + key = paper._paper_console_chain.pop() + self._paper_fill_console(key) + + def _paper_fill_console(self, key): + text = "paper_%s %s" % (key, "foo") + self.fm.open_console(text, position=len(text)) + + +class paper_title(paper): """ :paper_title <title> @@ -1296,6 +1324,7 @@ class paper_title(Command): update_dict = dict() update_dict[self._key] = self.rest(1) self.fm.papermanager.set_paper_info(self.fm.thisfile.path, update_dict) + self._process_command_stack() def tab(self): paperinfo = self.fm.papermanager.get_paper_info(self.fm.thisfile.path) -- cgit 1.4.1-2-gfad0 From 8c987ebc72928fef34ca14e16b7d1d538610fbd4 Mon Sep 17 00:00:00 2001 From: hut <hut@lepus.uberspace.de> Date: Thu, 4 Dec 2014 00:30:43 +0100 Subject: change papermanager_deep_search default option to false --- ranger/config/rc.conf | 2 +- ranger/ext/papermanager.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index 34ee2fad..9514c55f 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -176,7 +176,7 @@ set idle_delay 2000 # In the paper manger mode, should ranger try to find the ".paperinfo" file in # directories above the current directory? -set papermanager_deep_search true +set papermanager_deep_search false # =================================================================== # == Local Options diff --git a/ranger/ext/papermanager.py b/ranger/ext/papermanager.py index c01ea784..059f051f 100644 --- a/ranger/ext/papermanager.py +++ b/ranger/ext/papermanager.py @@ -15,7 +15,7 @@ The columns are: """ PAPERINFO_FILE_NAME = ".paperinfo" -DEEP_SEARCH_DEFAULT = True +DEEP_SEARCH_DEFAULT = False import csv from os.path import join, dirname, exists, basename -- cgit 1.4.1-2-gfad0 From 987d618504ead0a099160c14855d8181500f3463 Mon Sep 17 00:00:00 2001 From: hut <hut@lepus.uberspace.de> Date: Thu, 4 Dec 2014 00:36:16 +0100 Subject: config/commands.py: in :paper, properly fill in the console lines --- ranger/config/commands.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ranger/config/commands.py b/ranger/config/commands.py index 1685898b..8145aadd 100644 --- a/ranger/config/commands.py +++ b/ranger/config/commands.py @@ -1308,7 +1308,12 @@ class paper(Command): self._paper_fill_console(key) def _paper_fill_console(self, key): - text = "paper_%s %s" % (key, "foo") + paperinfo = self.fm.papermanager.get_paper_info(self.fm.thisfile.path) + if key in paperinfo and paperinfo[key]: + existing_value = paperinfo[key] + else: + existing_value = "" + text = "paper_%s %s" % (key, existing_value) self.fm.open_console(text, position=len(text)) -- cgit 1.4.1-2-gfad0 From b132301bc72351ad0baad92650cfc040112cafee Mon Sep 17 00:00:00 2001 From: hut <hut@lepus.uberspace.de> Date: Thu, 4 Dec 2014 00:51:41 +0100 Subject: ext.papermanager: redraw after using :paper* commands --- ranger/config/commands.py | 3 +++ ranger/ext/papermanager.py | 7 +++++++ ranger/gui/widgets/browsercolumn.py | 22 ++++++++++++---------- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/ranger/config/commands.py b/ranger/config/commands.py index 8145aadd..8485c784 100644 --- a/ranger/config/commands.py +++ b/ranger/config/commands.py @@ -1306,6 +1306,9 @@ class paper(Command): if paper._paper_console_chain: key = paper._paper_console_chain.pop() self._paper_fill_console(key) + else: + for col in self.fm.ui.browser.columns: + col.need_redraw = True def _paper_fill_console(self, key): paperinfo = self.fm.papermanager.get_paper_info(self.fm.thisfile.path) diff --git a/ranger/ext/papermanager.py b/ranger/ext/papermanager.py index 059f051f..366dd6fa 100644 --- a/ranger/ext/papermanager.py +++ b/ranger/ext/papermanager.py @@ -78,6 +78,7 @@ class PaperManager(object): if name in valid: return self._set_pager_info_raw(filename, update_dict, metafile) + self.metadata_cache[filename] = result finally: if csvfile: csvfile.close() @@ -89,6 +90,8 @@ class PaperManager(object): def _set_pager_info_raw(self, filename, update_dict, metafile): valid = (filename, basename(filename)) + paperinfo = OpenStruct(filename=filename, title=None, year=None, + authors=None, url=None) try: with open(metafile, "r") as infile: @@ -107,6 +110,8 @@ class PaperManager(object): # When finding the row that corresponds to the given filename, # update the items with the information from update_dict. self._fill_row_with_ostruct(row, update_dict) + self._fill_ostruct_with_data(paperinfo, row) + self.metadata_cache[filename] = paperinfo found = True writer.writerow(row) @@ -114,6 +119,8 @@ class PaperManager(object): if not found: row = [basename(filename), None, None, None, None] self._fill_row_with_ostruct(row, update_dict) + self._fill_ostruct_with_data(paperinfo, row) + self.metadata_cache[filename] = paperinfo writer.writerow(row) def _get_metafile_content(self, metafile): diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index 12523648..b2159339 100644 --- a/ranger/gui/widgets/browsercolumn.py +++ b/ranger/gui/widgets/browsercolumn.py @@ -248,10 +248,18 @@ class BrowserColumn(Pager): else: tagged_marker = " " + # Extract linemode-related information from the drawn object + paperinfo = None + use_linemode = drawn._linemode + if use_linemode == "papertitle": + paperinfo = self.fm.papermanager.get_paper_info(drawn.path) + if not paperinfo.title: + use_linemode = "filename" + 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, - drawn._linemode) + use_linemode) if key in drawn.display_data: self.execute_curses_batch(line, drawn.display_data[key]) @@ -260,17 +268,11 @@ class BrowserColumn(Pager): # Deal with the line mode - paperinfo = None - use_linemode = drawn._linemode if use_linemode == "papertitle": - paperinfo = self.fm.papermanager.get_paper_info(drawn.path) - if paperinfo.title: - if paperinfo.year: - text = "%s - %s" % (paperinfo.year, paperinfo.title) - else: - text = paperinfo.title + if paperinfo.year: + text = "%s - %s" % (paperinfo.year, paperinfo.title) else: - use_linemode = "filename" + text = paperinfo.title if use_linemode == "filename": text = drawn.basename elif use_linemode == "permissions": -- cgit 1.4.1-2-gfad0 From 42325092019837545a67b0851a3bbc7104f15f57 Mon Sep 17 00:00:00 2001 From: hut <hut@lepus.uberspace.de> Date: Thu, 4 Dec 2014 01:05:20 +0100 Subject: ext.papermanager: s/pager/paper/ --- ranger/ext/papermanager.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ranger/ext/papermanager.py b/ranger/ext/papermanager.py index 366dd6fa..a6292c49 100644 --- a/ranger/ext/papermanager.py +++ b/ranger/ext/papermanager.py @@ -59,7 +59,7 @@ class PaperManager(object): if not self.deep_search: metafile = next(self._get_metafile_names(filename)) - return self._set_pager_info_raw(filename, update_dict, metafile) + return self._set_paper_info_raw(filename, update_dict, metafile) for i, metafile in enumerate(self._get_metafile_names(filename)): if i == 0: @@ -76,7 +76,7 @@ class PaperManager(object): for row in reader: name, year, title, authors, url = row if name in valid: - return self._set_pager_info_raw(filename, update_dict, + return self._set_paper_info_raw(filename, update_dict, metafile) self.metadata_cache[filename] = result finally: @@ -86,9 +86,9 @@ class PaperManager(object): # No .paperinfo file found, so let's create a new one in the same path # as the given file. if first_metafile: - return self._set_pager_info_raw(filename, update_dict, first_metafile) + return self._set_paper_info_raw(filename, update_dict, first_metafile) - def _set_pager_info_raw(self, filename, update_dict, metafile): + def _set_paper_info_raw(self, filename, update_dict, metafile): valid = (filename, basename(filename)) paperinfo = OpenStruct(filename=filename, title=None, year=None, authors=None, url=None) -- cgit 1.4.1-2-gfad0 From 1f58043102c54d3fdc1243931e2b02151610dd2b Mon Sep 17 00:00:00 2001 From: hut <hut@lepus.uberspace.de> Date: Fri, 5 Dec 2014 00:25:28 +0100 Subject: config/commands.py: added :default_linemode command --- ranger/config/commands.py | 37 +++++++++++++++++++++++++++++++++++++ ranger/container/fsobject.py | 21 +++++++++++++++++++-- ranger/core/fm.py | 1 + 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/ranger/config/commands.py b/ranger/config/commands.py index 8485c784..db14403f 100644 --- a/ranger/config/commands.py +++ b/ranger/config/commands.py @@ -381,6 +381,43 @@ class setintag(setlocal): self.fm.set_option_from_string(name, value, tags=tags) +class default_linemode(Command): + def execute(self): + import re + from ranger.container.fsobject import POSSIBLE_LINEMODES + + if len(self.args) < 2: + self.fm.notify("Usage: default_linemode [path=<regexp> | tag=<tag(s)>] <linemode>", bad=True) + + # Extract options like "path=..." or "tag=..." from the command line + arg1 = self.arg(1) + method = "always" + argument = None + if arg1.startswith("path="): + method = "path" + argument = re.compile(arg1[5:]) + self.shift() + elif arg1.startswith("tag="): + method = "tag" + argument = arg1[4:] + self.shift() + + # Extract and validate the line mode from the command line + linemode = self.rest(1) + if linemode not in POSSIBLE_LINEMODES: + self.fm.notify("Invalid linemode: %s; should be %s" % + (linemode, "/".join(POSSIBLE_LINEMODES)), bad=True) + + # Add the prepared entry to the fm.default_linemodes + entry = [method, argument, linemode] + self.fm.default_linemodes.appendleft(entry) + + # Redraw the columns + if hasattr(self.fm.ui, "browser"): + for col in self.fm.ui.browser.columns: + col.need_redraw = True + + class quit(Command): """:quit diff --git a/ranger/container/fsobject.py b/ranger/container/fsobject.py index e5e0983e..59e23f6b 100644 --- a/ranger/container/fsobject.py +++ b/ranger/container/fsobject.py @@ -12,6 +12,9 @@ DOCUMENT_BASENAMES = ('bugs', 'bugs', 'changelog', 'copying', 'credits', BAD_INFO = '?' +POSSIBLE_LINEMODES = ("filename", "papertitle", "permissions") +DEFAULT_LINEMODE = "filename" + import re from grp import getgrgid from os import lstat, stat, getcwd @@ -82,8 +85,7 @@ class FileSystemObject(FileManagerAware, SettingsAware): basename_is_rel = False - # the line mode may be "filename", "permissions" or "papertitle" - _linemode = "filename" + _linemode = DEFAULT_LINEMODE def __init__(self, path, preload=None, path_is_abs=False, basename_is_rel=False): if not path_is_abs: @@ -106,6 +108,21 @@ class FileSystemObject(FileManagerAware, SettingsAware): except ValueError: self.extension = None + # Set the line mode from fm.default_linemodes + for method, argument, linemode in self.fm.default_linemodes: + if linemode in POSSIBLE_LINEMODES: + if method == "always": + self._linemode = linemode + break + if method == "path" and argument.search(path): + self._linemode = linemode + break + if method == "tag" and self.realpath in self.fm.tags and \ + self.fm.tags.marker(self.realpath) in argument: + self._linemode = linemode + break + + def __repr__(self): return "<{0} {1}>".format(self.__class__.__name__, self.path) diff --git a/ranger/core/fm.py b/ranger/core/fm.py index fbdc5a6a..3497f20c 100644 --- a/ranger/core/fm.py +++ b/ranger/core/fm.py @@ -57,6 +57,7 @@ class FM(Actions, SignalDispatcher): self.restorable_tabs = deque([], ranger.MAX_RESTORABLE_TABS) self.py3 = sys.version_info >= (3, ) self.previews = {} + self.default_linemodes = deque() self.loader = Loader() self.copy_buffer = set() self.do_cut = False -- cgit 1.4.1-2-gfad0 From bb3e357a6df9c7ee6ecb351bda25a28b1e916a6e Mon Sep 17 00:00:00 2001 From: hut <hut@lepus.uberspace.de> Date: Fri, 5 Dec 2014 00:26:06 +0100 Subject: core.actions: make the hardcoded linemode check more dynamic --- ranger/core/actions.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ranger/core/actions.py b/ranger/core/actions.py index 13bf4dd3..879d1f68 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -27,6 +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 MACRO_FAIL = "<\x01\x01MACRO_HAS_NO_VALUE\x01\01>" @@ -163,10 +164,10 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): - "depth" specifies the recursion depth """ - assert mode in ("normal", "filename", "permissions", "papertitle") + assert mode == "normal" or mode in POSSIBLE_LINEMODES if mode == "normal": - mode = "filename" + mode = DEFAULT_LINEMODE if directory is None: directory = self.fm.thisdir -- cgit 1.4.1-2-gfad0 From a4ca7aaacfebec8558b681eef076116ed8cab688 Mon Sep 17 00:00:00 2001 From: hut <hut@lepus.uberspace.de> Date: Fri, 5 Dec 2014 01:01:32 +0100 Subject: config/commands.py: fix paper_* commands It expected paper._paper_console_chain to be set, but it isn't by default... --- ranger/config/commands.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ranger/config/commands.py b/ranger/config/commands.py index db14403f..49d8f213 100644 --- a/ranger/config/commands.py +++ b/ranger/config/commands.py @@ -1330,6 +1330,7 @@ class paper(Command): manager module of ranger and can be later displayed in ranger, for example by setting the option "linemode" to "papertitle". """ + _paper_console_chain = None def execute(self): # TODO: This sets a pseudo-global variable containing a stack of # commands that should be opened in the console next. It's a -- cgit 1.4.1-2-gfad0 From bf6158a1088c7e2bb1f83d6a48c8de3f9c9c88f6 Mon Sep 17 00:00:00 2001 From: hut <hut@lepus.uberspace.de> Date: Fri, 5 Dec 2014 01:39:10 +0100 Subject: doc/ranger.1: added documentation on linemodes and :paper commands --- doc/ranger.1 | 56 ++++++++++++++++++++++++++++++++++++++++++++++- doc/ranger.pod | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ ranger/config/rc.conf | 5 +++-- 3 files changed, 118 insertions(+), 3 deletions(-) diff --git a/doc/ranger.1 b/doc/ranger.1 index 9aa4e318..5b245dd8 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "RANGER 1" -.TH RANGER 1 "ranger-1.6.1" "10/31/2014" "ranger manual" +.TH RANGER 1 "ranger-1.6.1" "12/05/2014" "ranger manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -684,6 +684,11 @@ How many directory changes should be kept in history? .IP "mouse_enabled [bool] <zm>" 4 .IX Item "mouse_enabled [bool] <zm>" Enable mouse input? +.IP "papermanager_deep_search [bool]" 4 +.IX Item "papermanager_deep_search [bool]" +When the paper manager module looks for metadata, should it only look for a +\&\*(L".paperinfo\*(R" file in the current directory, or do a deep search and check all +directories above the current one as well? .IP "padding_right [bool]" 4 .IX Item "padding_right [bool]" When collapse_preview is on and there is no preview, should there remain a @@ -798,18 +803,25 @@ ranger. For your convenience, this is a list of the \*(L"public\*(R" commands i \& copypmap key newkey [newkey2...] \& copytmap key newkey [newkey2...] \& cunmap keys... +\& default_linemode [path=regexp | tag=tags] linemodename \& delete \& edit [filename] \& eval [\-q] python_code \& filter [string] \& find pattern \& grep pattern +\& linemode linemodename \& load_copy_buffer \& map key command \& mark pattern \& mark_tag [tags] \& mkdir dirname \& open_with [application] [flags] [mode] +\& paper +\& paper_authors [authors] +\& paper_title [title] +\& paper_url [url] +\& paper_year [year] \& pmap key command \& punmap keys... \& quit @@ -898,6 +910,20 @@ See \f(CW\*(C`copymap\*(C'\fR .IP "cunmap [\fIkeys...\fR]" 2 .IX Item "cunmap [keys...]" Removes key mappings of the console. Works like the \f(CW\*(C`unmap\*(C'\fR command. +.IP "default_linemode [\fIpath=regexp\fR | \fItag=tags\fR] \fIlinemodename\fR" 2 +.IX Item "default_linemode [path=regexp | tag=tags] linemodename" +Sets the default linemode. See \fIlinemode\fR command. +.Sp +Examples: +.Sp +Set the global default linemode to \*(L"permissions\*(R": + :default_linemode permissions +.Sp +Set the default linemode to \*(L"permissions\*(R" for all files tagged with \*(L"p\*(R" or \*(L"P\*(R": + :default_linemode tag=pP permissions +.Sp +Set the default linemode for all files in ~/books/ to \*(L"papertitle\*(R": + :default_linemode path=/home/.*?/books/.* papertitle .IP "delete" 2 .IX Item "delete" Destroy all files in the selection with a roundhouse kick. ranger will ask for @@ -932,6 +958,16 @@ This command is based on the \fIscout\fR command and supports all of its options .IP "grep \fIpattern\fR" 2 .IX Item "grep pattern" Looks for a string in all marked files or directories. +.IP "linemode \fIlinemodename\fR" 2 +.IX Item "linemode linemodename" +Sets the linemode of all files in the current directory. The linemode may be: +.Sp +.Vb 4 +\& "filename": display each line as "<basename>...<size>" +\& "permissions": display each line as "<permissions> <owner> <group> <basename>" +\& "papertitle": display metadata from .paperinfo files if available, fall back +\& to the "filename" linemode if no metadata was found. See :paper commands. +.Ve .IP "load_copy_buffer" 2 .IX Item "load_copy_buffer" Load the copy buffer from \fI~/.config/ranger/copy_buffer\fR. This can be used to @@ -968,6 +1004,24 @@ of applications is generated by the external file opener \*(L"rifle\*(R" and can displayed when pressing \*(L"r\*(R" in ranger. .Sp Note that if you specify an application, the mode is ignored. +.IP "paper" 2 +.IX Item "paper" +This command opens a series of commands on the console that will ask the user +to input metadata about the current file. This is used by the paper manager +module of ranger and can be later displayed in ranger, for example by setting +the option \*(L"linemode\*(R" to \*(L"papertitle\*(R". +.IP "paper_authors \fIauthors\fR" 2 +.IX Item "paper_authors authors" +Tells the paper manager to set/update the authors of the current file +.IP "paper_title \fItitle\fR" 2 +.IX Item "paper_title title" +Tells the paper manager to set/update the title of the current file +.IP "paper_url \fIurl\fR" 2 +.IX Item "paper_url url" +Tells the paper manager to set/update the url of the current file +.IP "paper_year \fIyear\fR" 2 +.IX Item "paper_year year" +Tells the paper manager to set/update the year of the current file .IP "pmap \fIkey\fR \fIcommand\fR" 2 .IX Item "pmap key command" Binds keys for the pager. Works like the \f(CW\*(C`map\*(C'\fR command. diff --git a/doc/ranger.pod b/doc/ranger.pod index 370bbb85..43003380 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -674,6 +674,12 @@ How many directory changes should be kept in history? Enable mouse input? +=item papermanager_deep_search [bool] + +When the paper manager module looks for metadata, should it only look for a +".paperinfo" file in the current directory, or do a deep search and check all +directories above the current one as well? + =item padding_right [bool] When collapse_preview is on and there is no preview, should there remain a @@ -813,18 +819,25 @@ ranger. For your convenience, this is a list of the "public" commands including copypmap key newkey [newkey2...] copytmap key newkey [newkey2...] cunmap keys... + default_linemode [path=regexp | tag=tags] linemodename delete edit [filename] eval [-q] python_code filter [string] find pattern grep pattern + linemode linemodename load_copy_buffer map key command mark pattern mark_tag [tags] mkdir dirname open_with [application] [flags] [mode] + paper + paper_authors [authors] + paper_title [title] + paper_url [url] + paper_year [year] pmap key command punmap keys... quit @@ -927,6 +940,21 @@ See C<copymap> Removes key mappings of the console. Works like the C<unmap> command. +=item default_linemode [I<path=regexp> | I<tag=tags>] I<linemodename> + +Sets the default linemode. See I<linemode> command. + +Examples: + +Set the global default linemode to "permissions": + :default_linemode permissions + +Set the default linemode to "permissions" for all files tagged with "p" or "P": + :default_linemode tag=pP permissions + +Set the default linemode for all files in ~/books/ to "papertitle": + :default_linemode path=/home/.*?/books/.* papertitle + =item delete Destroy all files in the selection with a roundhouse kick. ranger will ask for @@ -967,6 +995,15 @@ This command is based on the I<scout> command and supports all of its options. Looks for a string in all marked files or directories. +=item linemode I<linemodename> + +Sets the linemode of all files in the current directory. The linemode may be: + + "filename": display each line as "<basename>...<size>" + "permissions": display each line as "<permissions> <owner> <group> <basename>" + "papertitle": display metadata from .paperinfo files if available, fall back + to the "filename" linemode if no metadata was found. See :paper commands. + =item load_copy_buffer Load the copy buffer from F<~/.config/ranger/copy_buffer>. This can be used to @@ -1009,6 +1046,29 @@ displayed when pressing "r" in ranger. Note that if you specify an application, the mode is ignored. +=item paper + +This command opens a series of commands on the console that will ask the user +to input metadata about the current file. This is used by the paper manager +module of ranger and can be later displayed in ranger, for example by setting +the option "linemode" to "papertitle". + +=item paper_authors I<authors> + +Tells the paper manager to set/update the authors of the current file + +=item paper_title I<title> + +Tells the paper manager to set/update the title of the current file + +=item paper_url I<url> + +Tells the paper manager to set/update the url of the current file + +=item paper_year I<year> + +Tells the paper manager to set/update the year of the current file + =item pmap I<key> I<command> Binds keys for the pager. Works like the C<map> command. diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index 9514c55f..12fd2a32 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -174,8 +174,9 @@ set show_selection_in_titlebar true # increases CPU load. set idle_delay 2000 -# In the paper manger mode, should ranger try to find the ".paperinfo" file in -# directories above the current directory? +# When the paper manager module looks for metadata, should it only look for a +# ".paperinfo" file in the current directory, or do a deep search and check all +# directories above the current one as well? set papermanager_deep_search false # =================================================================== -- cgit 1.4.1-2-gfad0 From 8e0e465774d541181f27cd9e92a79ed01c84d115 Mon Sep 17 00:00:00 2001 From: hut <hut@lepus.uberspace.de> Date: Fri, 5 Dec 2014 01:44:16 +0100 Subject: doc/ranger.1: document M* keybindings --- doc/ranger.1 | 5 +++++ doc/ranger.pod | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/doc/ranger.1 b/doc/ranger.1 index 5b245dd8..27de2aa9 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -539,6 +539,11 @@ Go to the next or previous tab. You can also use \s-1TAB\s0 and \s-1SHIFT+TAB\s0 .IP "gc, ^W" 14 .IX Item "gc, ^W" Close the current tab. The last tab cannot be closed this way. +.IP "M" 14 +.IX Item "M" +A key chain that allows you to quickly change the line mode of all the files of +the current directory. For a more permanent solution, use the command +\&\*(L"default_linemode\*(R" in your rc.conf. .SS "READLINE-LIKE \s-1BINDINGS IN THE CONSOLE\s0" .IX Subsection "READLINE-LIKE BINDINGS IN THE CONSOLE" .IP "^B, ^F" 14 diff --git a/doc/ranger.pod b/doc/ranger.pod index 43003380..7a6de447 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -490,6 +490,12 @@ Go to the next or previous tab. You can also use TAB and SHIFT+TAB instead. Close the current tab. The last tab cannot be closed this way. +=item M + +A key chain that allows you to quickly change the line mode of all the files of +the current directory. For a more permanent solution, use the command +"default_linemode" in your rc.conf. + =back =head2 READLINE-LIKE BINDINGS IN THE CONSOLE -- cgit 1.4.1-2-gfad0