mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
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.players.models import PlayerDB
|
||||
from evennia.utils import logger, utils, gametime, create, prettytable
|
||||
from evennia.utils.eveditor import EvEditor
|
||||
from evennia.utils.evtable import EvTable
|
||||
from evennia.utils.utils import crop, class_from_module
|
||||
|
||||
|
|
@ -122,19 +123,101 @@ class CmdShutdown(COMMAND_DEFAULT_CLASS):
|
|||
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):
|
||||
"""
|
||||
execute a snippet of python code
|
||||
|
||||
Usage:
|
||||
@py <cmd>
|
||||
@py/edit
|
||||
|
||||
Switch:
|
||||
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
|
||||
available for convenience in order to offer access to the system
|
||||
(you can import more at execution time).
|
||||
Separate multiple commands by ';' or open the editor using the
|
||||
/edit switch. A few variables are made available for convenience
|
||||
in order to offer access to the system (you can import more at
|
||||
execution time).
|
||||
|
||||
Available variables in @py environment:
|
||||
self, me : caller
|
||||
|
|
@ -160,58 +243,18 @@ class CmdPy(COMMAND_DEFAULT_CLASS):
|
|||
caller = self.caller
|
||||
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:
|
||||
string = "Usage: @py <code>"
|
||||
self.msg(string)
|
||||
return
|
||||
|
||||
# check if caller is a player
|
||||
|
||||
# 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})
|
||||
|
||||
_run_snippet(caller, self.args, m_time="time" in self.switches)
|
||||
|
||||
# helper function. Kept outside so it can be imported and run
|
||||
# by other commands.
|
||||
|
|
|
|||
|
|
@ -375,7 +375,7 @@ class CmdLineInput(CmdEditorBase):
|
|||
buf = editor.get_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 buf:
|
||||
buf = line
|
||||
|
|
@ -396,8 +396,12 @@ class CmdLineInput(CmdEditorBase):
|
|||
cline = len(self.editor.get_buffer().split('\n'))
|
||||
if editor._code:
|
||||
# display the current level of identation
|
||||
self.caller.msg("{b%02i|{n ({g%d{n) %s" % (
|
||||
cline, editor._indent, line))
|
||||
indent = editor._indent
|
||||
if indent < 0:
|
||||
indent = "off"
|
||||
|
||||
self.caller.msg("{b%02i|{n ({g%s{n) %s" % (
|
||||
cline, indent, line))
|
||||
else:
|
||||
self.caller.msg("{b%02i|{n %s" % (cline, self.args))
|
||||
|
||||
|
|
@ -503,6 +507,13 @@ class CmdEditorGroup(CmdEditorBase):
|
|||
elif cmd == ":DD":
|
||||
# clear 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)
|
||||
elif cmd == ":y":
|
||||
# :y <l> - yank line(s) to copy buffer
|
||||
|
|
@ -949,7 +960,7 @@ class EvEditor(object):
|
|||
|
||||
"""
|
||||
string = self._sep * _DEFAULT_WIDTH + _HELP_TEXT
|
||||
if self.code:
|
||||
if self._code:
|
||||
string += _HELP_CODE
|
||||
string += _HELP_LEGEND + self._sep * _DEFAULT_WIDTH
|
||||
self._caller.msg(string)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue