Fixing a few edge cases
This commit is contained in:
13
rtv/page.py
13
rtv/page.py
@@ -11,7 +11,6 @@ import six
|
|||||||
from kitchen.text.display import textual_width
|
from kitchen.text.display import textual_width
|
||||||
|
|
||||||
from . import docs
|
from . import docs
|
||||||
from .theme import get_next_theme, get_previous_theme
|
|
||||||
from .objects import Controller, Command
|
from .objects import Controller, Command
|
||||||
from .clipboard import copy
|
from .clipboard import copy
|
||||||
from .exceptions import TemporaryFileError, ProgramError
|
from .exceptions import TemporaryFileError, ProgramError
|
||||||
@@ -98,7 +97,11 @@ class Page(object):
|
|||||||
|
|
||||||
@PageController.register(Command('PREVIOUS_THEME'))
|
@PageController.register(Command('PREVIOUS_THEME'))
|
||||||
def previous_theme(self):
|
def previous_theme(self):
|
||||||
theme = get_previous_theme(self.term.theme)
|
|
||||||
|
theme = self.term.theme_list.previous(self.term.theme)
|
||||||
|
while not self.term.test_theme(theme):
|
||||||
|
theme = self.term.theme_list.previous(theme)
|
||||||
|
|
||||||
self.term.set_theme(theme)
|
self.term.set_theme(theme)
|
||||||
self.draw()
|
self.draw()
|
||||||
message = self.term.theme.display_string
|
message = self.term.theme.display_string
|
||||||
@@ -106,7 +109,11 @@ class Page(object):
|
|||||||
|
|
||||||
@PageController.register(Command('NEXT_THEME'))
|
@PageController.register(Command('NEXT_THEME'))
|
||||||
def next_theme(self):
|
def next_theme(self):
|
||||||
theme = get_next_theme(self.term.theme)
|
|
||||||
|
theme = self.term.theme_list.next(self.term.theme)
|
||||||
|
while not self.term.test_theme(theme):
|
||||||
|
theme = self.term.theme_list.next(theme)
|
||||||
|
|
||||||
self.term.set_theme(theme)
|
self.term.set_theme(theme)
|
||||||
self.draw()
|
self.draw()
|
||||||
message = self.term.theme.display_string
|
message = self.term.theme.display_string
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import six
|
|||||||
from kitchen.text.display import textual_width_chop
|
from kitchen.text.display import textual_width_chop
|
||||||
|
|
||||||
from . import exceptions, mime_parsers
|
from . import exceptions, mime_parsers
|
||||||
from .theme import Theme
|
from .theme import Theme, ThemeList
|
||||||
from .objects import LoadScreen
|
from .objects import LoadScreen
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -57,6 +57,7 @@ class Terminal(object):
|
|||||||
self.config = config
|
self.config = config
|
||||||
self.loader = LoadScreen(self)
|
self.loader = LoadScreen(self)
|
||||||
self.theme = None # Initialized by term.set_theme()
|
self.theme = None # Initialized by term.set_theme()
|
||||||
|
self.theme_list = ThemeList()
|
||||||
|
|
||||||
self._display = None
|
self._display = None
|
||||||
self._mailcap_dict = mailcap.getcaps()
|
self._mailcap_dict = mailcap.getcaps()
|
||||||
@@ -829,6 +830,20 @@ class Terminal(object):
|
|||||||
|
|
||||||
return self.theme.get(element)
|
return self.theme.get(element)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def test_theme(theme):
|
||||||
|
"""
|
||||||
|
Check if the given theme is supported by the terminal
|
||||||
|
"""
|
||||||
|
terminal_colors = curses.COLORS if curses.has_colors() else 0
|
||||||
|
|
||||||
|
if theme.required_colors > terminal_colors:
|
||||||
|
return False
|
||||||
|
elif theme.required_color_pairs > curses.COLOR_PAIRS:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
def set_theme(self, theme=None):
|
def set_theme(self, theme=None):
|
||||||
"""
|
"""
|
||||||
Check that the terminal supports the provided theme, and applies
|
Check that the terminal supports the provided theme, and applies
|
||||||
@@ -839,10 +854,7 @@ class Terminal(object):
|
|||||||
should be compatible with any terminal that supports basic colors.
|
should be compatible with any terminal that supports basic colors.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if curses.has_colors():
|
terminal_colors = curses.COLORS if curses.has_colors() else 0
|
||||||
terminal_colors = curses.COLORS
|
|
||||||
else:
|
|
||||||
terminal_colors = 0
|
|
||||||
|
|
||||||
if theme is None:
|
if theme is None:
|
||||||
theme = Theme(use_color=bool(terminal_colors))
|
theme = Theme(use_color=bool(terminal_colors))
|
||||||
|
|||||||
33
rtv/theme.py
33
rtv/theme.py
@@ -50,8 +50,6 @@ class Theme(object):
|
|||||||
for i in range(256):
|
for i in range(256):
|
||||||
COLOR_CODES['ansi_{0}'.format(i)] = i
|
COLOR_CODES['ansi_{0}'.format(i)] = i
|
||||||
|
|
||||||
# TODO: Apply selected on top of items, not underneath them
|
|
||||||
|
|
||||||
# For compatibility with as many terminals as possible, the default theme
|
# For compatibility with as many terminals as possible, the default theme
|
||||||
# can only use the 8 basic colors with the default color as the background
|
# can only use the 8 basic colors with the default color as the background
|
||||||
DEFAULT_THEME = {
|
DEFAULT_THEME = {
|
||||||
@@ -159,26 +157,28 @@ class Theme(object):
|
|||||||
elements[key] = (None, None, None)
|
elements[key] = (None, None, None)
|
||||||
|
|
||||||
self._set_fallback(elements, 'Normal', (-1, -1, curses.A_NORMAL))
|
self._set_fallback(elements, 'Normal', (-1, -1, curses.A_NORMAL))
|
||||||
self._set_fallback(elements, 'Selected', 'Normal')
|
|
||||||
self._set_fallback(elements, 'SelectedCursor', 'Normal')
|
|
||||||
|
|
||||||
# Most elements have two possible attribute states:
|
# Fill in the ``None`` values for all of the elements with normal text
|
||||||
# 1. The default state - inherits from "Normal"
|
|
||||||
# 2. The selected state - inherits from "Selected" and is
|
|
||||||
# prefixed by the "@" sign.
|
|
||||||
for name in self.DEFAULT_THEME['normal']:
|
for name in self.DEFAULT_THEME['normal']:
|
||||||
dest = '@{0}'.format(name)
|
|
||||||
self._set_fallback(elements, name, 'Selected', dest)
|
|
||||||
self._set_fallback(elements, name, 'Normal')
|
self._set_fallback(elements, name, 'Normal')
|
||||||
|
|
||||||
for name in self.DEFAULT_THEME['cursor']:
|
for name in self.DEFAULT_THEME['cursor']:
|
||||||
dest = '@{0}'.format(name)
|
|
||||||
self._set_fallback(elements, name, 'SelectedCursor', dest)
|
|
||||||
self._set_fallback(elements, name, 'Normal')
|
self._set_fallback(elements, name, 'Normal')
|
||||||
|
|
||||||
for name in self.DEFAULT_THEME['page']:
|
for name in self.DEFAULT_THEME['page']:
|
||||||
self._set_fallback(elements, name, 'Normal')
|
self._set_fallback(elements, name, 'Normal')
|
||||||
|
|
||||||
|
# Create the "Selected" versions of elements, which are prefixed with
|
||||||
|
# the @ symbol. For example, "@CommentText" represents how comment
|
||||||
|
# text is formatted when it is highlighted by the cursor.
|
||||||
|
for name in self.DEFAULT_THEME['normal']:
|
||||||
|
dest = '@{0}'.format(name)
|
||||||
|
self._set_fallback(elements, 'Selected', name, dest)
|
||||||
|
for name in self.DEFAULT_THEME['cursor']:
|
||||||
|
dest = '@{0}'.format(name)
|
||||||
|
self._set_fallback(elements, 'SelectedCursor', name, dest)
|
||||||
|
|
||||||
|
self._set_fallback(elements, 'Selected', 'Normal')
|
||||||
|
self._set_fallback(elements, 'SelectedCursor', 'Normal')
|
||||||
|
|
||||||
self.elements = elements
|
self.elements = elements
|
||||||
|
|
||||||
if self.use_color:
|
if self.use_color:
|
||||||
@@ -546,8 +546,3 @@ class ThemeList(object):
|
|||||||
|
|
||||||
def previous(self, theme):
|
def previous(self, theme):
|
||||||
return self._step(theme, -1)
|
return self._step(theme, -1)
|
||||||
|
|
||||||
|
|
||||||
theme_list = ThemeList()
|
|
||||||
get_next_theme = theme_list.next
|
|
||||||
get_previous_theme = theme_list.previous
|
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
[theme]
|
|
||||||
;<element> = <foreground> <background> <attributes>
|
|
||||||
Normal = default default -
|
|
||||||
Selected = - - -
|
|
||||||
SelectedCursor = - - reverse
|
|
||||||
|
|
||||||
TitleBar = cyan - bold+reverse
|
|
||||||
OrderBar = yellow - bold
|
|
||||||
OrderBarHighlight = yellow - bold+reverse
|
|
||||||
HelpBar = cyan - bold+reverse
|
|
||||||
Prompt = cyan - bold+reverse
|
|
||||||
NoticeInfo = - - bold
|
|
||||||
NoticeLoading = - - bold
|
|
||||||
NoticeError = - - bold
|
|
||||||
NoticeSuccess = - - bold
|
|
||||||
|
|
||||||
CursorBlock = - - -
|
|
||||||
CursorBar1 = magenta - -
|
|
||||||
CursorBar2 = cyan - -
|
|
||||||
CursorBar3 = green - -
|
|
||||||
CursorBar4 = yellow - -
|
|
||||||
|
|
||||||
CommentAuthor = cyan - bold
|
|
||||||
CommentAuthorSelf = green - bold
|
|
||||||
CommentCount = - - -
|
|
||||||
CommentText = - - -
|
|
||||||
Created = - - -
|
|
||||||
Downvote = red - bold
|
|
||||||
Gold = yellow - bold
|
|
||||||
HiddenCommentExpand = - - bold
|
|
||||||
HiddenCommentText = - - -
|
|
||||||
MultiredditName = yellow - bold
|
|
||||||
MultiredditText = - - -
|
|
||||||
NeutralVote = - - bold
|
|
||||||
NSFW = red - bold+reverse
|
|
||||||
Saved = green - -
|
|
||||||
Score = - - -
|
|
||||||
Separator = - - bold
|
|
||||||
Stickied = green - -
|
|
||||||
SubscriptionName = yellow - bold
|
|
||||||
SubscriptionText = - - -
|
|
||||||
SubmissionAuthor = green - bold
|
|
||||||
SubmissionFlair = red - -
|
|
||||||
SubmissionSubreddit = yellow - -
|
|
||||||
SubmissionText = - - -
|
|
||||||
SubmissionTitle = - - bold
|
|
||||||
Upvote = green - bold
|
|
||||||
Link = cyan - underline
|
|
||||||
LinkSeen = magenta - underline
|
|
||||||
UserFlair = yellow - bold
|
|
||||||
@@ -15,7 +15,7 @@ from collections import Counter
|
|||||||
from vcr import VCR
|
from vcr import VCR
|
||||||
from six.moves.urllib.parse import urlparse, parse_qs
|
from six.moves.urllib.parse import urlparse, parse_qs
|
||||||
|
|
||||||
from rtv.theme import Theme, get_next_theme, get_previous_theme, theme_list
|
from rtv.theme import Theme, ThemeList
|
||||||
from rtv.config import Config
|
from rtv.config import Config
|
||||||
from rtv.packages import praw
|
from rtv.packages import praw
|
||||||
from rtv.oauth import OAuthHelper
|
from rtv.oauth import OAuthHelper
|
||||||
@@ -244,6 +244,8 @@ def main():
|
|||||||
oauth = OAuthHelper(reddit, term, config)
|
oauth = OAuthHelper(reddit, term, config)
|
||||||
oauth.authorize()
|
oauth.authorize()
|
||||||
|
|
||||||
|
theme_list = ThemeList()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
term = Terminal(stdscr, config)
|
term = Terminal(stdscr, config)
|
||||||
term.set_theme(theme)
|
term.set_theme(theme)
|
||||||
@@ -266,14 +268,15 @@ def main():
|
|||||||
theme_list.reload()
|
theme_list.reload()
|
||||||
|
|
||||||
if ch == curses.KEY_RIGHT:
|
if ch == curses.KEY_RIGHT:
|
||||||
theme = get_next_theme(theme)
|
theme = theme_list.next(theme)
|
||||||
elif ch == curses.KEY_LEFT:
|
elif ch == curses.KEY_LEFT:
|
||||||
theme = get_previous_theme(theme)
|
theme = theme_list.previous(theme)
|
||||||
elif ch == Terminal.ESCAPE:
|
elif ch == Terminal.ESCAPE:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
# Force the theme to reload
|
# Force the theme to reload
|
||||||
theme = get_next_theme(theme)
|
theme = theme_list.next(theme)
|
||||||
theme = get_previous_theme(theme)
|
theme = theme_list.previous(theme)
|
||||||
|
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user