summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortoonn <toonn@toonn.io>2021-01-05 18:52:25 +0100
committertoonn <toonn@toonn.io>2021-01-05 18:52:25 +0100
commit790d90853504f62e9449844a6481f3955190e35d (patch)
treebaf6c8c4eca175ab0da304c840285bfdbaa4ee09
parent7a0d077e4545f18d30488122fee80ba4df1c7b52 (diff)
parent6fd49695111232df31358a67b11dc5ee3b8dbcfc (diff)
Merge branch 'chu4ng-fix-files-index' into fix-files-none
-rw-r--r--.pylintrc2
-rw-r--r--Makefile25
-rw-r--r--doc/ranger.114
-rw-r--r--doc/ranger.pod9
-rw-r--r--doc/rifle.16
-rw-r--r--doc/rifle.pod4
-rw-r--r--examples/rifle_different_file_opener.conf4
-rw-r--r--ranger/config/.pylintrc2
-rwxr-xr-xranger/config/commands.py31
-rw-r--r--ranger/config/rc.conf4
-rw-r--r--ranger/config/rifle.conf47
-rw-r--r--ranger/container/settings.py13
-rw-r--r--ranger/core/actions.py2
-rw-r--r--ranger/core/tab.py2
-rw-r--r--ranger/ext/img_display.py2
-rw-r--r--ranger/gui/color.py36
-rw-r--r--ranger/gui/widgets/statusbar.py8
-rw-r--r--ranger/gui/widgets/view_multipane.py102
-rw-r--r--tests/pylint/test_py2_compat.py12
19 files changed, 240 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/core/tab.py b/ranger/core/tab.py
index 1771ffa2..b61a77cc 100644
--- a/ranger/core/tab.py
+++ b/ranger/core/tab.py
@@ -73,6 +73,8 @@ class Tab(FileManagerAware, SettingsAware): # pylint: disable=too-many-instance
self._pointed_obj = self.thisdir.files[self._pointer]
except TypeError:
pass
+ except IndexError:
+ pass
pointer = property(_get_pointer, _set_pointer)
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") #@
""")