Allow EvMore text argument to be a list

This commit is contained in:
Griatch 2020-01-10 17:56:45 +01:00
parent 716a0b20e3
commit b5aee2c41e
3 changed files with 33 additions and 13 deletions

View file

@ -32,8 +32,10 @@ without arguments starts a full interactive Python console.
- Make code auto-formatted with Black. - Make code auto-formatted with Black.
- Make default `set` command able to edit nested structures (PR by Aaron McMillan) - Make default `set` command able to edit nested structures (PR by Aaron McMillan)
- Allow running Evennia test suite from core repo with `make test`. - Allow running Evennia test suite from core repo with `make test`.
- Return `store_key` from `TickerHandler.add` and add `store_key` as a kwarg to - Return `store_key` from `TickerHandler.add` and add `store_key` as a kwarg to
the `TickerHandler.remove` method. This makes it easier to manage tickers. the `TickerHandler.remove` method. This makes it easier to manage tickers.
- EvMore `text` argument can now also be a list - each entry in the list is run
through str(eval()) and ends up on its own line. Good for paginated object lists.
## Evennia 0.9 (2018-2019) ## Evennia 0.9 (2018-2019)

View file

@ -233,6 +233,7 @@ def _init():
from . import contrib from . import contrib
from .utils.evmenu import EvMenu from .utils.evmenu import EvMenu
from .utils.evtable import EvTable from .utils.evtable import EvTable
from .utils.evmore import EvMore
from .utils.evform import EvForm from .utils.evform import EvForm
from .utils.eveditor import EvEditor from .utils.eveditor import EvEditor
from .utils.ansi import ANSIString from .utils.ansi import ANSIString

View file

@ -30,7 +30,7 @@ caller.msg() construct every time the page is updated.
from django.conf import settings from django.conf import settings
from evennia import Command, CmdSet from evennia import Command, CmdSet
from evennia.commands import cmdhandler from evennia.commands import cmdhandler
from evennia.utils.utils import justify from evennia.utils.utils import justify, make_iter
_CMD_NOMATCH = cmdhandler.CMD_NOMATCH _CMD_NOMATCH = cmdhandler.CMD_NOMATCH
_CMD_NOINPUT = cmdhandler.CMD_NOINPUT _CMD_NOINPUT = cmdhandler.CMD_NOINPUT
@ -149,7 +149,9 @@ class EvMore(object):
Args: Args:
caller (Object or Account): Entity reading the text. caller (Object or Account): Entity reading the text.
text (str): The text to put under paging. text (str or iterator): The text to put under paging. If an iterator,
each iteration step is expected to be a line in the final display,
and each line will be run through repr().
always_page (bool, optional): If `False`, the always_page (bool, optional): If `False`, the
pager will only kick in if `text` is too big pager will only kick in if `text` is too big
to fit the screen. to fit the screen.
@ -170,12 +172,21 @@ class EvMore(object):
kwargs (any, optional): These will be passed on kwargs (any, optional): These will be passed on
to the `caller.msg` method. to the `caller.msg` method.
Examples:
super_long_text = " ... "
EvMore(caller, super_long_text)
from django.core.paginator import Paginator
query = ObjectDB.objects.all()
pages = Paginator(query, 10) # 10 objs per page
EvMore(caller, pages) # will repr() each object per line, 10 to a page
""" """
self._caller = caller self._caller = caller
self._kwargs = kwargs self._kwargs = kwargs
self._pages = [] self._pages = []
self._npages = [] self._npages = 1
self._npos = [] self._npos = 0
self.exit_on_lastpage = exit_on_lastpage self.exit_on_lastpage = exit_on_lastpage
self.exit_cmd = exit_cmd self.exit_cmd = exit_cmd
self._exit_msg = "Exited |wmore|n pager." self._exit_msg = "Exited |wmore|n pager."
@ -194,6 +205,12 @@ class EvMore(object):
) )
width = session.protocol_flags.get("SCREENWIDTH", {0: _SCREEN_WIDTH})[0] width = session.protocol_flags.get("SCREENWIDTH", {0: _SCREEN_WIDTH})[0]
# analyze text
if not isinstance(text, str):
# not a string - pre-set pages of some form
text = "\n".join(str(repr(element)) for element in make_iter(text))
# the normal case - a string we need to manually split.
if "\f" in text: if "\f" in text:
self._pages = text.split("\f") self._pages = text.split("\f")
self._npages = len(self._pages) self._npages = len(self._pages)
@ -242,7 +259,7 @@ class EvMore(object):
""" """
Pretty-print the page. Pretty-print the page.
""" """
pos = self._pos pos = self._npos
text = self._pages[pos] text = self._pages[pos]
if show_footer: if show_footer:
page = _DISPLAY.format(text=text, pageno=pos + 1, pagemax=self._npages) page = _DISPLAY.format(text=text, pageno=pos + 1, pagemax=self._npages)
@ -262,14 +279,14 @@ class EvMore(object):
""" """
Display the top page Display the top page
""" """
self._pos = 0 self._npos = 0
self.display() self.display()
def page_end(self): def page_end(self):
""" """
Display the bottom page. Display the bottom page.
""" """
self._pos = self._npages - 1 self._npos = self._npages - 1
self.display() self.display()
def page_next(self): def page_next(self):
@ -277,12 +294,12 @@ class EvMore(object):
Scroll the text to the next page. Quit if already at the end Scroll the text to the next page. Quit if already at the end
of the page. of the page.
""" """
if self._pos >= self._npages - 1: if self._npos >= self._npages - 1:
# exit if we are already at the end # exit if we are already at the end
self.page_quit() self.page_quit()
else: else:
self._pos += 1 self._npos += 1
if self.exit_on_lastpage and self._pos >= (self._npages - 1): if self.exit_on_lastpage and self._npos >= (self._npages - 1):
self.display(show_footer=False) self.display(show_footer=False)
self.page_quit(quiet=True) self.page_quit(quiet=True)
else: else:
@ -292,7 +309,7 @@ class EvMore(object):
""" """
Scroll the text back up, at the most to the top. Scroll the text back up, at the most to the top.
""" """
self._pos = max(0, self._pos - 1) self._npos = max(0, self._npos - 1)
self.display() self.display()
def page_quit(self, quiet=False): def page_quit(self, quiet=False):