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

1#!/usr/bin/env python 

2""" 

3Larch command-line shell 

4""" 

5import cmd 

6import os 

7import sys 

8from .interpreter import Interpreter 

9 

10from .site_config import history_file 

11from .version import make_banner 

12from .larchlib import StdWriter 

13from .utils import uname 

14 

15HAS_READLINE = False 

16try: 

17 import readline 

18 HAS_READLINE = True 

19except ImportError: 

20 pass 

21 

22HAS_WXPYTHON = False 

23try: 

24 import wx 

25 HAS_WXPYTHON = True 

26except ImportError: 

27 wx = None 

28 

29 

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): 

35 

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 

44 

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}') 

50 

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 

61 

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) 

66 

67 def on_ctrl_c(*args, **kws): 

68 return 0 

69 

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 

78 

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() 

94 

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() 

106 

107 def do_exit(self, text): 

108 "exit" 

109 self.on_exit(text=text) 

110 

111 def do_quit(self, text): 

112 "quit" 

113 self.on_exit(text=text) 

114 

115 def emptyline(self): 

116 pass 

117 

118 def onecmd(self, line): 

119 "single command" 

120 return self.default(line) 

121 

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})") 

131 

132 def do_shell(self, txt): 

133 "shell command" 

134 os.system(txt) 

135 

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)) 

150 

151 self.larch.writer.flush() 

152 self.prompt = self.larch.input.next_prompt