Fix documentation for threaded segments

This commit is contained in:
ZyX 2013-03-17 20:20:21 +04:00
parent ce65470ac3
commit 19b45e609a
5 changed files with 157 additions and 112 deletions

View File

@ -3,9 +3,10 @@
import os
import sys
sys.path.insert(0, os.path.abspath('../..'))
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(os.getcwd()))))
sys.path.insert(0, os.path.abspath(os.getcwd()))
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.viewcode']
extensions = ['powerline_autodoc', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.viewcode']
source_suffix = '.rst'
master_doc = 'index'
project = u'Powerline'

View File

@ -0,0 +1,56 @@
from sphinx.ext import autodoc
from sphinx.util.inspect import getargspec
from inspect import ArgSpec, getargspec, formatargspec
from powerline.lib.threaded import ThreadedSegment, KwThreadedSegment
from itertools import count
class ThreadedDocumenter(autodoc.FunctionDocumenter):
'''Specialized documenter subclass for ThreadedSegment subclasses.'''
@classmethod
def can_document_member(cls, member, membername, isattr, parent):
return (isinstance(member, ThreadedSegment) or
super(ThreadedDocumenter, cls).can_document_member(member, membername, isattr, parent))
def format_args(self):
if isinstance(self.object, ThreadedSegment):
args = ['interval']
defaults = [getattr(self.object, 'interval', 1)]
methods = ['render', 'set_state']
if isinstance(self.object, KwThreadedSegment):
methods += ['key', 'render_one']
for method in methods:
if hasattr(self.object, method):
# Note: on <python-2.6 it may return simple tuple, not
# ArgSpec instance.
argspec = getargspec(getattr(self.object, method))
for i, arg in zip(count(-1, -1), reversed(argspec.args)):
if (arg == 'self' or
(arg == 'segment_info' and
getattr(self.object, 'requires_powerline_segment_info', None)) or
(method == 'render_one' and -i == len(argspec.args))):
continue
if argspec.defaults and len(argspec.defaults) >= -i:
default = argspec.defaults[i]
defaults.append(default)
args.append(arg)
else:
args.insert(0, arg)
argspec = ArgSpec(args=args, varargs=None, keywords=None, defaults=tuple(defaults))
else:
argspec = getargspec(self.object)
args = argspec.args
defaults = argspec.defaults
if args and args[0] == 'segment_info' and getattr(self.object, 'requires_powerline_segment_info', None):
args = args[1:]
if defaults and len(defaults) > len(args):
defaults = defaults[1:]
argspec = ArgSpec(args=args, varargs=argspec.varargs, keywords=argspec.keywords, defaults=defaults)
return formatargspec(*argspec).replace('\\', '\\\\')
def setup(app):
autodoc.setup(app)
app.add_autodocumenter(ThreadedDocumenter)

View File

@ -123,3 +123,8 @@ class KwThreadedSegment(ThreadedSegment):
@staticmethod
def render_one(update_state, **kwargs):
return update_state
def with_docstring(instance, doc):
instance.__doc__ = doc
return instance

View File

@ -12,7 +12,7 @@ from multiprocessing import cpu_count
from powerline.lib import add_divider_highlight_group
from powerline.lib.url import urllib_read, urllib_urlencode
from powerline.lib.vcs import guess
from powerline.lib.threaded import ThreadedSegment, KwThreadedSegment
from powerline.lib.threaded import ThreadedSegment, KwThreadedSegment, with_docstring
from powerline.lib.time import monotonic
from powerline.lib.humanize_bytes import humanize_bytes
from collections import namedtuple
@ -173,20 +173,6 @@ def _external_ip(query_url='http://ipv4.icanhazip.com/'):
class ExternalIpSegment(ThreadedSegment):
'''Return external IP address.
Suggested URIs:
* http://ipv4.icanhazip.com/
* http://ipv6.icanhazip.com/
* http://icanhazip.com/ (returns IPv6 address if available, else IPv4)
:param str query_url:
URI to query for IP address, should return only the IP address as a text string
Divider highlight group used: ``background:divider``.
'''
def set_state(self, query_url='http://ipv4.icanhazip.com/', **kwargs):
super(ExternalIpSegment, self).set_state(**kwargs)
self.query_url = query_url
@ -200,7 +186,20 @@ class ExternalIpSegment(ThreadedSegment):
return [{'contents': self.ip, 'divider_highlight_group': 'background:divider'}]
external_ip = ExternalIpSegment()
external_ip = with_docstring(ExternalIpSegment(),
'''Return external IP address.
Suggested URIs:
* http://ipv4.icanhazip.com/
* http://ipv6.icanhazip.com/
* http://icanhazip.com/ (returns IPv6 address if available, else IPv4)
:param str query_url:
URI to query for IP address, should return only the IP address as a text string
Divider highlight group used: ``background:divider``.
''')
# Weather condition code descriptions available at
@ -293,30 +292,6 @@ temp_units = {
class WeatherSegment(ThreadedSegment):
'''Return weather from Yahoo! Weather.
Uses GeoIP lookup from http://freegeoip.net/ to automatically determine
your current location. This should be changed if you're in a VPN or if your
IP address is registered at another location.
Returns a list of colorized icon and temperature segments depending on
weather conditions.
:param str unit:
temperature unit, can be one of ``F``, ``C`` or ``K``
:param str location_query:
location query for your current location, e.g. ``oslo, norway``
:param dict icons:
dict for overriding default icons, e.g. ``{'heavy_snow' : u''}``
:param str temperature_format:
format string, receives ``temp`` as an argument. Should also hold unit.
Divider highlight group used: ``background:divider``.
Highlight groups used: ``weather_conditions`` or ``weather``, ``weather_temp_cold`` or ``weather_temp_hot`` or ``weather_temp`` or ``weather``.
Also uses ``weather_conditions_{condition}`` for all weather conditions supported by Yahoo.
'''
interval = 600
def set_state(self, location_query=None, **kwargs):
@ -395,7 +370,30 @@ class WeatherSegment(ThreadedSegment):
]
weather = WeatherSegment()
weather = with_docstring(WeatherSegment(),
'''Return weather from Yahoo! Weather.
Uses GeoIP lookup from http://freegeoip.net/ to automatically determine
your current location. This should be changed if you're in a VPN or if your
IP address is registered at another location.
Returns a list of colorized icon and temperature segments depending on
weather conditions.
:param str unit:
temperature unit, can be one of ``F``, ``C`` or ``K``
:param str location_query:
location query for your current location, e.g. ``oslo, norway``
:param dict icons:
dict for overriding default icons, e.g. ``{'heavy_snow' : u''}``
:param str temperature_format:
format string, receives ``temp`` as an argument. Should also hold unit.
Divider highlight group used: ``background:divider``.
Highlight groups used: ``weather_conditions`` or ``weather``, ``weather_temp_cold`` or ``weather_temp_hot`` or ``weather_temp`` or ``weather``.
Also uses ``weather_conditions_{condition}`` for all weather conditions supported by Yahoo.
''')
def system_load(format='{avg:.1f}', threshold_good=1, threshold_bad=2):
@ -552,22 +550,6 @@ def uptime(format='{days}d {hours:02d}h {minutes:02d}m'):
class NetworkLoadSegment(KwThreadedSegment):
'''Return the network load.
Uses the ``psutil`` module if available for multi-platform compatibility,
falls back to reading
:file:`/sys/class/net/{interface}/statistics/{rx,tx}_bytes`.
:param str interface:
network interface to measure
:param str suffix:
string appended to each load string
:param bool si_prefix:
use SI prefix, e.g. MB instead of MiB
:param str format:
format string, receives ``recv`` and ``sent`` as arguments
'''
interfaces = {}
@staticmethod
@ -611,7 +593,22 @@ class NetworkLoadSegment(KwThreadedSegment):
}]
network_load = NetworkLoadSegment()
network_load = with_docstring(NetworkLoadSegment(),
'''Return the network load.
Uses the ``psutil`` module if available for multi-platform compatibility,
falls back to reading
:file:`/sys/class/net/{interface}/statistics/{rx,tx}_bytes`.
:param str interface:
network interface to measure
:param str suffix:
string appended to each load string
:param bool si_prefix:
use SI prefix, e.g. MB instead of MiB
:param str format:
format string, receives ``recv`` and ``sent`` as arguments
''')
def virtualenv():
@ -619,31 +616,15 @@ def virtualenv():
return os.path.basename(os.environ.get('VIRTUAL_ENV', '')) or None
IMAPKey = namedtuple('Key', 'username password server port folder')
_IMAPKey = namedtuple('Key', 'username password server port folder')
class EmailIMAPSegment(KwThreadedSegment):
'''Return unread e-mail count for IMAP servers.
:param str username:
login username
:param str password:
login password
:param str server:
e-mail server
:param int port:
e-mail server port
:param str folder:
folder to check for e-mails
Highlight groups used: ``email_alert``.
'''
interval = 60
@staticmethod
def key(username, password, server='imap.gmail.com', port=993, folder='INBOX'):
return IMAPKey(username, password, server, port, folder)
return _IMAPKey(username, password, server, port, folder)
@staticmethod
def compute_state(key):
@ -669,7 +650,22 @@ class EmailIMAPSegment(KwThreadedSegment):
}]
email_imap_alert = EmailIMAPSegment()
email_imap_alert = with_docstring(EmailIMAPSegment(),
'''Return unread e-mail count for IMAP servers.
:param str username:
login username
:param str password:
login password
:param str server:
e-mail server
:param int port:
e-mail server port
:param str folder:
folder to check for e-mails
Highlight groups used: ``email_alert``.
''')
class NowPlayingSegment(object):

