Add the /edit swtich to the @py command
This commit is contained in:
parent
36b268ca81
commit
1697263fd7
2 changed files with 108 additions and 54 deletions
|
|
@ -19,6 +19,7 @@ from evennia.scripts.models import ScriptDB
|
||||||
from evennia.objects.models import ObjectDB
|
from evennia.objects.models import ObjectDB
|
||||||
from evennia.players.models import PlayerDB
|
from evennia.players.models import PlayerDB
|
||||||
from evennia.utils import logger, utils, gametime, create, prettytable
|
from evennia.utils import logger, utils, gametime, create, prettytable
|
||||||
|
from evennia.utils.eveditor import EvEditor
|
||||||
from evennia.utils.evtable import EvTable
|
from evennia.utils.evtable import EvTable
|
||||||
from evennia.utils.utils import crop, class_from_module
|
from evennia.utils.utils import crop, class_from_module
|
||||||
|
|
||||||
|
|
@ -122,19 +123,101 @@ class CmdShutdown(COMMAND_DEFAULT_CLASS):
|
||||||
SESSIONS.portal_shutdown()
|
SESSIONS.portal_shutdown()
|
||||||
|
|
||||||
|
|
||||||
|
def _py_load(caller):
|
||||||
|
return ""
|
||||||
|
|
||||||
|
def _py_save(caller, buf):
|
||||||
|
"""
|
||||||
|
Execute the buffer.
|
||||||
|
"""
|
||||||
|
caller.msg("Executing the entered code...")
|
||||||
|
_run_snippet(caller, buf, mode="exec", show_input=False)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _py_quit(caller):
|
||||||
|
caller.msg("Exited the code editor.")
|
||||||
|
|
||||||
|
def _run_snippet(caller, pycode, mode="eval", m_time=False,
|
||||||
|
show_input=True):
|
||||||
|
"""
|
||||||
|
Run code and try to display information to the caller.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
caller (Object): the caller.
|
||||||
|
pycode (str): the Python code to run.
|
||||||
|
m_time (bool, optional): should we measure the time of execution?
|
||||||
|
show_input (bookl, optional): should we display the input?
|
||||||
|
|
||||||
|
"""
|
||||||
|
# Try to retrieve the session
|
||||||
|
session = caller
|
||||||
|
if hasattr(caller, "sessions"):
|
||||||
|
session = caller.sessions.get()[0]
|
||||||
|
|
||||||
|
# import useful variables
|
||||||
|
import evennia
|
||||||
|
available_vars = {
|
||||||
|
'self': caller,
|
||||||
|
'me': caller,
|
||||||
|
'here': getattr(caller, "location", None),
|
||||||
|
'evennia': evennia,
|
||||||
|
'ev': evennia,
|
||||||
|
'inherits_from': utils.inherits_from,
|
||||||
|
}
|
||||||
|
|
||||||
|
if show_input:
|
||||||
|
try:
|
||||||
|
caller.msg(">>> %s" % pycode, session=session,
|
||||||
|
options={"raw":True})
|
||||||
|
except TypeError:
|
||||||
|
caller.msg(">>> %s" % pycode, options={"raw":True})
|
||||||
|
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
pycode_compiled = compile(pycode, "", mode)
|
||||||
|
except Exception:
|
||||||
|
mode = "exec"
|
||||||
|
pycode_compiled = compile(pycode, "", mode)
|
||||||
|
|
||||||
|
duration = ""
|
||||||
|
if m_time:
|
||||||
|
t0 = time.time()
|
||||||
|
ret = eval(pycode_compiled, {}, available_vars)
|
||||||
|
t1 = time.time()
|
||||||
|
duration = " (runtime ~ %.4f ms)" % ((t1 - t0) * 1000)
|
||||||
|
else:
|
||||||
|
ret = eval(pycode_compiled, {}, available_vars)
|
||||||
|
if mode == "eval":
|
||||||
|
ret = "%s%s" % (str(ret), duration)
|
||||||
|
else:
|
||||||
|
ret = " Done (use self.msg() if you want to catch output)%s" % duration
|
||||||
|
except Exception:
|
||||||
|
errlist = traceback.format_exc().split('\n')
|
||||||
|
if len(errlist) > 4:
|
||||||
|
errlist = errlist[4:]
|
||||||
|
ret = "\n".join("%s" % line for line in errlist if line)
|
||||||
|
|
||||||
|
try:
|
||||||
|
caller.msg(ret, session=session, options={"raw":True})
|
||||||
|
except TypeError:
|
||||||
|
caller.msg(ret, options={"raw":True})
|
||||||
|
|
||||||
class CmdPy(COMMAND_DEFAULT_CLASS):
|
class CmdPy(COMMAND_DEFAULT_CLASS):
|
||||||
"""
|
"""
|
||||||
execute a snippet of python code
|
execute a snippet of python code
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
@py <cmd>
|
@py <cmd>
|
||||||
|
@py/edit
|
||||||
|
|
||||||
Switch:
|
Switch:
|
||||||
time - output an approximate execution time for <cmd>
|
time - output an approximate execution time for <cmd>
|
||||||
|
edit - open a code editor to enter several lines of code
|
||||||
|
|
||||||
Separate multiple commands by ';'. A few variables are made
|
Separate multiple commands by ';' or open the editor using the
|
||||||
available for convenience in order to offer access to the system
|
/edit switch. A few variables are made available for convenience
|
||||||
(you can import more at execution time).
|
in order to offer access to the system (you can import more at
|
||||||
|
execution time).
|
||||||
|
|
||||||
Available variables in @py environment:
|
Available variables in @py environment:
|
||||||
self, me : caller
|
self, me : caller
|
||||||
|
|
@ -160,58 +243,18 @@ class CmdPy(COMMAND_DEFAULT_CLASS):
|
||||||
caller = self.caller
|
caller = self.caller
|
||||||
pycode = self.args
|
pycode = self.args
|
||||||
|
|
||||||
|
if "edit" in self.switches:
|
||||||
|
EvEditor(self.caller, loadfunc=_py_load, savefunc=_py_save,
|
||||||
|
quitfunc=_py_quit, key="PyEditor", persistent=True,
|
||||||
|
code=True)
|
||||||
|
return
|
||||||
|
|
||||||
if not pycode:
|
if not pycode:
|
||||||
string = "Usage: @py <code>"
|
string = "Usage: @py <code>"
|
||||||
self.msg(string)
|
self.msg(string)
|
||||||
return
|
return
|
||||||
|
|
||||||
# check if caller is a player
|
_run_snippet(caller, self.args, m_time="time" in self.switches)
|
||||||
|
|
||||||
# import useful variables
|
|
||||||
import evennia
|
|
||||||
available_vars = {'self': caller,
|
|
||||||
'me': caller,
|
|
||||||
'here': hasattr(caller, "location") and caller.location or None,
|
|
||||||
'evennia': evennia,
|
|
||||||
'ev': evennia,
|
|
||||||
'inherits_from': utils.inherits_from}
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.msg(">>> %s" % pycode, session=self.session, options={"raw":True})
|
|
||||||
except TypeError:
|
|
||||||
self.msg(">>> %s" % pycode, options={"raw":True})
|
|
||||||
|
|
||||||
mode = "eval"
|
|
||||||
try:
|
|
||||||
try:
|
|
||||||
pycode_compiled = compile(pycode, "", mode)
|
|
||||||
except Exception:
|
|
||||||
mode = "exec"
|
|
||||||
pycode_compiled = compile(pycode, "", mode)
|
|
||||||
|
|
||||||
duration = ""
|
|
||||||
if "time" in self.switches:
|
|
||||||
t0 = time.time()
|
|
||||||
ret = eval(pycode_compiled, {}, available_vars)
|
|
||||||
t1 = time.time()
|
|
||||||
duration = " (runtime ~ %.4f ms)" % ((t1 - t0) * 1000)
|
|
||||||
else:
|
|
||||||
ret = eval(pycode_compiled, {}, available_vars)
|
|
||||||
if mode == "eval":
|
|
||||||
ret = "%s%s" % (str(ret), duration)
|
|
||||||
else:
|
|
||||||
ret = " Done (use self.msg() if you want to catch output)%s" % duration
|
|
||||||
except Exception:
|
|
||||||
errlist = traceback.format_exc().split('\n')
|
|
||||||
if len(errlist) > 4:
|
|
||||||
errlist = errlist[4:]
|
|
||||||
ret = "\n".join("%s" % line for line in errlist if line)
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.msg(ret, session=self.session, options={"raw":True})
|
|
||||||
except TypeError:
|
|
||||||
self.msg(ret, options={"raw":True})
|
|
||||||
|
|
||||||
|
|
||||||
# helper function. Kept outside so it can be imported and run
|
# helper function. Kept outside so it can be imported and run
|
||||||
# by other commands.
|
# by other commands.
|
||||||
|
|
|
||||||
|
|
@ -375,7 +375,7 @@ class CmdLineInput(CmdEditorBase):
|
||||||
buf = editor.get_buffer()
|
buf = editor.get_buffer()
|
||||||
|
|
||||||
# add a line of text to buffer
|
# add a line of text to buffer
|
||||||
line = self.raw_string
|
line = self.raw_string.strip("\r\n")
|
||||||
if not editor._code:
|
if not editor._code:
|
||||||
if not buf:
|
if not buf:
|
||||||
buf = line
|
buf = line
|
||||||
|
|
@ -396,8 +396,12 @@ class CmdLineInput(CmdEditorBase):
|
||||||
cline = len(self.editor.get_buffer().split('\n'))
|
cline = len(self.editor.get_buffer().split('\n'))
|
||||||
if editor._code:
|
if editor._code:
|
||||||
# display the current level of identation
|
# display the current level of identation
|
||||||
self.caller.msg("{b%02i|{n ({g%d{n) %s" % (
|
indent = editor._indent
|
||||||
cline, editor._indent, line))
|
if indent < 0:
|
||||||
|
indent = "off"
|
||||||
|
|
||||||
|
self.caller.msg("{b%02i|{n ({g%s{n) %s" % (
|
||||||
|
cline, indent, line))
|
||||||
else:
|
else:
|
||||||
self.caller.msg("{b%02i|{n %s" % (cline, self.args))
|
self.caller.msg("{b%02i|{n %s" % (cline, self.args))
|
||||||
|
|
||||||
|
|
@ -503,6 +507,13 @@ class CmdEditorGroup(CmdEditorBase):
|
||||||
elif cmd == ":DD":
|
elif cmd == ":DD":
|
||||||
# clear buffer
|
# clear buffer
|
||||||
editor.update_buffer("")
|
editor.update_buffer("")
|
||||||
|
|
||||||
|
# Reset indentation level to 0
|
||||||
|
if editor._code:
|
||||||
|
if editor._indent >= 0:
|
||||||
|
editor._indent = 0
|
||||||
|
if editor._persistent:
|
||||||
|
caller.attributes.add("_eveditor_indent", 0)
|
||||||
caller.msg("Cleared %i lines from buffer." % self.nlines)
|
caller.msg("Cleared %i lines from buffer." % self.nlines)
|
||||||
elif cmd == ":y":
|
elif cmd == ":y":
|
||||||
# :y <l> - yank line(s) to copy buffer
|
# :y <l> - yank line(s) to copy buffer
|
||||||
|
|
@ -949,7 +960,7 @@ class EvEditor(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
string = self._sep * _DEFAULT_WIDTH + _HELP_TEXT
|
string = self._sep * _DEFAULT_WIDTH + _HELP_TEXT
|
||||||
if self.code:
|
if self._code:
|
||||||
string += _HELP_CODE
|
string += _HELP_CODE
|
||||||
string += _HELP_LEGEND + self._sep * _DEFAULT_WIDTH
|
string += _HELP_LEGEND + self._sep * _DEFAULT_WIDTH
|
||||||
self._caller.msg(string)
|
self._caller.msg(string)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue