diff options
author | Steven Silvester | 2014-08-10 13:34:54 -0500 |
---|---|---|
committer | Steven Silvester | 2014-08-10 13:34:54 -0500 |
commit | af7556f4b53bbc5d4112814d87e212d8e43badf2 (patch) | |
tree | 58fae887faa73d1a420e446c288613a7950e30cb | |
parent | ad07fa18ba43d2511194f6ba465259628e7aff2d (diff) | |
download | scilab_kernel-af7556f4b53bbc5d4112814d87e212d8e43badf2.tar.gz scilab_kernel-af7556f4b53bbc5d4112814d87e212d8e43badf2.tar.bz2 scilab_kernel-af7556f4b53bbc5d4112814d87e212d8e43badf2.zip |
Improved completion and help docstrings, refactor helper funcs
-rw-r--r-- | scilab_kernel.py | 223 |
1 files changed, 128 insertions, 95 deletions
diff --git a/scilab_kernel.py b/scilab_kernel.py index b30e6f4..9dfe1fa 100644 --- a/scilab_kernel.py +++ b/scilab_kernel.py @@ -43,7 +43,7 @@ class ScilabKernel(Kernel): def __init__(self, **kwargs): Kernel.__init__(self, **kwargs) - self.log.setLevel(logging.CRITICAL) + self.log.setLevel(logging.INFO) # Signal handlers are inherited by forked processes, # and we can't easily reset it from the subprocess. @@ -54,6 +54,8 @@ class ScilabKernel(Kernel): try: self.scilab_wrapper = scilab scilab.restart() + # start scilab and override gettext function + self.scilab_wrapper._eval('_ = ""') finally: signal.signal(signal.SIGINT, sig) @@ -147,30 +149,19 @@ class ScilabKernel(Kernel): return default token = tokens[-1] - if os.sep in token: - dname = os.path.dirname(token) - rest = os.path.basename(token) - - if os.path.exists(dname): - files = os.listdir(dname) - matches = [f for f in files if f.startswith(rest)] - start = cursor_pos - len(rest) - - else: - return default - - else: - start = cursor_pos - len(token) - cmd = 'completion("%s")' % token - output = self.scilab_wrapper._eval([cmd]) - if output is None or output == '': - return default + start = cursor_pos - len(token) + cmd = 'x = completion("%s");' % token + output = self.scilab_wrapper._eval(cmd) + matches = [] + if not output is None: matches = output.replace('!', ' ').split() for item in dir(self.scilab_wrapper): if item.startswith(token) and not item in matches: matches.append(item) + matches.extend(_complete_path(token)) + return {'matches': matches, 'cursor_start': start, 'cursor_end': cursor_pos, 'metadata': dict(), 'status': 'ok'} @@ -184,9 +175,9 @@ class ScilabKernel(Kernel): else: token = code[:cursor_pos - 1].replace(';', '').split()[-1] - self.log.info(token) - docstring = self._get_scilab_info(token, - detail_level)['docstring'] + info = _get_scilab_info(self.scilab_wrapper, self.inspector, + token, detail_level) + docstring = info['docstring'] if docstring: data = {'text/plain': docstring} @@ -246,7 +237,9 @@ class ScilabKernel(Kernel): return token = tokens[-1] - info = self._get_scilab_info(token, detail_level) + info = _get_scilab_info(self.scilab_wrapper, self.inspector, + token, detail_level) + if 'built-in Scilab function.' in info['docstring']: self.scilab_wrapper.help(token) @@ -255,7 +248,7 @@ class ScilabKernel(Kernel): self.send_response(self.iopub_socket, 'stream', stream_content) else: - output = self._get_printable_info(info, detail_level) + output = _get_printable_info(self.inspector, info, detail_level) stream_content = {'name': 'stdout', 'data': output} self.send_response(self.iopub_socket, 'stream', stream_content) @@ -276,86 +269,126 @@ class ScilabKernel(Kernel): return {'status': 'error', 'execution_count': self.execution_count, 'ename': '', 'evalue': err, 'traceback': []} - def _get_printable_info(self, info, detail_level=0): - inspector = self.inspector - displayfields = [] - def add_fields(fields): - for title, key in fields: - field = info[key] - if field is not None: - displayfields.append((title, field.rstrip())) +def _get_printable_info(inspector, info, detail_level=0): + displayfields = [] - add_fields(inspector.pinfo_fields1) - add_fields(inspector.pinfo_fields2) - add_fields(inspector.pinfo_fields3) + def add_fields(fields): + for title, key in fields: + field = info[key] + if field is not None: + displayfields.append((title, field.rstrip())) - # Source or docstring, depending on detail level and whether - # source found. - if detail_level > 0 and info['source'] is not None: - source = cast_unicode(info['source']) - displayfields.append(("Source", source)) + add_fields(inspector.pinfo_fields1) + add_fields(inspector.pinfo_fields2) + add_fields(inspector.pinfo_fields3) - elif info['docstring'] is not None: - displayfields.append(("Docstring", info["docstring"])) + # Source or docstring, depending on detail level and whether + # source found. + if detail_level > 0 and info['source'] is not None: + source = cast_unicode(info['source']) + displayfields.append(("Source", source)) - # Info for objects: - else: - add_fields(inspector.pinfo_fields_obj) - - # Finally send to printer/pager: - if displayfields: - return inspector._format_fields(displayfields) - - def _get_scilab_info(self, obj, detail_level): - info = dict(argspec=None, base_class=None, call_def=None, - call_docstring=None, class_docstring=None, - definition=None, docstring=None, file=None, - found=False, init_definition=None, - init_docstring=None, isalias=0, isclass=None, - ismagic=0, length=None, name='', namespace=None, - source=None, string_form=None, type_name='') - - sci = self.scilab_wrapper - - if obj in dir(sci): - obj = getattr(sci, obj) - return self.inspector.info(obj, detail_level=detail_level) - - exist = sci.run('exists("%s")' % obj) - if exist == 0: - return info - - typeof = sci._eval('typeof(%s)' % obj) - lookup = dict(st="structure array", ce="cell array", - fptr="built-in Scilab function") - typeof = lookup.get(typeof, typeof) - - var = None - if typeof in ['function', 'built-in Scilab function']: - docstring = sci._get_doc(obj) - else: - docstring = 'A %s' % typeof - try: - var = sci.get(obj) - except Scilab2PyError: - pass - - if typeof == 'function': - source = sci._eval('fun2string(%s)' % obj) - source = source.replace('!', '').splitlines() - source = '\n'.join(source[::2]) - else: - source = docstring + elif info['docstring'] is not None: + displayfields.append(("Docstring", info["docstring"])) - info['found'] = True - info['docstring'] = docstring - info['type_name'] = typeof.capitalize() - info['source'] = source - info['string_form'] = obj if var is None else str(var) + # Info for objects: + else: + add_fields(inspector.pinfo_fields_obj) + # Finally send to printer/pager: + if displayfields: + return inspector._format_fields(displayfields) + + +def _get_scilab_info(scilab, inspector, obj, detail_level): + info = dict(argspec=None, base_class=None, call_def=None, + call_docstring=None, class_docstring=None, + definition=None, docstring=None, file=None, + found=False, init_definition=None, + init_docstring=None, isalias=0, isclass=None, + ismagic=0, length=None, name='', namespace=None, + source=None, string_form=None, type_name='') + + sci = scilab + + if obj in dir(sci): + obj = getattr(sci, obj) + return inspector.info(obj, detail_level=detail_level) + + exist = sci._eval('exists("%s");' % obj) + if exist == 0 or exist is None: return info + typeof = sci._eval('typeof(%s);' % obj) or 'Error' + lookup = dict(st="structure array", ce="cell array", + fptr="built-in Scilab function") + typeof = lookup.get(typeof, typeof) + + var = None + if typeof in ['function', 'built-in Scilab function']: + docstring = sci._get_doc(obj) or '' + + if typeof == 'built-in Scilab function': + before = """Use run("help %s") for full docs.""" % obj + after = "Type `help %s` to bring up the Help Browser" % obj + docstring = docstring.replace(before, after) + + else: + docstring = 'A %s' % typeof + try: + var = sci.get(obj) + except Scilab2PyError: + pass + + source = docstring + + if typeof == 'function': + source = sci._eval('fun2string(%s);' % obj) or '' + source = source.replace('!', '').splitlines() + source = '\n'.join(source[::2]) + + info['found'] = True + info['docstring'] = docstring + info['type_name'] = typeof.capitalize() + info['source'] = source + info['string_form'] = obj if var is None else str(var) + + return info + + +def _listdir(root): + "List directory 'root' appending the path separator to subdirs." + res = [] + for name in os.listdir(root): + path = os.path.join(root, name) + if os.path.isdir(path): + name += os.sep + res.append(name) + return res + + +def _complete_path(path=None): + """Perform completion of filesystem path. + + http://stackoverflow.com/questions/5637124/tab-completion-in-pythons-raw-input + """ + if not path: + return _listdir('.') + dirname, rest = os.path.split(path) + tmp = dirname if dirname else '.' + res = [os.path.join(dirname, p) + for p in _listdir(tmp) if p.startswith(rest)] + # more than one match, or single match which does not exist (typo) + if len(res) > 1 or not os.path.exists(path): + return res + # resolved to a single directory, so return list of files below it + if os.path.isdir(path): + return [os.path.join(path, p) for p in _listdir(path)] + # exact file match terminates this completion + return [path + ' '] + + if __name__ == '__main__': from IPython.kernel.zmq.kernelapp import IPKernelApp IPKernelApp.launch_instance(kernel_class=ScilabKernel) |