View File

@ -13,7 +13,7 @@ from powerline.theme import requires_segment_info
from powerline.lib import add_divider_highlight_group
from powerline.lib.vcs import guess
from powerline.lib.humanize_bytes import humanize_bytes
from powerline.lib.threaded import KwThreadedSegment
from powerline.lib.threaded import KwThreadedSegment, with_docstring
from functools import wraps
from collections import defaultdict
@ -77,28 +77,18 @@ def launchevent(event):
pass
def bufnr(segment_info, **kwargs):
'''Used for cache key, returns current buffer number'''
return segment_info['bufnr']
def bufname(segment_info, **kwargs):
'''Used for cache key, returns current buffer name'''
return segment_info['buffer'].name
# TODO Remove cache when needed
def window_cached(func):
cache = {}
@requires_segment_info
@wraps(func)
def ret(segment_info, *args, **kwargs):
def ret(segment_info, **kwargs):
window_id = segment_info['window_id']
if segment_info['mode'] == 'nc':
return cache.get(window_id)
else:
r = func(*args, **kwargs)
r = func(**kwargs)
cache[window_id] = r
return r
@ -348,8 +338,6 @@ class RepositorySegment(KwWindowThreadedSegment):
@requires_segment_info
class RepositoryStatusSegment(RepositorySegment):
'''Return the status for the current repo.'''
interval = 2
@staticmethod
@ -357,21 +345,12 @@ class RepositoryStatusSegment(RepositorySegment):
return repo.status()
repository_status = RepositoryStatusSegment()
repository_status = with_docstring(RepositoryStatusSegment(),
'''Return the status for the current repo.''')
@requires_segment_info
class BranchSegment(RepositorySegment):
'''Return the current working branch.
:param bool status_colors:
determines whether repository status will be used to determine highlighting. Default: False.
Highlight groups used: ``branch_clean``, ``branch_dirty``, ``branch``.
Divider highlight group used: ``branch:divider``.
'''
interval = 0.2
started_repository_status = False
@ -405,16 +384,20 @@ class BranchSegment(RepositorySegment):
super(BranchSegment, self).shutdown()
branch = BranchSegment()
branch = with_docstring(BranchSegment(),
'''Return the current working branch.
:param bool status_colors:
determines whether repository status will be used to determine highlighting. Default: False.
Highlight groups used: ``branch_clean``, ``branch_dirty``, ``branch``.
Divider highlight group used: ``branch:divider``.
''')
@requires_segment_info
class FileVCSStatusSegment(KwWindowThreadedSegment):
'''Return the VCS status for this buffer.
Highlight groups used: ``file_vcs_status``.
'''
interval = 0.2
@staticmethod
@ -443,4 +426,8 @@ class FileVCSStatusSegment(KwWindowThreadedSegment):
return None
file_vcs_status = FileVCSStatusSegment()
file_vcs_status = with_docstring(FileVCSStatusSegment(),
'''Return the VCS status for this buffer.
Highlight groups used: ``file_vcs_status``.
''')