diff options
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | doc/howto-publish-a-release.md | 2 | ||||
-rw-r--r-- | doc/ranger.1 | 12 | ||||
-rw-r--r-- | doc/ranger.pod | 8 | ||||
-rw-r--r-- | doc/rifle.1 | 5 | ||||
-rw-r--r-- | doc/rifle.pod | 3 | ||||
-rwxr-xr-x | ranger/config/commands.py | 10 | ||||
-rw-r--r-- | ranger/config/rc.conf | 4 | ||||
-rw-r--r-- | ranger/config/rifle.conf | 14 | ||||
-rw-r--r-- | ranger/core/actions.py | 26 | ||||
-rw-r--r-- | ranger/core/filter_stack.py | 16 | ||||
-rw-r--r-- | ranger/core/main.py | 13 | ||||
-rw-r--r-- | ranger/core/tab.py | 8 | ||||
-rw-r--r-- | ranger/ext/img_display.py | 18 | ||||
-rw-r--r-- | ranger/gui/ui.py | 95 | ||||
-rwxr-xr-x | setup.py | 16 |
16 files changed, 145 insertions, 109 deletions
diff --git a/Makefile b/Makefile index d70728f6..82a6153a 100644 --- a/Makefile +++ b/Makefile @@ -8,9 +8,9 @@ VERSION_RIFLE = $(VERSION) SNAPSHOT_NAME ?= $(NAME)-$(VERSION)-$(shell git rev-parse HEAD | cut -b 1-8).tar.gz # Find suitable python version (need python >= 2.6 or 3.1): PYTHON ?= $(shell \ - (python -c 'import sys; sys.exit(sys.version < "2.6")' && \ + (which python3) \ + || (python -c 'import sys; sys.exit(sys.version < "2.6")' && \ which python) \ - || (which python3) \ || (python2 -c 'import sys; sys.exit(sys.version < "2.6")' && \ which python2) \ ) diff --git a/doc/howto-publish-a-release.md b/doc/howto-publish-a-release.md index 6bd70047..c62a1908 100644 --- a/doc/howto-publish-a-release.md +++ b/doc/howto-publish-a-release.md @@ -62,7 +62,7 @@ Update the website Make a PyPI release ------------------- * [ ] `git clean --force -d -x` -* [ ] `SETUPTOOLS_USE=1 python setup.py sdist` +* [ ] `python setup.py sdist` * [ ] `gpg --local-user 0x00000000 --detach-sign --armor dist/*` * [ ] `twine upload dist/*` diff --git a/doc/ranger.1 b/doc/ranger.1 index 57646fc7..50d6bb0f 100644 --- a/doc/ranger.1 +++ b/doc/ranger.1 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "RANGER 1" -.TH RANGER 1 "ranger-1.9.3" "2019-12-31" "ranger manual" +.TH RANGER 1 "ranger-1.9.3" "2020-02-22" "ranger manual" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -1731,9 +1731,9 @@ Creates an empty file with the name \fIfilename\fR, unless it already exists. .IX Item "trash" Move all files in the selection to the trash using rifle. Rifle tries to use a trash manager like \fItrash-cli\fR if available but will fall back to moving files -to either \fI\f(CI$XDG_DATA_HOME\fI/ranger\-trash\fR or \fI~/.ranger/ranger\-trash\fR. This is -a less permanent version of \fIdelete\fR, relying on the user to clear out the -trash whenever it's convenient. While having the possibility of restoring +to either \fI\f(CI$XDG_DATA_HOME\fI/ranger/trash\fR or \fI~/.local/share/ranger/trash\fR. +This is a less permanent version of \fIdelete\fR, relying on the user to clear out +the trash whenever it's convenient. While having the possibility of restoring trashed files until this happens. ranger will ask for a confirmation if you attempt to trash multiple (marked) files or non-empty directories. This can be changed by modifying the setting \*(L"confirm_on_delete\*(R". @@ -1869,8 +1869,8 @@ the \*(L"S\*(R" key. Defaults to \*(L"/bin/sh\*(R". .IX Item "TERMCMD" Defines the terminal emulator command that ranger is going to use with the :terminal command and the \*(L"t\*(R" run flag. Defaults to \*(L"xterm\*(R". -.IP "\s-1BAT_STYLE\s0" 8 -.IX Item "BAT_STYLE" +.IP "\s-1BAT_THEME\s0" 8 +.IX Item "BAT_THEME" Specifies the theme to be used for syntax highlighting when \fIbat\fR is installed, unless \fIhighlight\fR is also installed. Find out possible values by running \f(CW\*(C`bat \-\-list\-themes\*(C'\fR. diff --git a/doc/ranger.pod b/doc/ranger.pod index ed347665..3f41467d 100644 --- a/doc/ranger.pod +++ b/doc/ranger.pod @@ -1879,9 +1879,9 @@ Creates an empty file with the name I<filename>, unless it already exists. Move all files in the selection to the trash using rifle. Rifle tries to use a trash manager like I<trash-cli> if available but will fall back to moving files -to either F<$XDG_DATA_HOME/ranger-trash> or F<~/.ranger/ranger-trash>. This is -a less permanent version of I<delete>, relying on the user to clear out the -trash whenever it's convenient. While having the possibility of restoring +to either F<$XDG_DATA_HOME/ranger/trash> or F<~/.local/share/ranger/trash>. +This is a less permanent version of I<delete>, relying on the user to clear out +the trash whenever it's convenient. While having the possibility of restoring trashed files until this happens. ranger will ask for a confirmation if you attempt to trash multiple (marked) files or non-empty directories. This can be changed by modifying the setting "confirm_on_delete". @@ -2057,7 +2057,7 @@ the "S" key. Defaults to "/bin/sh". Defines the terminal emulator command that ranger is going to use with the :terminal command and the "t" run flag. Defaults to "xterm". -=item BAT_STYLE +=item BAT_THEME Specifies the theme to be used for syntax highlighting when I<bat> is installed, unless I<highlight> is also installed. Find out possible values by diff --git a/doc/rifle.1 b/doc/rifle.1 index 1d3553f4..b3dd6373 100644 --- a/doc/rifle.1 +++ b/doc/rifle.1 @@ -133,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "RIFLE 1" -.TH RIFLE 1 "rifle-1.9.3" "2019-12-31" "rifle manual" +.TH RIFLE 1 "rifle-1.9.3" "2020-02-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 @@ -185,7 +185,8 @@ Print a list of options and exit. rifle shares configuration files with ranger, though ranger is not required in order to use rifle. The default configuration file \fIrifle.conf\fR is expected to be at \fI~/.config/ranger/rifle.conf\fR. However, this can be overridden with -the \fB\-c\fR option. +the \fB\-c\fR option. Note that due to the nature of the configuration, rifle will +only read one file, it will not read the defaults in addition. .PP This file specifies patterns for determining the commands to open files with. The syntax is described in the comments of the default \fIrifle.conf\fR that ships diff --git a/doc/rifle.pod b/doc/rifle.pod index b4d76287..e0abaa3b 100644 --- a/doc/rifle.pod +++ b/doc/rifle.pod @@ -71,7 +71,8 @@ Print a list of options and exit. rifle shares configuration files with ranger, though ranger is not required in order to use rifle. The default configuration file F<rifle.conf> is expected to be at F<~/.config/ranger/rifle.conf>. However, this can be overridden with -the B<-c> option. +the B<-c> option. Note that due to the nature of the configuration, rifle will +only read one file, it will not read the defaults in addition. This file specifies patterns for determining the commands to open files with. The syntax is described in the comments of the default F<rifle.conf> that ships diff --git a/ranger/config/commands.py b/ranger/config/commands.py index 5defa677..7e244e6f 100755 --- a/ranger/config/commands.py +++ b/ranger/config/commands.py @@ -1124,6 +1124,12 @@ class bulkrename(Command): After you close it, it will be executed. """ + def __init__(self, *args, **kwargs): + super(bulkrename, self).__init__(*args, **kwargs) + self.flags, _ = self.parse_flags() + if not self.flags: + self.flags = "w" + def execute(self): # pylint: disable=too-many-locals,too-many-statements,too-many-branches import sys @@ -1184,7 +1190,7 @@ class bulkrename(Command): script_was_edited = (script_content != cmdfile.read()) # Do the renaming - self.fm.run(['/bin/sh', cmdfile.name], flags='w') + self.fm.run(['/bin/sh', cmdfile.name], flags=self.flags) # Retag the files, but only if the script wasn't changed during review, # because only then we know which are the source and destination files. @@ -1704,7 +1710,7 @@ class filter_stack(Command): return else: self.fm.notify( - "Unknown subcommand: {}".format(subcommand), + "Unknown subcommand: {sub}".format(sub=subcommand), bad=True ) return diff --git a/ranger/config/rc.conf b/ranger/config/rc.conf index 9d08a6a7..e1ed1b73 100644 --- a/ranger/config/rc.conf +++ b/ranger/config/rc.conf @@ -25,7 +25,6 @@ # multipane: Midnight-commander like multipane view showing all tabs next # to each other set viewmode miller -#set viewmode multipane # How many columns are there, and what are their relative widths? set column_ratios 1,3,4 @@ -334,6 +333,7 @@ alias qall! quitall! alias setl setlocal alias filter scout -prts +alias hide scout -prtsv alias find scout -aets alias mark scout -mr alias unmark scout -Mr @@ -620,7 +620,7 @@ map m<any> set_bookmark %any map um<any> unset_bookmark %any map m<bg> draw_bookmarks -copymap m<bg> um<bg> `<bg> '<bg> +copymap m<bg> um<bg> `<bg> '<bg> p`<bg> p'<bg> # Generate all the chmod bindings with some python help: eval for arg in "rwxXst": cmd("map +u{0} shell -f chmod u+{0} %s".format(arg)) diff --git a/ranger/config/rifle.conf b/ranger/config/rifle.conf index 0c821a37..8e2a7a40 100644 --- a/ranger/config/rifle.conf +++ b/ranger/config/rifle.conf @@ -87,8 +87,8 @@ 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 editor, ext xml|json|csv|tex|py|pl|rb|js|sh|php = ${VISUAL:-$EDITOR} -- "$@" -!mime ^text, label pager, ext xml|json|csv|tex|py|pl|rb|js|sh|php = "$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" -- "$@" ext 1 = man "$1" ext s[wmf]c, has zsnes, X = zsnes "$1" @@ -262,13 +262,13 @@ label wallpaper, number 14, mime ^image, has feh, X = feh --bg-fill "$1" #------------------------------------------- # Generic file openers #------------------------------------------- -label open, has xdg-open = xdg-open -- "$@" +label open, has xdg-open = xdg-open "$@" 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|js|sh|php = ask -label editor, !mime ^text, !ext xml|json|csv|tex|py|pl|rb|js|sh|php = ${VISUAL:-$EDITOR} -- "$@" -label pager, !mime ^text, !ext xml|json|csv|tex|py|pl|rb|js|sh|php = "$PAGER" -- "$@" + !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" -- "$@" ###################################################################### @@ -281,4 +281,4 @@ mime application/x-executable = "$1" # Move the file to trash using trash-cli. label trash, has trash-put = trash-put -- "$@" -label trash = mkdir -p -- ${XDG_DATA_DIR:-$HOME/.ranger}/ranger-trash; mv -- "$@" ${XDG_DATA_DIR:-$HOME/.ranger}/ranger-trash +label trash = mkdir -p -- "${XDG_DATA_HOME:-$HOME/.local/share}/ranger/trash"; mv -- "$@" "${XDG_DATA_HOME:-$HOME/.local/share}/ranger/trash" diff --git a/ranger/core/actions.py b/ranger/core/actions.py index c3d7de86..fe7d7e5e 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -16,8 +16,7 @@ import string import tempfile from inspect import cleandoc from stat import S_IEXEC -from hashlib import sha1 -from sys import version_info +from hashlib import sha512 from logging import getLogger import ranger @@ -35,7 +34,6 @@ from ranger.container.file import File from ranger.core.loader import CommandLoader, CopyLoader from ranger.container.settings import ALLOWED_SETTINGS, ALLOWED_VALUES - MACRO_FAIL = "<\x01\x01MACRO_HAS_NO_VALUE\x01\01>" LOG = getLogger(__name__) @@ -242,14 +240,14 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m if cmd.resolve_macros and _MacroTemplate.delimiter in cmd.line: def any_macro(i, char): - return ('any{:d}'.format(i), key_to_string(char)) + return ('any{0:d}'.format(i), key_to_string(char)) def anypath_macro(i, char): try: val = self.fm.bookmarks[key_to_string(char)] except KeyError: val = MACRO_FAIL - return ('any_path{:d}'.format(i), val) + return ('any_path{0:d}'.format(i), val) macros = dict(f(i, char) for f in (any_macro, anypath_macro) for i, char in enumerate(wildcards if wildcards @@ -1049,11 +1047,12 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m return True @staticmethod - def sha1_encode(path): - if version_info[0] < 3: - return os.path.join(ranger.args.cachedir, sha1(path).hexdigest()) + '.jpg' - return os.path.join(ranger.args.cachedir, - sha1(path.encode('utf-8', 'backslashreplace')).hexdigest()) + '.jpg' + def sha512_encode(path): + stat_ = stat(path) + sha = sha512(stat_.st_dev) + sha.update(stat_.st_ino) + sha.update(stat_.st_mtime) + return '{0}.jpg'.format(sha.hexdigest()) def get_preview(self, fobj, width, height): # pylint: disable=too-many-return-statements pager = self.ui.get_pager() @@ -1121,10 +1120,9 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m if not os.path.exists(ranger.args.cachedir): os.makedirs(ranger.args.cachedir) - cacheimg = os.path.join(ranger.args.cachedir, self.sha1_encode(path)) + cacheimg = os.path.join(ranger.args.cachedir, self.sha512_encode(path)) if self.settings.preview_images and \ - os.path.isfile(cacheimg) and \ - os.path.getmtime(cacheimg) > os.path.getmtime(path): + os.path.isfile(cacheimg): data['foundpreview'] = True data['imagepreview'] = True pager.set_image(cacheimg) @@ -1609,7 +1607,7 @@ class Actions( # pylint: disable=too-many-instance-attributes,too-many-public-m # COMPAT: old command.py use fm.delete() without arguments if files is None: files = (fobj.path for fobj in self.thistab.get_selection()) - self.notify("Deleting {}!".format(", ".join(files))) + self.notify("Deleting {fls}!".format(fls=", ".join(files))) files = [os.path.abspath(path) for path in files] for path in files: # Untag the deleted files. diff --git a/ranger/core/filter_stack.py b/ranger/core/filter_stack.py index bd63f2fe..58ce1a1c 100644 --- a/ranger/core/filter_stack.py +++ b/ranger/core/filter_stack.py @@ -55,7 +55,7 @@ class NameFilter(BaseFilter): return self.regex.search(fobj.relative_path) def __str__(self): - return "<Filter: name =~ /{}/>".format(self.pattern) + return "<Filter: name =~ /{pat}/>".format(pat=self.pattern) @stack_filter("mime") @@ -71,7 +71,7 @@ class MimeFilter(BaseFilter): return self.regex.search(mimetype) def __str__(self): - return "<Filter: mimetype =~ /{}/>".format(self.pattern) + return "<Filter: mimetype =~ /{pat}/>".format(pat=self.pattern) @stack_filter("hash") @@ -97,7 +97,7 @@ class HashFilter(BaseFilter, FileManagerAware): return True def __str__(self): - return "<Filter: hash {}>".format(self.filepath) + return "<Filter: hash {fp}>".format(fp=self.filepath) def group_by_hash(fsobjects): @@ -192,7 +192,7 @@ class TypeFilter(BaseFilter): return self.type_to_function[self.filetype](fobj) def __str__(self): - return "<Filter: type == '{}'>".format(self.filetype) + return "<Filter: type == '{ft}'>".format(ft=self.filetype) @filter_combinator("or") @@ -216,7 +216,8 @@ class OrFilter(BaseFilter): ) def __str__(self): - return "<Filter: {}>".format(" or ".join(map(str, self.subfilters))) + return "<Filter: {comp}>".format( + comp=" or ".join(map(str, self.subfilters))) def decompose(self): return self.subfilters @@ -236,7 +237,8 @@ class AndFilter(BaseFilter): return accept_file(fobj, self.subfilters) def __str__(self): - return "<Filter: {}>".format(" and ".join(map(str, self.subfilters))) + return "<Filter: {comp}>".format( + comp=" and ".join(map(str, self.subfilters))) def decompose(self): return self.subfilters @@ -252,7 +254,7 @@ class NotFilter(BaseFilter): return not self.subfilter(fobj) def __str__(self): - return "<Filter: not {}>".format(str(self.subfilter)) + return "<Filter: not {exp}>".format(exp=str(self.subfilter)) def decompose(self): return [self.subfilter] diff --git a/ranger/core/main.py b/ranger/core/main.py index 7322a501..b16b6318 100644 --- a/ranger/core/main.py +++ b/ranger/core/main.py @@ -6,8 +6,10 @@ from __future__ import (absolute_import, division, print_function) from logging import getLogger +import atexit import locale import os.path +import shutil import sys import tempfile @@ -337,6 +339,17 @@ def parse_arguments(): args.cachedir = mkdtemp(suffix='.ranger-cache') args.confdir = None args.datadir = None + + @atexit.register + def cleanup_cachedir(): # pylint: disable=unused-variable + try: + shutil.rmtree(args.cachedir) + except Exception as ex: # pylint: disable=broad-except + sys.stderr.write( + "Error during the temporary cache directory cleanup:\n" + "{ex}\n".format(ex=ex) + ) + else: args.cachedir = path_init('cachedir') args.confdir = path_init('confdir') diff --git a/ranger/core/tab.py b/ranger/core/tab.py index 1d5e69d4..7bb45d75 100644 --- a/ranger/core/tab.py +++ b/ranger/core/tab.py @@ -4,7 +4,7 @@ from __future__ import (absolute_import, division, print_function) import os -from os.path import abspath, normpath, join, expanduser, isdir +from os.path import abspath, normpath, join, expanduser, isdir, dirname import sys from ranger.container import settings @@ -123,9 +123,11 @@ class Tab(FileManagerAware, SettingsAware): # pylint: disable=too-many-instance # get the absolute path path = normpath(join(self.path, expanduser(path))) + selectfile = None if not isdir(path): - return False + selectfile = path + path = dirname(path) new_thisdir = self.fm.get_directory(path) try: @@ -155,6 +157,8 @@ class Tab(FileManagerAware, SettingsAware): # pylint: disable=too-many-instance self.thisdir.sort_directories_first = self.fm.settings.sort_directories_first self.thisdir.sort_reverse = self.fm.settings.sort_reverse self.thisdir.sort_if_outdated() + if selectfile: + self.thisdir.move_to_obj(selectfile) if previous and previous.path != path: self.thisfile = self.thisdir.pointed_obj else: diff --git a/ranger/ext/img_display.py b/ranger/ext/img_display.py index ffaa4c07..70983bc7 100644 --- a/ranger/ext/img_display.py +++ b/ranger/ext/img_display.py @@ -233,7 +233,7 @@ class W3MImageDisplayer(ImageDisplayer, FileManagerAware): # max_height_pixels = (max_height - 1) * fonth - 2 # get image size - cmd = "5;{}\n".format(path) + cmd = "5;{path}\n".format(path=path) self.process.stdin.write(cmd) self.process.stdin.flush() @@ -590,7 +590,7 @@ class KittyImageDisplayer(ImageDisplayer, FileManagerAware): self.stream = True else: raise ImgDisplayUnsupportedException( - 'kitty replied an unexpected response: {}'.format(resp)) + 'kitty replied an unexpected response: {r}'.format(r=resp)) # get the image manipulation backend try: @@ -616,7 +616,8 @@ class KittyImageDisplayer(ImageDisplayer, FileManagerAware): # a is the display command, with T going for immediate output # i is the id entifier for the image cmds = {'a': 'T', 'i': self.image_id} - # sys.stderr.write('{}-{}@{}x{}\t'.format(start_x, start_y, width, height)) + # sys.stderr.write('{0}-{1}@{2}x{3}\t'.format( + # start_x, start_y, width, height)) # finish initialization if it is the first call if self.needs_late_init: @@ -673,12 +674,13 @@ class KittyImageDisplayer(ImageDisplayer, FileManagerAware): if b'OK' in resp: return else: - raise ImageDisplayError('kitty replied "{}"'.format(resp)) + raise ImageDisplayError('kitty replied "{r}"'.format(r=resp)) def clear(self, start_x, start_y, width, height): # let's assume that every time ranger call this # it actually wants just to remove the previous image - # TODO: implement this using the actual x, y, since the protocol supports it + # TODO: implement this using the actual x, y, since the protocol + # supports it cmds = {'a': 'd', 'i': self.image_id} for cmd_str in self._format_cmd_str(cmds): self.stdbout.write(cmd_str) @@ -690,7 +692,8 @@ class KittyImageDisplayer(ImageDisplayer, FileManagerAware): self.fm.ui.win.refresh() def _format_cmd_str(self, cmd, payload=None, max_slice_len=2048): - central_blk = ','.join(["{}={}".format(k, v) for k, v in cmd.items()]).encode('ascii') + central_blk = ','.join(["{k}={v}".format(k=k, v=v) + for k, v in cmd.items()]).encode('ascii') if payload is not None: # we add the m key to signal a multiframe communication # appending the end (m=0) key to a single message has no effect @@ -706,7 +709,8 @@ class KittyImageDisplayer(ImageDisplayer, FileManagerAware): yield self.protocol_start + central_blk + b';' + self.protocol_end def quit(self): - # clear all remaining images, then check if all files went through or are orphaned + # clear all remaining images, then check if all files went through or + # are orphaned while self.image_id >= 1: self.clear(0, 0, 0, 0) # for k in self.temp_paths: diff --git a/ranger/gui/ui.py b/ranger/gui/ui.py index d2dbb759..a2ea7778 100644 --- a/ranger/gui/ui.py +++ b/ranger/gui/ui.py @@ -9,6 +9,7 @@ import threading import curses from subprocess import CalledProcessError +from ranger.ext.get_executables import get_executables from ranger.ext.keybinding_parser import KeyBuffer, KeyMaps, ALT_KEY from ranger.ext.lazy_property import lazy_property from ranger.ext.signals import Signal @@ -49,6 +50,16 @@ def _setup_mouse(signal): curses.mousemask(0) +def _in_tmux(): + return ('TMUX' in os.environ + and 'tmux' in get_executables()) + + +def _in_screen(): + return ('screen' in os.environ['TERM'] + and 'screen' in get_executables()) + + class UI( # pylint: disable=too-many-instance-attributes,too-many-public-methods DisplayableContainer): ALLOWED_VIEWMODES = 'miller', 'multipane' @@ -73,8 +84,7 @@ class UI( # pylint: disable=too-many-instance-attributes,too-many-public-method self.multiplexer = None self._draw_title = None self._tmux_automatic_rename = None - self._tmux_title = None - self._screen_title = None + self._multiplexer_title = None self.browser = None if fm is not None: @@ -469,58 +479,63 @@ class UI( # pylint: disable=too-many-instance-attributes,too-many-public-method # Handles window renaming behaviour of the terminal multiplexers # GNU Screen and Tmux def handle_multiplexer(self): - if self.settings.update_tmux_title: - if 'TMUX' in os.environ: - # Stores the automatic-rename setting - # prints out a warning if the allow-rename in tmux is not set - tmux_allow_rename = check_output( - ['tmux', 'show-window-options', '-v', - 'allow-rename']).strip() - if tmux_allow_rename == 'off': - self.fm.notify('Warning: allow-rename not set in Tmux!', - bad=True) - elif self._tmux_title is None: - self._tmux_title = check_output( - ['tmux', 'display-message', '-p', '#W']).strip() - else: + if (self.settings.update_tmux_title and not self._multiplexer_title): + try: + if _in_tmux(): + # Stores the automatic-rename setting + # prints out a warning if allow-rename isn't set in tmux try: + tmux_allow_rename = check_output( + ['tmux', 'show-window-options', '-v', + 'allow-rename']).strip() + except CalledProcessError: + tmux_allow_rename = 'off' + if tmux_allow_rename == 'off': + self.fm.notify('Warning: allow-rename not set in Tmux!', + bad=True) + else: + self._multiplexer_title = check_output( + ['tmux', 'display-message', '-p', '#W']).strip() self._tmux_automatic_rename = check_output( ['tmux', 'show-window-options', '-v', 'automatic-rename']).strip() if self._tmux_automatic_rename == 'on': check_output(['tmux', 'set-window-option', 'automatic-rename', 'off']) - except CalledProcessError: - pass - elif 'screen' in os.environ['TERM'] and self._screen_title is None: - # Stores the screen window name before renaming it - # gives out a warning if $TERM is not "screen" - try: - self._screen_title = check_output( + elif _in_screen(): + # Stores the screen window name before renaming it + # gives out a warning if $TERM is not "screen" + self._multiplexer_title = check_output( ['screen', '-Q', 'title']).strip() - except CalledProcessError: - self._screen_title = None + except CalledProcessError: + self.fm.notify("Couldn't access previous multiplexer window" + " name, won't be able to restore.", + bad=False) + if not self._multiplexer_title: + self._multiplexer_title = os.path.basename( + os.environ.get("SHELL", "shell")) sys.stdout.write("\033kranger\033\\") sys.stdout.flush() # Restore window name def restore_multiplexer_name(self): - try: - if 'TMUX' in os.environ: - if self._tmux_automatic_rename: - check_output(['tmux', 'set-window-option', - 'automatic-rename', - self._tmux_automatic_rename]) - else: - check_output(['tmux', 'set-window-option', '-u', - 'automatic-rename']) - if self._tmux_title: - check_output(['tmux', 'rename-window', self._tmux_title]) - elif 'screen' in os.environ['TERM'] and self._screen_title: - check_output(['screen', '-X', 'title', self._screen_title]) - except CalledProcessError: - self.fm.notify("Could not restore window-name!", bad=True) + if self._multiplexer_title: + try: + if _in_tmux(): + if self._tmux_automatic_rename: + check_output(['tmux', 'set-window-option', + 'automatic-rename', + self._tmux_automatic_rename]) + else: + check_output(['tmux', 'set-window-option', '-u', + 'automatic-rename']) + except CalledProcessError: + self.fm.notify("Could not restore multiplexer window name!", + bad=True) + + sys.stdout.write("\033k{}\033\\".format(self._multiplexer_title)) + sys.stdout.flush() def hint(self, text=None): self.status.hint = text diff --git a/setup.py b/setup.py index edf48c4a..493deadd 100755 --- a/setup.py +++ b/setup.py @@ -4,11 +4,13 @@ from __future__ import (absolute_import, division, print_function) -from distutils import log # pylint: disable=import-error,no-name-in-module from hashlib import sha512 import os import shutil +from setuptools import setup +from setuptools.command.install_lib import install_lib + import ranger @@ -16,16 +18,6 @@ SCRIPTS_PATH = 'build_scripts' EXECUTABLES_PATHS = ['/ranger/data/scope.sh'] -# pylint: disable=import-error,no-name-in-module,ungrouped-imports -if os.environ.get('SETUPTOOLS_USE'): - from setuptools import setup - from setuptools.command.install_lib import install_lib -else: - from distutils.core import setup - from distutils.command.install_lib import install_lib -# pylint: enable=import-error,no-name-in-module,ungrouped-imports - - def findall(directory): return [os.path.join(directory, f) for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f))] @@ -59,7 +51,7 @@ class InstallLib(install_lib): for exe_path in EXECUTABLES_PATHS: if path.endswith(exe_path): mode = ((os.stat(path).st_mode) | 0o555) & 0o7777 - log.info('changing mode of %s to %o', path, mode) + print('changing mode of %s to %o' % (path, mode)) os.chmod(path, mode) |