Coverage for /Users/Newville/Codes/xraylarch/larch/shell.py: 0%
115 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-09 10:08 -0600
« prev ^ index » next coverage.py v7.3.2, created at 2023-11-09 10:08 -0600
1#!/usr/bin/env python
2"""
3Larch command-line shell
4"""
5import cmd
6import os
7import sys
8from .interpreter import Interpreter
10from .site_config import history_file
11from .version import make_banner
12from .larchlib import StdWriter
13from .utils import uname
15HAS_READLINE = False
16try:
17 import readline
18 HAS_READLINE = True
19except ImportError:
20 pass
22HAS_WXPYTHON = False
23try:
24 import wx
25 HAS_WXPYTHON = True
26except ImportError:
27 wx = None
30class Shell(cmd.Cmd):
31 """command shell for Larch"""
32 def __init__(self, completekey='tab', debug=False, quiet=False,
33 stdin=None, stdout=None, banner_msg=None,
34 maxhist=25000, with_wx=False):
36 self.debug = debug
37 cmd.Cmd.__init__(self,completekey='tab')
38 if stdin is not None:
39 sys.stdin = stdin
40 if stdout is not None:
41 sys.stdout = stdout
42 self.stdin = sys.stdin
43 self.stdout = sys.stdout
45 if HAS_READLINE:
46 try:
47 readline.read_history_file(history_file)
48 except IOError:
49 print(f'could not read history from {history_file}')
51 self.larch = Interpreter(historyfile=history_file,
52 maxhistory=maxhist)
53 self.larch.writer = StdWriter(_larch=self.larch)
54 if with_wx and HAS_WXPYTHON:
55 symtable = self.larch.symtable
56 try:
57 from .wxlib import LarchWxApp
58 app = LarchWxApp(redirect=False, clearSigInt=False)
59 except SystemExit:
60 with_wx = False
62 if with_wx and HAS_WXPYTHON:
63 symtable.set_symbol('_sys.wx.wxapp', app)
64 symtable.set_symbol('_sys.wx.force_wxupdate', False)
65 symtable.set_symbol('_sys.wx.parent', None)
67 def on_ctrl_c(*args, **kws):
68 return 0
70 from .wxlib import inputhook
71 symtable.set_symbol('_sys.wx.inputhook', inputhook)
72 if uname == 'darwin':
73 symtable.set_symbol('_sys.wx.ping', inputhook.ping_darwin)
74 else:
75 symtable.set_symbol('_sys.wx.ping', inputhook.ping)
76 inputhook.ON_INTERRUPT = on_ctrl_c
77 inputhook.WXLARCH_SYM = symtable
79 self.prompt = self.larch.input.prompt
80 writer = self.larch.writer
81 self.color_writer = (uname != 'win' and hasattr(writer, 'set_textstyle'))
82 if not quiet:
83 if banner_msg is None:
84 banner_msg = make_banner(show_libraries=['numpy', 'scipy', 'matplotlib', 'h5py',
85 'lmfit', 'xraydb', 'wx','wxmplot'])
86 if self.color_writer:
87 writer.set_textstyle('error')
88 writer.write(banner_msg)
89 writer.write("\n")
90 if self.color_writer:
91 writer.set_textstyle('text')
92 self.larch_execute = self.default
93 self.larch.run_init_scripts()
95 def on_exit(self, text=None):
96 "exit"
97 trim_last = False
98 if text is not None:
99 trim_last = text.strip() in ('quit', 'exit')
100 try:
101 self.larch.input.history.save(trim_last=trim_last)
102 except PermissionError:
103 print("Warning: could not save session history -- permission denied")
104 self.larch.symtable._plotter.close_all_displays()
105 sys.exit()
107 def do_exit(self, text):
108 "exit"
109 self.on_exit(text=text)
111 def do_quit(self, text):
112 "quit"
113 self.on_exit(text=text)
115 def emptyline(self):
116 pass
118 def onecmd(self, line):
119 "single command"
120 return self.default(line)
122 def do_help(self, arg):
123 "help"
124 if arg.startswith('(') and arg.endswith(')'):
125 arg = arg[1:-1]
126 elif arg.startswith("'") and arg.endswith("'"):
127 arg = arg[1:-1]
128 elif arg.startswith('"') and arg.endswith('"'):
129 arg = arg[1:-1]
130 self.default(f"help({arg})")
132 def do_shell(self, txt):
133 "shell command"
134 os.system(txt)
136 def default(self, line):
137 "default handler"
138 if line.strip() in ('quit', 'exit', 'quit()', 'exit()', 'EOF'):
139 self.on_exit(line)
140 ret = self.larch.eval(line, fname='<stdin>', lineno=0)
141 if self.larch.error:
142 self.larch.input.clear()
143 if self.color_writer:
144 self.larch.writer.set_textstyle('error')
145 self.larch.show_errors()
146 if self.color_writer:
147 self.larch.writer.set_textstyle('line')
148 if ret is not None:
149 self.larch.writer.write("%s\n" % repr(ret))
151 self.larch.writer.flush()
152 self.prompt = self.larch.input.next_prompt