mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Merge branches 'new_options' and 'styles_options' into full_options
This commit is contained in:
commit
71108daa25
10 changed files with 197 additions and 23 deletions
|
|
@ -20,6 +20,7 @@ from django.utils.module_loading import import_string
|
|||
from evennia.typeclasses.models import TypeclassBase
|
||||
from evennia.accounts.manager import AccountManager
|
||||
from evennia.accounts.models import AccountDB
|
||||
from evennia.accounts.styles import StyleHandler
|
||||
from evennia.objects.models import ObjectDB
|
||||
from evennia.comms.models import ChannelDB
|
||||
from evennia.commands import cmdhandler
|
||||
|
|
@ -1383,6 +1384,10 @@ class DefaultAccount(with_metaclass(TypeclassBase, AccountDB)):
|
|||
look_string = ("-" * 68) + "\n" + "".join(result) + "\n" + ("-" * 68)
|
||||
return look_string
|
||||
|
||||
@lazy_property
|
||||
def style(self):
|
||||
return StyleHandler(self)
|
||||
|
||||
|
||||
class DefaultGuest(DefaultAccount):
|
||||
"""
|
||||
|
|
|
|||
36
evennia/accounts/styles.py
Normal file
36
evennia/accounts/styles.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
"""
|
||||
Styles (playing off CSS) are a way to change the colors and symbols used for standardized
|
||||
displays used in Evennia. Accounts all have a StyleHandler accessible via .style which
|
||||
retrieves per-Account settings, falling back to the global settings contained in settings.py.
|
||||
|
||||
"""
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
class StyleHandler(object):
|
||||
category = 'style'
|
||||
|
||||
def __init__(self, acc):
|
||||
self.acc = acc
|
||||
|
||||
def set(self, option, value):
|
||||
pass
|
||||
|
||||
def get(self, option):
|
||||
"""
|
||||
Get the stored Style information from this Account's Attributes if possible.
|
||||
If not, fallback to the Global.
|
||||
|
||||
Args:
|
||||
option (str): The key of the Style to retrieve.
|
||||
|
||||
Returns:
|
||||
String or None
|
||||
"""
|
||||
stored = self.acc.attributes.get(option, category=self.category)
|
||||
if stored:
|
||||
return stored
|
||||
default = settings.DEFAULT_STYLES.get(option, None)
|
||||
if default:
|
||||
return default[2]
|
||||
return None
|
||||
|
|
@ -367,7 +367,7 @@ class CmdSessions(COMMAND_DEFAULT_CLASS):
|
|||
"""Implement function"""
|
||||
account = self.account
|
||||
sessions = account.sessions.all()
|
||||
table = evtable.EvTable("|wsessid",
|
||||
table = self.style_table("|wsessid",
|
||||
"|wprotocol",
|
||||
"|whost",
|
||||
"|wpuppet/character",
|
||||
|
|
@ -418,7 +418,7 @@ class CmdWho(COMMAND_DEFAULT_CLASS):
|
|||
naccounts = (SESSIONS.account_count())
|
||||
if show_session_data:
|
||||
# privileged info
|
||||
table = evtable.EvTable("|wAccount Name",
|
||||
table = self.style_table("|wAccount Name",
|
||||
"|wOn for",
|
||||
"|wIdle",
|
||||
"|wPuppeting",
|
||||
|
|
@ -444,7 +444,7 @@ class CmdWho(COMMAND_DEFAULT_CLASS):
|
|||
isinstance(session.address, tuple) and session.address[0] or session.address)
|
||||
else:
|
||||
# unprivileged
|
||||
table = evtable.EvTable("|wAccount name", "|wOn for", "|wIdle")
|
||||
table = self.style_table("|wAccount name", "|wOn for", "|wIdle")
|
||||
for session in session_list:
|
||||
if not session.logged_in:
|
||||
continue
|
||||
|
|
@ -524,7 +524,7 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
|||
options.pop("TTYPE", None)
|
||||
|
||||
header = ("Name", "Value", "Saved") if saved_options else ("Name", "Value")
|
||||
table = evtable.EvTable(*header)
|
||||
table = self.style_table(*header)
|
||||
for key in sorted(options):
|
||||
row = [key, options[key]]
|
||||
if saved_options:
|
||||
|
|
@ -870,3 +870,19 @@ class CmdQuell(COMMAND_DEFAULT_CLASS):
|
|||
else:
|
||||
self.msg("Quelling Account permissions%s. Use @unquell to get them back." % permstr)
|
||||
self._recache_locks(account)
|
||||
|
||||
|
||||
class CmdStyle(COMMAND_DEFAULT_CLASS):
|
||||
key = "@style"
|
||||
switch_options = ['clear']
|
||||
|
||||
def func(self):
|
||||
if not self.args:
|
||||
self.list_styles()
|
||||
return
|
||||
|
||||
def list_styles(self):
|
||||
styles_table = self.style_table('Option', 'Description', 'Value')
|
||||
for k, v in settings.DEFAULT_STYLES.items():
|
||||
styles_table.add_row(k, v[0], v[2])
|
||||
self.msg(str(styles_table))
|
||||
|
|
@ -112,7 +112,7 @@ def list_bans(banlist):
|
|||
if not banlist:
|
||||
return "No active bans were found."
|
||||
|
||||
table = evtable.EvTable("|wid", "|wname/ip", "|wdate", "|wreason")
|
||||
table = self.style_table("|wid", "|wname/ip", "|wdate", "|wreason")
|
||||
for inum, ban in enumerate(banlist):
|
||||
table.add_row(str(inum + 1),
|
||||
ban[0] and ban[0] or ban[1],
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ class AccountCmdSet(CmdSet):
|
|||
self.add(account.CmdPassword())
|
||||
self.add(account.CmdColorTest())
|
||||
self.add(account.CmdQuell())
|
||||
self.add(account.CmdStyle())
|
||||
|
||||
# nicks
|
||||
self.add(general.CmdNick())
|
||||
|
|
|
|||
|
|
@ -292,7 +292,7 @@ class CmdChannels(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
if self.cmdstring == "comlist":
|
||||
# just display the subscribed channels with no extra info
|
||||
comtable = evtable.EvTable("|wchannel|n", "|wmy aliases|n",
|
||||
comtable = self.style_table("|wchannel|n", "|wmy aliases|n",
|
||||
"|wdescription|n", align="l", maxwidth=_DEFAULT_WIDTH)
|
||||
for chan in subs:
|
||||
clower = chan.key.lower()
|
||||
|
|
@ -306,7 +306,7 @@ class CmdChannels(COMMAND_DEFAULT_CLASS):
|
|||
" |waddcom|n/|wdelcom|n to sub/unsub):|n\n%s" % comtable)
|
||||
else:
|
||||
# full listing (of channels caller is able to listen to)
|
||||
comtable = evtable.EvTable("|wsub|n", "|wchannel|n", "|wmy aliases|n",
|
||||
comtable = self.style_table("|wsub|n", "|wchannel|n", "|wmy aliases|n",
|
||||
"|wlocks|n", "|wdescription|n", maxwidth=_DEFAULT_WIDTH)
|
||||
for chan in channels:
|
||||
clower = chan.key.lower()
|
||||
|
|
@ -815,7 +815,7 @@ def _list_bots():
|
|||
ircbots = [bot for bot in AccountDB.objects.filter(db_is_bot=True, username__startswith="ircbot-")]
|
||||
if ircbots:
|
||||
from evennia.utils.evtable import EvTable
|
||||
table = EvTable("|w#dbref|n", "|wbotname|n", "|wev-channel|n",
|
||||
table = self.style_table("|w#dbref|n", "|wbotname|n", "|wev-channel|n",
|
||||
"|wirc-channel|n", "|wSSL|n", maxwidth=_DEFAULT_WIDTH)
|
||||
for ircbot in ircbots:
|
||||
ircinfo = "%s (%s:%s)" % (ircbot.db.irc_channel, ircbot.db.irc_network, ircbot.db.irc_port)
|
||||
|
|
@ -1051,7 +1051,7 @@ class CmdRSS2Chan(COMMAND_DEFAULT_CLASS):
|
|||
rssbots = [bot for bot in AccountDB.objects.filter(db_is_bot=True, username__startswith="rssbot-")]
|
||||
if rssbots:
|
||||
from evennia.utils.evtable import EvTable
|
||||
table = EvTable("|wdbid|n", "|wupdate rate|n", "|wev-channel",
|
||||
table = self.style_table("|wdbid|n", "|wupdate rate|n", "|wev-channel",
|
||||
"|wRSS feed URL|n", border="cells", maxwidth=_DEFAULT_WIDTH)
|
||||
for rssbot in rssbots:
|
||||
table.add_row(rssbot.id, rssbot.db.rss_rate, rssbot.db.ev_channel, rssbot.db.rss_url)
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ class CmdNick(COMMAND_DEFAULT_CLASS):
|
|||
if not nicklist:
|
||||
string = "|wNo nicks defined.|n"
|
||||
else:
|
||||
table = evtable.EvTable("#", "Type", "Nick match", "Replacement")
|
||||
table = self.style_table("#", "Type", "Nick match", "Replacement")
|
||||
for inum, nickobj in enumerate(nicklist):
|
||||
_, _, nickvalue, replacement = nickobj.value
|
||||
table.add_row(str(inum + 1), nickobj.db_category, _cy(nickvalue), _cy(replacement))
|
||||
|
|
@ -338,7 +338,7 @@ class CmdInventory(COMMAND_DEFAULT_CLASS):
|
|||
if not items:
|
||||
string = "You are not carrying anything."
|
||||
else:
|
||||
table = evtable.EvTable(border="header")
|
||||
table = self.style_table(border="header")
|
||||
for item in items:
|
||||
table.add_row("|C%s|n" % item.name, item.db.desc or "")
|
||||
string = "|wYou are carrying:\n%s" % table
|
||||
|
|
|
|||
|
|
@ -3,8 +3,11 @@ The command template for the default MUX-style command set. There
|
|||
is also an Account/OOC version that makes sure caller is an Account object.
|
||||
"""
|
||||
|
||||
import math
|
||||
from evennia.utils import utils
|
||||
from evennia.commands.command import Command
|
||||
from evennia.utils.evtable import EvTable
|
||||
from evennia.utils.ansi import ANSIString
|
||||
|
||||
# limit symbol import for API
|
||||
__all__ = ("MuxCommand", "MuxAccountCommand")
|
||||
|
|
@ -229,6 +232,98 @@ class MuxCommand(Command):
|
|||
string += "-" * 50
|
||||
self.caller.msg(string)
|
||||
|
||||
def width(self):
|
||||
return self.session.protocol_flags['SCREENWIDTH'][0]
|
||||
|
||||
def style_table(self, *args, **kwargs):
|
||||
border_color = self.account.style.get('border_color')
|
||||
column_color = self.account.style.get('column_names_color')
|
||||
|
||||
colornames = ['|%s%s|n' % (column_color, col) for col in args]
|
||||
|
||||
h_line_char = kwargs.pop('header_line_char', '-')
|
||||
header_line_char = ANSIString(f'|{border_color}{h_line_char}|n')
|
||||
|
||||
c_char = kwargs.pop('corner_char', '+')
|
||||
corner_char = ANSIString(f'|{border_color}{c_char}|n')
|
||||
|
||||
b_left_char = kwargs.pop('border_left_char', '||')
|
||||
border_left_char = ANSIString(f'|{border_color}{b_left_char}|n')
|
||||
|
||||
b_right_char = kwargs.pop('border_right_char', '||')
|
||||
border_right_char = ANSIString(f'|{border_color}{b_right_char}|n')
|
||||
|
||||
b_bottom_char = kwargs.pop('border_bottom_char', '-')
|
||||
border_bottom_char = ANSIString(f'|{border_color}{b_bottom_char}|n')
|
||||
|
||||
b_top_char = kwargs.pop('border_top_char', '-')
|
||||
border_top_char = ANSIString(f'|{border_color}{b_top_char}|n')
|
||||
|
||||
table = EvTable(*colornames, header_line_char=header_line_char, corner_char=corner_char,
|
||||
border_left_char=border_left_char, border_right_char=border_right_char,
|
||||
border_bottom_char=border_bottom_char, border_top_char=border_top_char, **kwargs)
|
||||
return table
|
||||
|
||||
def render_header(self, header_text=None, fill_character=None, edge_character=None,
|
||||
mode='header', color_header=True):
|
||||
colors = dict()
|
||||
colors['border'] = self.account.style.get('border_color')
|
||||
colors['headertext'] = self.account.style.get('%s_text_color' % mode)
|
||||
colors['headerstar'] = self.account.style.get('%s_star_color' % mode)
|
||||
|
||||
width = self.width()
|
||||
if edge_character:
|
||||
width -= 2
|
||||
|
||||
if header_text:
|
||||
if color_header:
|
||||
header_text = ANSIString(header_text).clean()
|
||||
header_text = ANSIString('|n|%s%s|n' % (colors['headertext'], header_text))
|
||||
if mode == 'header':
|
||||
begin_center = ANSIString("|n|%s<|%s* |n" % (colors['border'], colors['headerstar']))
|
||||
end_center = ANSIString("|n |%s*|%s>|n" % (colors['headerstar'], colors['border']))
|
||||
center_string = ANSIString(begin_center + header_text + end_center)
|
||||
else:
|
||||
center_string = ANSIString('|n |%s%s |n' % (colors['headertext'], header_text))
|
||||
else:
|
||||
center_string = ''
|
||||
|
||||
fill_character = self.account.style.get('%s_fill' % mode)
|
||||
|
||||
remain_fill = width - len(center_string)
|
||||
if remain_fill % 2 == 0:
|
||||
right_width = remain_fill / 2
|
||||
left_width = remain_fill / 2
|
||||
else:
|
||||
right_width = math.floor(remain_fill / 2)
|
||||
left_width = math.ceil(remain_fill / 2)
|
||||
|
||||
right_fill = ANSIString('|n|%s%s|n' % (colors['border'], fill_character * int(right_width)))
|
||||
left_fill = ANSIString('|n|%s%s|n' % (colors['border'], fill_character * int(left_width)))
|
||||
|
||||
if edge_character:
|
||||
edge_fill = ANSIString('|n|%s%s|n' % (colors['border'], edge_character))
|
||||
main_string = ANSIString(center_string)
|
||||
final_send = ANSIString(edge_fill) + left_fill + main_string + right_fill + ANSIString(edge_fill)
|
||||
else:
|
||||
final_send = left_fill + ANSIString(center_string) + right_fill
|
||||
return final_send
|
||||
|
||||
def style_header(self, *args, **kwargs):
|
||||
if 'mode' not in kwargs:
|
||||
kwargs['mode'] = 'header'
|
||||
return self.render_header(*args, **kwargs)
|
||||
|
||||
def style_separator(self, *args, **kwargs):
|
||||
if 'mode' not in kwargs:
|
||||
kwargs['mode'] = 'separator'
|
||||
return self.render_header(*args, **kwargs)
|
||||
|
||||
def style_footer(self, *args, **kwargs):
|
||||
if 'mode' not in kwargs:
|
||||
kwargs['mode'] = 'footer'
|
||||
return self.render_header(*args, **kwargs)
|
||||
|
||||
|
||||
class MuxAccountCommand(MuxCommand):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -445,7 +445,7 @@ class CmdObjects(COMMAND_DEFAULT_CLASS):
|
|||
nobjs = nobjs or 1 # fix zero-div error with empty database
|
||||
|
||||
# total object sum table
|
||||
totaltable = EvTable("|wtype|n", "|wcomment|n", "|wcount|n", "|w%%|n", border="table", align="l")
|
||||
totaltable = self.style_table("|wtype|n", "|wcomment|n", "|wcount|n", "|w%%|n", border="table", align="l")
|
||||
totaltable.align = 'l'
|
||||
totaltable.add_row("Characters", "(BASE_CHARACTER_TYPECLASS)", nchars, "%.2f" % ((float(nchars) / nobjs) * 100))
|
||||
totaltable.add_row("Rooms", "(location=None)", nrooms, "%.2f" % ((float(nrooms) / nobjs) * 100))
|
||||
|
|
@ -453,7 +453,7 @@ class CmdObjects(COMMAND_DEFAULT_CLASS):
|
|||
totaltable.add_row("Other", "", nother, "%.2f" % ((float(nother) / nobjs) * 100))
|
||||
|
||||
# typeclass table
|
||||
typetable = EvTable("|wtypeclass|n", "|wcount|n", "|w%%|n", border="table", align="l")
|
||||
typetable = self.style_table("|wtypeclass|n", "|wcount|n", "|w%%|n", border="table", align="l")
|
||||
typetable.align = 'l'
|
||||
dbtotals = ObjectDB.objects.object_totals()
|
||||
for path, count in dbtotals.items():
|
||||
|
|
@ -461,7 +461,7 @@ class CmdObjects(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
# last N table
|
||||
objs = ObjectDB.objects.all().order_by("db_date_created")[max(0, nobjs - nlim):]
|
||||
latesttable = EvTable("|wcreated|n", "|wdbref|n", "|wname|n", "|wtypeclass|n", align="l", border="table")
|
||||
latesttable = self.style_table("|wcreated|n", "|wdbref|n", "|wname|n", "|wtypeclass|n", align="l", border="table")
|
||||
latesttable.align = 'l'
|
||||
for obj in objs:
|
||||
latesttable.add_row(utils.datetime_format(obj.date_created),
|
||||
|
|
@ -557,12 +557,12 @@ class CmdAccounts(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
# typeclass table
|
||||
dbtotals = AccountDB.objects.object_totals()
|
||||
typetable = EvTable("|wtypeclass|n", "|wcount|n", "|w%%|n", border="cells", align="l")
|
||||
typetable = self.style_table("|wtypeclass|n", "|wcount|n", "|w%%|n", border="cells", align="l")
|
||||
for path, count in dbtotals.items():
|
||||
typetable.add_row(path, count, "%.2f" % ((float(count) / naccounts) * 100))
|
||||
# last N table
|
||||
plyrs = AccountDB.objects.all().order_by("db_date_created")[max(0, naccounts - nlim):]
|
||||
latesttable = EvTable("|wcreated|n", "|wdbref|n", "|wname|n", "|wtypeclass|n", border="cells", align="l")
|
||||
latesttable = self.style_table("|wcreated|n", "|wdbref|n", "|wname|n", "|wtypeclass|n", border="cells", align="l")
|
||||
for ply in plyrs:
|
||||
latesttable.add_row(utils.datetime_format(ply.date_created), ply.dbref, ply.key, ply.path)
|
||||
|
||||
|
|
@ -613,7 +613,7 @@ class CmdService(COMMAND_DEFAULT_CLASS):
|
|||
if not switches or switches[0] == "list":
|
||||
# Just display the list of installed services and their
|
||||
# status, then exit.
|
||||
table = EvTable("|wService|n (use @services/start|stop|delete)", "|wstatus", align="l")
|
||||
table = self.style_table("|wService|n (use @services/start|stop|delete)", "|wstatus", align="l")
|
||||
for service in service_collection.services:
|
||||
table.add_row(service.name, service.running and "|gRunning" or "|rNot Running")
|
||||
caller.msg(str(table))
|
||||
|
|
@ -723,14 +723,14 @@ class CmdTime(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
def func(self):
|
||||
"""Show server time data in a table."""
|
||||
table1 = EvTable("|wServer time", "", align="l", width=78)
|
||||
table1 = self.style_table("|wServer time", "", align="l", width=78)
|
||||
table1.add_row("Current uptime", utils.time_format(gametime.uptime(), 3))
|
||||
table1.add_row("Portal uptime", utils.time_format(gametime.portal_uptime(), 3))
|
||||
table1.add_row("Total runtime", utils.time_format(gametime.runtime(), 2))
|
||||
table1.add_row("First start", datetime.datetime.fromtimestamp(gametime.server_epoch()))
|
||||
table1.add_row("Current time", datetime.datetime.now())
|
||||
table1.reformat_column(0, width=30)
|
||||
table2 = EvTable("|wIn-Game time", "|wReal time x %g" % gametime.TIMEFACTOR, align="l", width=77, border_top=0)
|
||||
table2 = self.style_table("|wIn-Game time", "|wReal time x %g" % gametime.TIMEFACTOR, align="l", width=77, border_top=0)
|
||||
epochtxt = "Epoch (%s)" % ("from settings" if settings.TIME_GAME_EPOCH else "server start")
|
||||
table2.add_row(epochtxt, datetime.datetime.fromtimestamp(gametime.game_epoch()))
|
||||
table2.add_row("Total time passed:", utils.time_format(gametime.gametime(), 2))
|
||||
|
|
@ -824,7 +824,7 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
|||
self.caller.msg(string % (rmem, pmem))
|
||||
return
|
||||
# Display table
|
||||
loadtable = EvTable("property", "statistic", align="l")
|
||||
loadtable = self.style_table("property", "statistic", align="l")
|
||||
loadtable.add_row("Total CPU load", "%g %%" % loadavg)
|
||||
loadtable.add_row("Total computer memory usage", "%g MB (%g%%)" % (rmem, pmem))
|
||||
loadtable.add_row("Process ID", "%g" % pid),
|
||||
|
|
@ -850,7 +850,7 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
|||
self.caller.msg(string % (rmem, pmem, vmem))
|
||||
return
|
||||
|
||||
loadtable = EvTable("property", "statistic", align="l")
|
||||
loadtable = self.style_table("property", "statistic", align="l")
|
||||
loadtable.add_row("Server load (1 min)", "%g" % loadavg)
|
||||
loadtable.add_row("Process ID", "%g" % pid),
|
||||
loadtable.add_row("Memory usage", "%g MB (%g%%)" % (rmem, pmem))
|
||||
|
|
@ -875,7 +875,7 @@ class CmdServerLoad(COMMAND_DEFAULT_CLASS):
|
|||
total_num, cachedict = _IDMAPPER.cache_size()
|
||||
sorted_cache = sorted([(key, num) for key, num in cachedict.items() if num > 0],
|
||||
key=lambda tup: tup[1], reverse=True)
|
||||
memtable = EvTable("entity name", "number", "idmapper %", align="l")
|
||||
memtable = self.style_table("entity name", "number", "idmapper %", align="l")
|
||||
for tup in sorted_cache:
|
||||
memtable.add_row(tup[0], "%i" % tup[1], "%.2f" % (float(tup[1]) / total_num * 100))
|
||||
|
||||
|
|
@ -907,7 +907,7 @@ class CmdTickers(COMMAND_DEFAULT_CLASS):
|
|||
if not all_subs:
|
||||
self.caller.msg("No tickers are currently active.")
|
||||
return
|
||||
table = EvTable("interval (s)", "object", "path/methodname", "idstring", "db")
|
||||
table = self.style_table("interval (s)", "object", "path/methodname", "idstring", "db")
|
||||
for sub in all_subs:
|
||||
table.add_row(sub[3],
|
||||
"%s%s" % (sub[0] or "[None]",
|
||||
|
|
|
|||
|
|
@ -489,6 +489,27 @@ START_LOCATION = "#2"
|
|||
# issues.
|
||||
TYPECLASS_AGGRESSIVE_CACHE = True
|
||||
|
||||
######################################################################
|
||||
# Styles
|
||||
######################################################################
|
||||
|
||||
# Replace entries in this dictionary to change the default stylings
|
||||
# Evennia uses for commands. Or add more entries! Accounts can have
|
||||
# per-user settings that override these.
|
||||
|
||||
DEFAULT_STYLES = {
|
||||
'border_color': ('Headers, footers, table borders, etc.', 'color', 'M'),
|
||||
'header_star_color': ('* inside Header lines.', 'color', 'm'),
|
||||
'header_text_color': ('Text inside Header lines.', 'color', 'w'),
|
||||
'footer_text_color': ('Text inside Footer Lines.', 'color', 'w'),
|
||||
'column_names_color': ('Table column header text.', 'color', 'G'),
|
||||
'header_fill': ('Fill for Header lines.', 'word', '='),
|
||||
'separator_fill': ('Fill for Separator Lines.', 'word', '-'),
|
||||
'footer_fill': ('Fill for Footer Lines.', 'word', '='),
|
||||
'help_category_color': ('Help category names.', 'color', 'g'),
|
||||
'help_entry_color': ('Help entry names.', 'color', 'c'),
|
||||
}
|
||||
|
||||
######################################################################
|
||||
# Batch processors
|
||||
######################################################################
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue