diff options
-rw-r--r-- | .pylintrc | 2 | ||||
-rw-r--r-- | Makefile | 25 | ||||
-rw-r--r-- | doc/ranger.1 | 14 | ||||
-rw-r--r-- | doc/ranger.pod | 9 | ||||
-rw-r--r-- | doc/rifle.1 | 6 | ||||
-rw-r--r-- | doc/rifle.pod | 4 | ||||
-rw-r--r-- | examples/rifle_different_file_opener.conf | 4 | ||||
-rw-r--r-- | ranger/config/.pylintrc | 2 | ||||
-rwxr-xr-x | ranger/config/commands.py | 31 | ||||
-rw-r--r-- | ranger/config/rc.conf | 4 | ||||
-rw-r--r-- | ranger/config/rifle.conf | 47 | ||||
-rw-r--r-- | ranger/container/settings.py | 13 | ||||
-rw-r--r-- | ranger/core/actions.py | 2 | ||||
-rw-r--r-- | ranger/ext/img_display.py | 2 | ||||
-rw-r--r-- | ranger/gui/color.py | 36 | ||||
-rw-r--r-- | ranger/gui/widgets/statusbar.py | 8 | ||||
-rw-r--r-- | ranger/gui/widgets/view_multipane.py | 102 | ||||
-rw-r--r-- | tests/pylint/test_py2_compat.py | 12 |
18 files changed, 238 insertions, 85 deletions
diff --git a/.pylintrc b/.pylintrc index 3fdcbaa8..994ddf62 100644 --- a/.pylintrc +++ b/.pylintrc @@ -13,7 +13,7 @@ max-branches=16 [FORMAT] max-line-length = 99 enable=no-absolute-import,old-division -disable=cyclic-import,duplicate-code,fixme,import-outside-toplevel,locally-disabled,locally-enabled,missing-docstring,no-else-break,no-else-continue,no-else-raise,no-else-return,redefined-variable-type,stop-iteration-return,useless-object-inheritance +disable=cyclic-import,duplicate-code,fixme,import-outside-toplevel,locally-disabled,locally-enabled,missing-docstring,no-else-break,no-else-continue,no-else-raise,no-else-return,raise-missing-from,redefined-variable-type,stop-iteration-return,super-with-arguments,useless-object-inheritance [TYPECHECK] ignored-classes=ranger.core.actions.Actions diff --git a/Makefile b/Makefile index 82a6153a..0cb35bd4 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,9 @@ FILTER ?= . CWD = $(shell pwd) +bold := $(shell tput bold) +normal := $(shell tput sgr0) + default: test compile @echo 'Run `make options` for a list of all options' @@ -91,39 +94,45 @@ TEST_PATHS_MAIN = \ TEST_PATH_CONFIG = ./ranger/config test_pylint: - @echo "Running pylint..." + @echo "$(bold)Running pylint...$(normal)" pylint $(TEST_PATHS_MAIN) pylint --rcfile=$(TEST_PATH_CONFIG)/.pylintrc $(TEST_PATH_CONFIG) test_flake8: - @echo "Running flake8..." + @echo "$(bold)Running flake8...$(normal)" flake8 $(TEST_PATHS_MAIN) $(TEST_PATH_CONFIG) + @echo test_doctest: - @echo "Running doctests..." + @echo "$(bold)Running doctests...$(normal)" @set -e; \ for FILE in $(shell grep -IHm 1 doctest -r ranger | grep $(FILTER) | cut -d: -f1); do \ echo "Testing $$FILE..."; \ RANGER_DOCTEST=1 PYTHONPATH=".:"$$PYTHONPATH ${PYTHON} $$FILE; \ done + @echo test_pytest: - @echo "Running py.test tests..." + @echo "$(bold)Running py.test tests...$(normal)" py.test tests + @echo test_py: test_pylint test_flake8 test_doctest test_pytest test_other - @echo "Finished python and documentation tests!" + @echo "$(bold)Finished python and documentation tests!$(normal)" + @echo test_shellcheck: - @echo "Running shellcheck..." + @echo "$(bold)Running shellcheck...$(normal)" sed '2,$$s/^\(\s*\)#/\1/' ./ranger/data/scope.sh | shellcheck -a - + @echo test_other: - @echo "Checking completeness of man page..." + @echo "$(bold)Checking completeness of man page...$(normal)" @tests/manpage_completion_test.py + @echo test: test_py test_shellcheck - @echo "Finished testing: All tests passed!" + @echo "$(bold)Finished testing: All tests passed!$(normal)" doc/ranger.1: doc/ranger.pod README.md pod2man --stderr --center='ranger manual' \ diff --git a/doc/ranger.1 b/doc/ranger.1 index 50d6bb0f..f675da91 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35) +.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "RANGER 1" -.TH RANGER 1 "ranger-1.9.3" "2020-02-22" "ranger manual" +.TH RANGER 1 "ranger-1.9.3" "2020-11-18" "ranger manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -974,6 +974,16 @@ Draw borders around or between the columns? Possible values are: \& separators draw only vertical lines between columns \& both both of the above .Ve +.IP "draw_borders_multipane [string]" 4 +.IX Item "draw_borders_multipane [string]" +Draw borders around or between the panes. This setting overrides +\&\fIdraw_borders\fR specifically for the multipane viewmode in case you want +different border styles in both viewmodes. There's one additional legal value +on top of those for \fIdraw_borders\fR: +.Sp +.Vb 1 +\& active\-pane draw an outline around the active pane only +.Ve .IP "draw_progress_bar_in_status_bar [bool]" 4 .IX Item "draw_progress_bar_in_status_bar [bool]" Draw a progress bar in the status bar which displays the average state of all diff --git a/doc/ranger.pod b/doc/ranger.pod index 3f41467d..bbdfd24e 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -1026,6 +1026,15 @@ Draw borders around or between the columns? Possible values are: separators draw only vertical lines between columns both both of the above +=item draw_borders_multipane [string] + +Draw borders around or between the panes. This setting overrides +I<draw_borders> specifically for the multipane viewmode in case you want +different border styles in both viewmodes. There's one additional legal value +on top of those for I<draw_borders>: + + active-pane draw an outline around the active pane only + =item draw_progress_bar_in_status_bar [bool] Draw a progress bar in the status bar which displays the average state of all diff --git a/doc/rifle.1 b/doc/rifle.1 index b3dd6373..6b676162 100644 --- a/doc/rifle.1 +++ b/doc/rifle.1 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "RIFLE 1" -.TH RIFLE 1 "rifle-1.9.3" "2020-02-08" "rifle manual" +.TH RIFLE 1 "rifle-1.9.3" "2020-11-08" "rifle manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -216,8 +216,8 @@ List all the different methods: .PP .Vb 4 \& $ rifle \-l helloworld.py -\& 0:editor::"$EDITOR" \-\- "$@" -\& 1:pager::"$PAGER" \-\- "$@" +\& 0:editor::$EDITOR \-\- "$@" +\& 1:pager::$PAGER \-\- "$@" \& 2:::python \-\- "$1" .Ve .PP diff --git a/doc/rifle.pod b/doc/rifle.pod index e0abaa3b..0cd34478 100644 --- a/doc/rifle.pod +++ b/doc/rifle.pod @@ -117,8 +117,8 @@ Specifies the directory for configuration files. Defaults to F<$HOME/.config>. List all the different methods: $ rifle -l helloworld.py - 0:editor::"$EDITOR" -- "$@" - 1:pager::"$PAGER" -- "$@" + 0:editor::$EDITOR -- "$@" + 1:pager::$PAGER -- "$@" 2:::python -- "$1" Display its content by opening it with "cat": diff --git a/examples/rifle_different_file_opener.conf b/examples/rifle_different_file_opener.conf index 695f27c6..b806b820 100644 --- a/examples/rifle_different_file_opener.conf +++ b/examples/rifle_different_file_opener.conf @@ -5,5 +5,5 @@ else = xdg-open "$1" # You need an "editor" and "pager" in order to use certain functions in ranger: -label editor = "$EDITOR" -- "$@" -label pager = "$PAGER" -- "$@" +label editor = $EDITOR -- "$@" +label pager = $PAGER -- "$@" diff --git a/ranger/config/.pylintrc b/ranger/config/.pylintrc index cc79f97c..316bf189 100644 --- a/ranger/config/.pylintrc +++ b/ranger/config/.pylintrc @@ -5,4 +5,4 @@ class-rgx=[a-z][a-z0-9_]{1,30}$ [FORMAT] max-line-length = 99 max-module-lines=3000 -disable=duplicate-code,fixme,import-outside-toplevel,locally-disabled,locally-enabled,missing-docstring,no-else-return +disable=duplicate-code,fixme,import-outside-toplevel,locally-disabled,locally-enabled,missing-docstring,no-else-return,super-with-arguments diff --git a/ranger/config/commands.py b/ranger/config/commands.py index b7b02e73..9031e7a2 100755 --- a/ranger/config/commands.py +++ b/ranger/config/commands.py @@ -1465,22 +1465,21 @@ class scout(Command): Multiple flags can be combined. For example, ":scout -gpt" would create a :filter-like command using globbing. """ - # pylint: disable=bad-whitespace - AUTO_OPEN = 'a' - OPEN_ON_ENTER = 'e' - FILTER = 'f' - SM_GLOB = 'g' - IGNORE_CASE = 'i' - KEEP_OPEN = 'k' - SM_LETTERSKIP = 'l' - MARK = 'm' - UNMARK = 'M' - PERM_FILTER = 'p' - SM_REGEX = 'r' - SMART_CASE = 's' - AS_YOU_TYPE = 't' - INVERT = 'v' - # pylint: enable=bad-whitespace + + AUTO_OPEN = "a" + OPEN_ON_ENTER = "e" + FILTER = "f" + SM_GLOB = "g" + IGNORE_CASE = "i" + KEEP_OPEN = "k" + SM_LETTERSKIP = "l" + MARK = "m" + UNMARK = "M" + PERM_FILTER = "p" + SM_REGEX = "r" + SMART_CASE = "s" + AS_YOU_TYPE = "t" + INVERT = "v" def __init__(self, *args, **kwargs): super(scout, self).__init__(*args, **kwargs) diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index e1ed1b73..d7d79f97 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -627,13 +627,13 @@ eval for arg in "rwxXst": cmd("map +u{0} shell -f chmod u+{0} %s".format(arg)) eval for arg in "rwxXst": cmd("map +g{0} shell -f chmod g+{0} %s".format(arg)) eval for arg in "rwxXst": cmd("map +o{0} shell -f chmod o+{0} %s".format(arg)) eval for arg in "rwxXst": cmd("map +a{0} shell -f chmod a+{0} %s".format(arg)) -eval for arg in "rwxXst": cmd("map +{0} shell -f chmod u+{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map +{0} shell -f chmod +{0} %s".format(arg)) eval for arg in "rwxXst": cmd("map -u{0} shell -f chmod u-{0} %s".format(arg)) eval for arg in "rwxXst": cmd("map -g{0} shell -f chmod g-{0} %s".format(arg)) eval for arg in "rwxXst": cmd("map -o{0} shell -f chmod o-{0} %s".format(arg)) eval for arg in "rwxXst": cmd("map -a{0} shell -f chmod a-{0} %s".format(arg)) -eval for arg in "rwxXst": cmd("map -{0} shell -f chmod u-{0} %s".format(arg)) +eval for arg in "rwxXst": cmd("map -{0} shell -f chmod -{0} %s".format(arg)) # =================================================================== # == Define keys for the console diff --git a/ranger/config/rifle.conf b/ranger/config/rifle.conf index 8e2a7a40..c9834224 100644 --- a/ranger/config/rifle.conf +++ b/ranger/config/rifle.conf @@ -86,15 +86,15 @@ ext x?html?, has w3m, terminal = w3m "$@" #------------------------------------------- # Define the "editor" for text files as first action mime ^text, label editor = ${VISUAL:-$EDITOR} -- "$@" -mime ^text, label pager = "$PAGER" -- "$@" +mime ^text, label pager = $PAGER -- "$@" !mime ^text, label editor, ext xml|json|csv|tex|py|pl|rb|rs|js|sh|php = ${VISUAL:-$EDITOR} -- "$@" -!mime ^text, label pager, ext xml|json|csv|tex|py|pl|rb|rs|js|sh|php = "$PAGER" -- "$@" +!mime ^text, label pager, ext xml|json|csv|tex|py|pl|rb|rs|js|sh|php = $PAGER -- "$@" ext 1 = man "$1" ext s[wmf]c, has zsnes, X = zsnes "$1" ext s[wmf]c, has snes9x-gtk,X = snes9x-gtk "$1" ext nes, has fceux, X = fceux "$1" -ext exe = wine "$1" +ext exe, has wine = wine "$1" name ^[mM]akefile$ = make #-------------------------------------------- @@ -118,17 +118,19 @@ ext midi?, terminal, has wildmidi = wildmidi -- "$@" #-------------------------------------------- # Video/Audio with a GUI #------------------------------------------- -mime ^video|audio, has gmplayer, X, flag f = gmplayer -- "$@" -mime ^video|audio, has smplayer, X, flag f = smplayer "$@" -mime ^video, has mpv, X, flag f = mpv -- "$@" -mime ^video, has mpv, X, flag f = mpv --fs -- "$@" -mime ^video, has mplayer2, X, flag f = mplayer2 -- "$@" -mime ^video, has mplayer2, X, flag f = mplayer2 -fs -- "$@" -mime ^video, has mplayer, X, flag f = mplayer -- "$@" -mime ^video, has mplayer, X, flag f = mplayer -fs -- "$@" -mime ^video|audio, has vlc, X, flag f = vlc -- "$@" -mime ^video|audio, has totem, X, flag f = totem -- "$@" -mime ^video|audio, has totem, X, flag f = totem --fullscreen -- "$@" +mime ^video|^audio, has gmplayer, X, flag f = gmplayer -- "$@" +mime ^video|^audio, has smplayer, X, flag f = smplayer "$@" +mime ^video, has mpv, X, flag f = mpv -- "$@" +mime ^video, has mpv, X, flag f = mpv --fs -- "$@" +mime ^video, has mplayer2, X, flag f = mplayer2 -- "$@" +mime ^video, has mplayer2, X, flag f = mplayer2 -fs -- "$@" +mime ^video, has mplayer, X, flag f = mplayer -- "$@" +mime ^video, has mplayer, X, flag f = mplayer -fs -- "$@" +mime ^video|^audio, has vlc, X, flag f = vlc -- "$@" +mime ^video|^audio, has totem, X, flag f = totem -- "$@" +mime ^video|^audio, has totem, X, flag f = totem --fullscreen -- "$@" +mime ^audio, has audacity, X, flag f = audacity -- "$@" +ext aup, has audacity, X, flag f = audacity -- "$@" #-------------------------------------------- # Video without X @@ -153,7 +155,8 @@ ext pdf, has epdfview, X, flag f = epdfview -- "$@" ext pdf, has qpdfview, X, flag f = qpdfview "$@" ext pdf, has open, X, flag f = open "$@" -ext docx?, has catdoc, terminal = catdoc -- "$@" | "$PAGER" +ext sc, has sc, = sc -- "$@" +ext docx?, has catdoc, terminal = catdoc -- "$@" | $PAGER ext sxc|xlsx?|xlt|xlw|gnm|gnumeric, has gnumeric, X, flag f = gnumeric -- "$@" ext sxc|xlsx?|xlt|xlw|gnm|gnumeric, has kspread, X, flag f = kspread -- "$@" @@ -174,6 +177,8 @@ ext mobi, has ebook-viewer, X, flag f = ebook-viewer -- "$@" ext cbr, has zathura, X, flag f = zathura -- "$@" ext cbz, has zathura, X, flag f = zathura -- "$@" +ext sla, has scribus, X, flag f = scribus -- "$@" + #------------------------------------------- # Images #------------------------------------------- @@ -193,6 +198,8 @@ mime ^image, has geeqie, X, flag f = geeqie -- "$@" mime ^image, has gpicview, X, flag f = gpicview -- "$@" mime ^image, has gwenview, X, flag f = gwenview -- "$@" mime ^image, has gimp, X, flag f = gimp -- "$@" +mime ^image, has krita, X, flag f = krita -- "$@" +ext kra, has krita, X, flag f = krita -- "$@" ext xcf, X, flag f = gimp -- "$@" #------------------------------------------- @@ -200,15 +207,15 @@ ext xcf, X, flag f = gimp -- "$@" #------------------------------------------- # avoid password prompt by providing empty password -ext 7z, has 7z = 7z -p l "$@" | "$PAGER" +ext 7z, has 7z = 7z -p l "$@" | $PAGER # This requires atool -ext ace|ar|arc|bz2?|cab|cpio|cpt|deb|dgc|dmg|gz, has atool = atool --list --each -- "$@" | "$PAGER" -ext iso|jar|msi|pkg|rar|shar|tar|tgz|xar|xpi|xz|zip, has atool = atool --list --each -- "$@" | "$PAGER" +ext ace|ar|arc|bz2?|cab|cpio|cpt|deb|dgc|dmg|gz, has atool = atool --list --each -- "$@" | $PAGER +ext iso|jar|msi|pkg|rar|shar|tar|tgz|xar|xpi|xz|zip, has atool = atool --list --each -- "$@" | $PAGER ext 7z|ace|ar|arc|bz2?|cab|cpio|cpt|deb|dgc|dmg|gz, has atool = atool --extract --each -- "$@" ext iso|jar|msi|pkg|rar|shar|tar|tgz|xar|xpi|xz|zip, has atool = atool --extract --each -- "$@" # Listing and extracting archives without atool: -ext tar|gz|bz2|xz, has tar = tar vvtf "$1" | "$PAGER" +ext tar|gz|bz2|xz, has tar = tar vvtf "$1" | $PAGER ext tar|gz|bz2|xz, has tar = for file in "$@"; do tar vvxf "$file"; done ext bz2, has bzip2 = for file in "$@"; do bzip2 -dk "$file"; done ext zip, has unzip = unzip -l "$1" | less @@ -268,7 +275,7 @@ label open, has open = open -- "$@" # Define the editor for non-text files + pager as last action !mime ^text, !ext xml|json|csv|tex|py|pl|rb|rs|js|sh|php = ask label editor, !mime ^text, !ext xml|json|csv|tex|py|pl|rb|rs|js|sh|php = ${VISUAL:-$EDITOR} -- "$@" -label pager, !mime ^text, !ext xml|json|csv|tex|py|pl|rb|rs|js|sh|php = "$PAGER" -- "$@" +label pager, !mime ^text, !ext xml|json|csv|tex|py|pl|rb|rs|js|sh|php = $PAGER -- "$@" ###################################################################### diff --git a/ranger/container/settings.py b/ranger/container/settings.py index 7549325a..e7d6775d 100644 --- a/ranger/container/settings.py +++ b/ranger/container/settings.py @@ -14,13 +14,11 @@ from ranger.gui.colorscheme import _colorscheme_name_to_class # Use these priority constants to trigger events at specific points in time # during processing of the signals "setopt" and "setopt.<some_setting_name>" -# pylint: disable=bad-whitespace -SIGNAL_PRIORITY_RAW = 2.0 # signal.value will be raw -SIGNAL_PRIORITY_SANITIZE = 1.0 # (Internal) post-processing signal.value -SIGNAL_PRIORITY_BETWEEN = 0.6 # sanitized signal.value, old fm.settings.XYZ -SIGNAL_PRIORITY_SYNC = 0.2 # (Internal) updating fm.settings.XYZ +SIGNAL_PRIORITY_RAW = 2.0 # signal.value will be raw +SIGNAL_PRIORITY_SANITIZE = 1.0 # (Internal) post-processing signal.value +SIGNAL_PRIORITY_BETWEEN = 0.6 # sanitized signal.value, old fm.settings.XYZ +SIGNAL_PRIORITY_SYNC = 0.2 # (Internal) updating fm.settings.XYZ SIGNAL_PRIORITY_AFTER_SYNC = 0.1 # after fm.settings.XYZ was updated -# pylint: enable=bad-whitespace ALLOWED_SETTINGS = { @@ -42,6 +40,7 @@ ALLOWED_SETTINGS = { "display_free_space_in_status_bar": bool, 'display_tags_in_all_columns': bool, 'draw_borders': str, + 'draw_borders_multipane': str, 'draw_progress_bar_in_status_bar': bool, 'flushinput': bool, 'freeze_files': bool, @@ -107,6 +106,8 @@ ALLOWED_VALUES = { 'cd_tab_case': ['sensitive', 'insensitive', 'smart'], 'confirm_on_delete': ['multiple', 'always', 'never'], 'draw_borders': ['none', 'both', 'outline', 'separators'], + 'draw_borders_multipane': [None, 'none', 'both', 'outline', + 'separators', 'active-pane'], 'line_numbers': ['false', 'absolute', 'relative'], 'nested_ranger_warning': ['true', 'false', 'error'], 'one_indexed': [False, True], diff --git a/ranger/core/actions.py b/ranger/core/actions.py index ba31db58..adfbe94d 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -1025,7 +1025,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m inode = stat(path).st_ino inode_path = "{0}{1}".format(str(inode), path) if PY3: - inode_path = inode_path.encode('utf-8', 'backslashescape') + inode_path = inode_path.encode('utf-8', 'backslashreplace') return '{0}.jpg'.format(sha512(inode_path).hexdigest()) def get_preview(self, fobj, width, height): diff --git a/ranger/ext/img_display.py b/ranger/ext/img_display.py index f056db3b..b738f458 100644 --- a/ranger/ext/img_display.py +++ b/ranger/ext/img_display.py @@ -683,7 +683,7 @@ class KittyImageDisplayer(ImageDisplayer, FileManagerAware): self.stdbout.flush() # kitty doesn't seem to reply on deletes, checking like we do in draw() # will slows down scrolling with timeouts from select - self.image_id -= 1 + self.image_id = max(0, self.image_id - 1) self.fm.ui.win.redrawwin() self.fm.ui.win.refresh() diff --git a/ranger/gui/color.py b/ranger/gui/color.py index 8f6439c7..81d8b44b 100644 --- a/ranger/gui/color.py +++ b/ranger/gui/color.py @@ -49,27 +49,27 @@ def get_color(fg, bg): return COLOR_PAIRS[key] -# pylint: disable=invalid-name,bad-whitespace -black = curses.COLOR_BLACK -blue = curses.COLOR_BLUE -cyan = curses.COLOR_CYAN -green = curses.COLOR_GREEN -magenta = curses.COLOR_MAGENTA -red = curses.COLOR_RED -white = curses.COLOR_WHITE -yellow = curses.COLOR_YELLOW -default = -1 - -normal = curses.A_NORMAL -bold = curses.A_BOLD -blink = curses.A_BLINK -reverse = curses.A_REVERSE -underline = curses.A_UNDERLINE -invisible = curses.A_INVIS +# pylint: disable=invalid-name +black = curses.COLOR_BLACK +blue = curses.COLOR_BLUE +cyan = curses.COLOR_CYAN +green = curses.COLOR_GREEN +magenta = curses.COLOR_MAGENTA +red = curses.COLOR_RED +white = curses.COLOR_WHITE +yellow = curses.COLOR_YELLOW +default = -1 + +normal = curses.A_NORMAL +bold = curses.A_BOLD +blink = curses.A_BLINK +reverse = curses.A_REVERSE +underline = curses.A_UNDERLINE +invisible = curses.A_INVIS dim = curses.A_DIM default_colors = (default, default, normal) -# pylint: enable=invalid-name,bad-whitespace +# pylint: enable=invalid-name curses.setupterm() # Adding BRIGHT to a color achieves what `bold` was used for. diff --git a/ranger/gui/widgets/statusbar.py b/ranger/gui/widgets/statusbar.py index fd44613e..4873c07a 100644 --- a/ranger/gui/widgets/statusbar.py +++ b/ranger/gui/widgets/statusbar.py @@ -42,6 +42,8 @@ class StatusBar(Widget): # pylint: disable=too-many-instance-attributes self.column = column self.settings.signal_bind('setopt.display_size_in_status_bar', self.request_redraw, weak=True) + self.fm.signal_bind('tab.layoutchange', self.request_redraw, weak=True) + self.fm.signal_bind('setop.viewmode', self.request_redraw, weak=True) def request_redraw(self): self.need_redraw = True @@ -52,9 +54,13 @@ class StatusBar(Widget): # pylint: disable=too-many-instance-attributes def clear_message(self): self.msg = None - def draw(self): + def draw(self): # pylint: disable=too-many-branches """Draw the statusbar""" + if self.column != self.fm.ui.browser.main_column: + self.column = self.fm.ui.browser.main_column + self.need_redraw = True + if self.hint and isinstance(self.hint, str): if self.old_hint != self.hint: self.need_redraw = True diff --git a/ranger/gui/widgets/view_multipane.py b/ranger/gui/widgets/view_multipane.py index 9661d31e..cef8d9a8 100644 --- a/ranger/gui/widgets/view_multipane.py +++ b/ranger/gui/widgets/view_multipane.py @@ -3,6 +3,7 @@ from __future__ import (absolute_import, division, print_function) +import curses from ranger.gui.widgets.view_base import ViewBase from ranger.gui.widgets.browsercolumn import BrowserColumn @@ -16,6 +17,17 @@ class ViewMultipane(ViewBase): # pylint: disable=too-many-ancestors self.fm.signal_bind('tab.change', self._tabchange_handler) self.rebuild() + self.old_draw_borders = self._draw_borders_setting() + + def _draw_borders_setting(self): + # If draw_borders_multipane has not been set, it defaults to `None` + # and we fallback to using draw_borders. Important to note: + # `None` is different from the string "none" referring to no borders + if self.settings.draw_borders_multipane is not None: + return self.settings.draw_borders_multipane + else: + return self.settings.draw_borders + def _layoutchange_handler(self): if self.fm.ui.browser == self: self.rebuild() @@ -43,13 +55,101 @@ class ViewMultipane(ViewBase): # pylint: disable=too-many-ancestors self.add_child(column) self.resize(self.y, self.x, self.hei, self.wid) + def draw(self): + if self.need_clear: + self.win.erase() + self.need_redraw = True + self.need_clear = False + + ViewBase.draw(self) + + if self._draw_borders_setting(): + draw_borders = self._draw_borders_setting() + if draw_borders in ['both', 'true']: # 'true' for backwards compat. + border_types = ['separators', 'outline'] + else: + border_types = [draw_borders] + self._draw_borders(border_types) + if self.draw_bookmarks: + self._draw_bookmarks() + elif self.draw_hints: + self._draw_hints() + elif self.draw_info: + self._draw_info(self.draw_info) + + def _draw_border_rectangle(self, left_start, right_end): + win = self.win + win.hline(0, left_start, curses.ACS_HLINE, right_end - left_start) + win.hline(self.hei - 1, left_start, curses.ACS_HLINE, right_end - left_start) + win.vline(1, left_start, curses.ACS_VLINE, self.hei - 2) + win.vline(1, right_end, curses.ACS_VLINE, self.hei - 2) + # Draw the four corners + self.addch(0, left_start, curses.ACS_ULCORNER) + self.addch(self.hei - 1, left_start, curses.ACS_LLCORNER) + self.addch(0, right_end, curses.ACS_URCORNER) + self.addch(self.hei - 1, right_end, curses.ACS_LRCORNER) + + def _draw_borders(self, border_types): + # Referenced from ranger.gui.widgets.view_miller + win = self.win + self.color('in_browser', 'border') + + left_start = 0 + right_end = self.wid - 1 + + # Draw the outline borders + if 'active-pane' not in border_types: + if 'outline' in border_types: + try: + self._draw_border_rectangle(left_start, right_end) + except curses.error: + pass + + # Draw the column separators + if 'separators' in border_types: + for child in self.columns[:-1]: + x = child.x + child.wid + y = self.hei - 1 + try: + win.vline(1, x, curses.ACS_VLINE, y - 1) + if 'outline' in border_types: + self.addch(0, x, curses.ACS_TTEE, 0) + self.addch(y, x, curses.ACS_BTEE, 0) + else: + self.addch(0, x, curses.ACS_VLINE, 0) + self.addch(y, x, curses.ACS_VLINE, 0) + except curses.error: + pass + else: + bordered_column = self.main_column + left_start = max(bordered_column.x, 0) + right_end = min(left_start + bordered_column.wid, self.wid - 1) + try: + self._draw_border_rectangle(left_start, right_end) + except curses.error: + pass + def resize(self, y, x, hei=None, wid=None): ViewBase.resize(self, y, x, hei, wid) + + border_type = self._draw_borders_setting() + if border_type in ['outline', 'both', 'true', 'active-pane']: + # 'true' for backwards compat., no height pad needed for 'separators' + pad = 1 + else: + pad = 0 column_width = int((wid - len(self.columns) + 1) / len(self.columns)) left = 0 top = 0 for column in self.columns: - column.resize(top, left, hei, max(1, column_width)) + column.resize(top + pad, left, hei - pad * 2, max(1, column_width)) left += column_width + 1 column.need_redraw = True self.need_redraw = True + + def poke(self): + ViewBase.poke(self) + + if self.old_draw_borders != self._draw_borders_setting(): + self.resize(self.y, self.x, self.hei, self.wid) + self.old_draw_borders = self._draw_borders_setting() diff --git a/tests/pylint/test_py2_compat.py b/tests/pylint/test_py2_compat.py index a5d2e284..bd1ace65 100644 --- a/tests/pylint/test_py2_compat.py +++ b/tests/pylint/test_py2_compat.py @@ -5,6 +5,9 @@ import py2_compat import astroid import pylint.testutils +from sys import version_info +PY2 = version_info[0] < 3 + class TestPy2CompatibilityChecker(pylint.testutils.CheckerTestCase): CHECKER_CLASS = py2_compat.Py2CompatibilityChecker @@ -42,6 +45,9 @@ class TestPy2CompatibilityChecker(pylint.testutils.CheckerTestCase): self.checker.visit_classdef(from_new) def test_print_without_import(self): + if PY2: + return + print_function_call = astroid.extract_node(""" print("Print function call without importing print_function") """) @@ -73,6 +79,9 @@ class TestPy2CompatibilityChecker(pylint.testutils.CheckerTestCase): self.checker.visit_call(nested_print_function_call) def test_print_late_import(self): + if PY2: + return + early_print_function_call = astroid.extract_node(""" print("Nested print with import in scope") #@ def f(): @@ -91,6 +100,9 @@ class TestPy2CompatibilityChecker(pylint.testutils.CheckerTestCase): self.checker.visit_call(early_print_function_call) def test_implicit_format_spec(self): + if PY2: + return + implicit_format_spec = astroid.extract_node(""" "{}".format("implicit") #@ """) |