def restart_euslisp_process(self): program = self.euslisp.program init_file = self.euslisp.init_file color = self.euslisp.color self.euslisp.stop() self.euslisp = EuslispProcess(program, init_file, color=color) self.euslisp.start()
def __init__(self, *args, **kwargs): self.euslisp = EuslispProcess(*args, **kwargs) self.close_request = Event() self.euslisp.start() self.command_id = None self.package = None self.debugger = []
def restart_euslisp_process(self): program = self.euslisp.program init_file = self.euslisp.init_file on_output = self.euslisp.on_output color = self.euslisp.color self.euslisp.stop() self.euslisp = EuslispProcess(program, init_file, on_output=on_output, color=color) self.euslisp.start() # get rid of the first abort request on the reploop self.euslisp.reset() self.euslisp.accumulate_output = False
class EuslimeHandler(object): def __init__(self, *args, **kwargs): self.euslisp = EuslispProcess(*args, **kwargs) self.close_request = Event() self.euslisp.start() self.command_id = None self.package = None self.debugger = [] def restart_euslisp_process(self): program = self.euslisp.program init_file = self.euslisp.init_file color = self.euslisp.color self.euslisp.stop() self.euslisp = EuslispProcess(program, init_file, color=color) self.euslisp.start() def maybe_new_prompt(self): new_prompt = self.euslisp.exec_internal('(slime::slime-prompt)') if new_prompt: yield [Symbol(":new-package")] + new_prompt def arglist(self, func, cursor=None, form=None): if not isinstance(func, unicode) and not isinstance(func, str): log.debug("Expected string at: %s" % func) return None cmd = '(slime::autodoc "{0}" {1} (lisp:quote {2}))'.format( qstr(func), dumps_lisp(cursor), dumps_lisp(form)) result = self.euslisp.exec_internal(cmd) if isinstance(result, str): return [result, False] elif result: return [dumps(result), True] return None def _emacs_return_string(self, process, count, msg): self.euslisp.input(msg) yield [Symbol(":read-string"), 0, 1] def _emacs_interrupt(self, process): raise KeyboardInterrupt def swank_connection_info(self): version = self.euslisp.exec_internal('(slime::implementation-version)') name = self.euslisp.exec_internal( '(lisp:pathname-name lisp:*program-name*)') res = { 'pid': os.getpid(), 'style': False, 'encoding': { 'coding-systems': ['utf-8-unix', 'iso-latin-1-unix'], }, 'lisp-implementation': { 'type': name, 'name': name, 'version': version, 'program': False, }, 'machine': { 'type': platform.machine().upper(), 'version': platform.machine().upper(), }, 'package': { 'name': 'USER', 'prompt': name, }, 'version': "2.20", # swank version } yield EuslispResult(res) def swank_create_repl(self, sexp): res = self.euslisp.exec_internal('(slime::slime-prompt)') yield EuslispResult(res) def swank_repl_create_repl(self, *sexp): return self.swank_create_repl(sexp) def swank_buffer_first_change(self, filename): yield EuslispResult(False) def swank_eval(self, sexp): yield [Symbol(":read-string"), 0, 1] try: for out in self.euslisp.eval(sexp): if isinstance(out, EuslispResult): yield [Symbol(":read-aborted"), 0, 1] for val in self.maybe_new_prompt(): yield val yield out except Exception as e: yield [Symbol(":read-aborted"), 0, 1] raise e def swank_interactive_eval(self, sexp): return self.swank_eval(sexp) def swank_interactive_eval_region(self, sexp): return self.swank_eval(sexp) def swank_repl_listener_eval(self, sexp): if self.debugger: return self.swank_throw_to_toplevel() return self.swank_eval(sexp) def swank_pprint_eval(self, sexp): return self.swank_eval(sexp) def swank_autodoc(self, sexp, _=None, line_width=None): """ (:emacs-rex (swank:autodoc '("ql:quickload" "" swank::%cursor-marker%) :print-right-margin 102) "COMMON-LISP-USER" :repl-thread 19) (:return (:ok ("(quickload ===> systems <=== &key (verbose quicklisp-client:*quickload-verbose*) silent\n (prompt quicklisp-client:*quickload-prompt*) explain &allow-other-keys)" t)) 19) """ try: # unquote if isinstance(sexp, Quoted): # For instance in emacs 27 sexp = sexp.value() else: sexp = sexp[1] # [Symbol('quote'), [ ... ]] scope, cursor = current_scope(sexp) log.debug("scope: %s, cursor: %s" % (scope, cursor)) assert cursor > 0 func = scope[0] scope = scope[:-1] # remove marker result = self.arglist(func, cursor, scope) if result: yield EuslispResult(result) else: yield EuslispResult([Symbol(":not-available"), True]) except Exception: log.error(traceback.format_exc()) yield EuslispResult([Symbol(":not-available"), True]) def swank_operator_arglist(self, func, pkg): # (swank:operator-arglist "format" "USER") result = self.arglist(func) if result: result = result[0] yield EuslispResult(result) def swank_completions(self, start, pkg): if start and start[0] == ':': return self.swank_completions_for_keyword(start, None) else: return self.swank_simple_completions(start, pkg) # return self.swank_fuzzy_completions(start, pkg, ':limit', 300, # ':time-limit-in-msec', 1500) def swank_simple_completions(self, start, pkg): # (swank:simple-completions "vector-" (quote "USER")) cmd = '(slime::slime-find-symbol "{0}")'.format(qstr(start)) yield EuslispResult(self.euslisp.exec_internal(cmd)) def swank_fuzzy_completions(self, start, pkg, *args): # Unsupported. Use swank_simple_completions instead yield EuslispResult([None, None]) def swank_completions_for_keyword(self, start, sexp): if sexp: sexp = sexp[1] # unquote scope, _ = current_scope(sexp) if scope: scope = scope[:-1] # remove marker if scope[-1] in ['', u'']: # remove null string scope = scope[:-1] else: scope = None cmd = '(slime::slime-find-keyword "{0}" (lisp:quote {1}))'.format( qstr(start), dumps_lisp(scope)) yield EuslispResult(self.euslisp.exec_internal(cmd)) def swank_completions_for_character(self, start): cmd = '(slime::slime-find-character "{0}")'.format(qstr(start)) yield EuslispResult(self.euslisp.exec_internal(cmd)) def swank_complete_form(self, *args): # (swank:complete-form # (quote ("float-vector" swank::%cursor-marker%)) return def swank_quit_lisp(self, *args): self.euslisp.stop() self.close_request.set() def swank_backtrace(self, start, end): res = self.euslisp.get_callstack(end) yield EuslispResult(res[start:]) def swank_throw_to_toplevel(self): lvl = len(self.debugger) return self.swank_invoke_nth_restart_for_emacs(lvl, 0) def swank_invoke_nth_restart_for_emacs(self, level, num): deb = self.debugger.pop(level - 1) res_dict = deb.restarts_dict def check_key(key): return key in res_dict and num == res_dict[key] if check_key('RESTART'): self.debugger = [] self.restart_euslisp_process() elif check_key('CONTINUE'): pass elif check_key('QUIT'): self.debugger = [] self.euslisp.reset() else: log.error("Restart not found!") msg = deb.message.split(self.euslisp.delim)[0] msg = repr(msg.rsplit(' in ', 1)[0]) yield [Symbol(':debug-return'), 0, level, Symbol('nil')] yield [Symbol(':return'), {'abort': 'NIL'}, self.command_id] for val in self.maybe_new_prompt(): yield val yield [Symbol(':return'), {'abort': msg}, deb.id] def swank_swank_require(self, *sexp): return def swank_init_presentations(self, *sexp): return def swank_compile_string_for_emacs(self, cmd_str, *args): # (sexp buffer-name (:position 1) (:line 1) () ()) # FIXME: This does not compile actually, just eval instead. # Although compiling it would have effect on the Call Stack cmd_str = "(lisp:progn " + cmd_str + ")" messages = [] sexp = loads(cmd_str, nil=None) for exp in sexp[1:]: if len(exp) > 2: messages.append(dumps(exp[:2] + [None], none_as='...')) else: messages.append(dumps(exp)) list(self.euslisp.eval(cmd_str)) for msg in messages: yield [Symbol(":write-string"), "; Loaded {}\n".format(msg)] errors = [] seconds = 0.01 yield EuslispResult([Symbol(":compilation-result"), errors, True, seconds, None, None]) def swank_compile_notes_for_emacs(self, *args): return self.swank_compile_string_for_emacs(*args) def swank_compile_file_for_emacs(self, *args): return self.swank_compile_file_if_needed(*args) def swank_compile_file_if_needed(self, filename, loadp): # FIXME: This returns without checking/compiling the file errors = [] seconds = 0.01 yield EuslispResult([Symbol(":compilation-result"), errors, True, seconds, loadp, filename]) def swank_load_file(self, filename): yield [Symbol(":write-string"), "Loading file: %s ...\n" % filename] res = self.euslisp.exec_internal('(lisp:load "{0}")'.format( qstr(filename))) yield [Symbol(":write-string"), "Loaded.\n"] yield EuslispResult(res) def swank_inspect_current_condition(self): # (swank:inspect-current-condition) return def swank_sldb_abort(self, *args): return def swank_sldb_out(self, *args): return def swank_frame_locals_and_catch_tags(self, *args): return def swank_find_definitions_for_emacs(self, keyword): return def swank_describe_symbol(self, sym): cmd = '(slime::slime-describe-symbol "{0}")'.format( qstr(sym.strip())) yield EuslispResult(self.euslisp.exec_internal(cmd)) def swank_describe_function(self, func): return self.swank_describe_symbol(func) def swank_describe_definition_for_emacs(self, name, type): return self.swank_describe_symbol(name) def swank_swank_expand_1(self, form): cmd = '(slime::slime-macroexpand (lisp:quote {0}))'.format(form) yield EuslispResult(self.euslisp.exec_internal(cmd)) def swank_list_all_package_names(self, nicknames=None): cmd = '(slime::slime-all-packages {0})'.format( dumps_lisp(nicknames)) yield EuslispResult(self.euslisp.exec_internal(cmd)) def swank_apropos_list_for_emacs(self, key, external_only=None, case_sensitive=None, package=None): # ignore 'external_only' and 'case_sensitive' arguments package = package[-1] # unquote cmd = '(slime::slime-apropos-list "{0}" {1})'.format( qstr(key), dumps_lisp(package)) yield EuslispResult(self.euslisp.exec_internal(cmd)) def swank_set_package(self, name): cmd = '(slime::set-package "{0}")'.format(qstr(name)) yield EuslispResult(self.euslisp.exec_internal(cmd)) def swank_default_directory(self): res = self.euslisp.exec_internal('(lisp:pwd)') yield EuslispResult(res) def swank_set_default_directory(self, dir): cmd = '(lisp:progn (lisp:cd "{0}") (lisp:pwd))'.format(qstr(dir)) yield EuslispResult(self.euslisp.exec_internal(cmd))
class EuslimeHandler(object): def __init__(self, *args, **kwargs): self.euslisp = EuslispProcess(*args, **kwargs) self.close_request = Event() self.euslisp.start() self.package = None self.debugger = [] def restart_euslisp_process(self): program = self.euslisp.program init_file = self.euslisp.init_file on_output = self.euslisp.on_output color = self.euslisp.color self.euslisp.stop() self.euslisp = EuslispProcess(program, init_file, on_output=on_output, color=color) self.euslisp.start() # get rid of the first abort request on the reploop self.euslisp.reset() self.euslisp.accumulate_output = False def maybe_new_prompt(self): cmd = '(slime::slime-prompt)' new_prompt = self.euslisp.exec_internal(cmd, force_repl_socket=True) if new_prompt: yield [Symbol(":new-package")] + new_prompt def arglist(self, func, cursor=None, form=None): if not isinstance(func, unicode) and not isinstance(func, str): log.debug("Expected string at: %s" % func) return None cmd = '(slime::autodoc "{0}" {1} (lisp:quote {2}))'.format( qstr(func), dumps_lisp(cursor), dumps_lisp(form)) # Eval from repl_socket to cope with thread special symbols result = self.euslisp.exec_internal(cmd, force_repl_socket=True) if isinstance(result, str): return [result, False] elif result: return [dumps_vec(result), True] return None def _emacs_return_string(self, process, count, msg): self.euslisp.input(msg) if self.euslisp.read_busy: log.debug("Exitting read mode...") self.euslisp.read_busy = False if len(msg) % 128 == 0: # communicate when the message ends exactly at buffer end cmd = '(send slime::*slime-input-stream* :set-flag)' self.euslisp.exec_internal(cmd) if self.euslisp.read_mode: yield [Symbol(":read-string"), process, 1] def _emacs_interrupt(self, process): if self.euslisp.read_mode: # propagate the signal to all child processes os.kill(-os.getpgid(self.euslisp.process.pid), 2) else: # send the signal directly to the euslisp process self.euslisp.process.send_signal(signal.SIGINT) if isinstance(process, int): # during a :read-string call self.euslisp.read_busy = False yield [Symbol(":read-aborted"), process, 1] def swank_connection_info(self): cmd_version = '(slime::implementation-version)' cmd_name = '(lisp:pathname-name lisp:*program-name*)' version = self.euslisp.exec_internal(cmd_version) name = self.euslisp.exec_internal(cmd_name) res = { 'pid': os.getpid(), 'style': False, 'encoding': { 'coding-systems': ['utf-8-unix', 'iso-latin-1-unix'], }, 'lisp-implementation': { 'type': name, 'name': name, 'version': version, 'program': False, }, 'machine': { 'type': platform.machine().upper(), 'version': platform.machine().upper(), }, 'package': { 'name': 'USER', 'prompt': name, }, 'version': "2.20", # swank version } yield EuslispResult(res) def swank_create_repl(self, sexp): lock = self.euslisp.euslime_connection_lock log.debug('Acquiring lock: %s' % lock) lock.acquire() cmd = '(slime::slime-prompt)' try: res = self.euslisp.exec_internal(cmd, force_repl_socket=True) self.euslisp.accumulate_output = False yield EuslispResult(res) finally: if lock.locked(): lock.release() def swank_repl_create_repl(self, *sexp): return self.swank_create_repl(sexp) def swank_buffer_first_change(self, filename): yield EuslispResult(False) def swank_eval(self, sexp): lock = self.euslisp.euslime_connection_lock log.debug('Acquiring lock: %s' % lock) lock.acquire() try: for val in self.euslisp.eval(sexp): if isinstance(val, str): # Colors are not allowed in :repl-result formatting yield [ Symbol(":write-string"), no_color(val), Symbol(":repl-result") ] yield [ Symbol(":write-string"), "\n", Symbol(":repl-result") ] else: yield val if self.euslisp.read_mode or self.euslisp.read_busy: log.debug("Aborting read mode...") self.euslisp.read_mode = False self.euslisp.read_busy = False yield [Symbol(":read-aborted"), 0, 1] for val in self.maybe_new_prompt(): yield val yield EuslispResult(None) lock.release() except AbortEvaluation as e: log.info('Aborting evaluation...') if self.euslisp.read_mode: log.debug("Aborting read mode...") self.euslisp.read_mode = False yield [Symbol(":read-aborted"), 0, 1] for val in self.maybe_new_prompt(): yield val if lock.locked(): lock.release() if e.message: yield EuslispResult(e.message, response_type='abort') else: yield EuslispResult(None) except Exception as e: log.error(traceback.format_exc()) if self.euslisp.read_mode or self.euslisp.read_busy: log.debug("Aborting read mode...") self.euslisp.read_mode = False self.euslisp.read_busy = False yield [Symbol(":read-aborted"), 0, 1] if lock.locked(): lock.release() raise e def swank_interactive_eval(self, sexp): return self.swank_eval(sexp) def swank_interactive_eval_region(self, sexp): return self.swank_eval(sexp) def swank_repl_listener_eval(self, sexp): if self.debugger: return self.swank_throw_to_toplevel() return self.swank_eval(sexp) def swank_pprint_eval(self, sexp): return self.swank_eval(sexp) def swank_autodoc(self, sexp, _=None, line_width=None): """ (:emacs-rex (swank:autodoc '("ql:quickload" "" swank::%cursor-marker%) :print-right-margin 102) "COMMON-LISP-USER" :repl-thread 19) (:return (:ok ("(quickload ===> systems <=== &key (verbose quicklisp-client:*quickload-verbose*) silent\n (prompt quicklisp-client:*quickload-prompt*) explain &allow-other-keys)" t)) 19) from swank-arglists.lisp: Return a list of two elements. First, a string representing the arglist for the deepest subform in RAW-FORM that does have an arglist. Second, a boolean value telling whether the returned string can be cached. """ try: sexp = unquote(sexp) scope, cursor = current_scope(sexp) log.debug("scope: %s, cursor: %s" % (scope, cursor)) assert cursor > 0 func = scope[0] scope = scope[:-1] # remove marker result = self.arglist(func, cursor, scope) if result: yield EuslispResult(result) else: yield EuslispResult([Symbol(":not-available"), True]) except Exception: log.error(traceback.format_exc()) yield EuslispResult([Symbol(":not-available"), True]) def swank_operator_arglist(self, func, pkg): # (swank:operator-arglist "format" "USER") result = self.arglist(func) if result: result = result[0] yield EuslispResult(result) def swank_completions(self, start, pkg): if start and start[0] == ':': return self.swank_completions_for_keyword(start, None) else: return self.swank_simple_completions(start, pkg) # return self.swank_fuzzy_completions(start, pkg, ':limit', 300, # ':time-limit-in-msec', 1500) def swank_simple_completions(self, start, pkg): # (swank:simple-completions "vector-" (quote "USER")) pkg = unquote(pkg) cmd = '(slime::slime-find-symbol "{0}" "{1}")'.format( qstr(start), qstr(pkg)) yield EuslispResult(self.euslisp.exec_internal(cmd)) def swank_fuzzy_completions(self, start, pkg, *args): # Unsupported # Return a list of simple_completions in the fuzzy format gen = self.swank_simple_completions(start, pkg) simple_completions = gen.next().value if simple_completions: first_comp = simple_completions[0] simple_completions = [[x, 0, None, None] for x in first_comp] yield EuslispResult([simple_completions, None]) def swank_fuzzy_completion_selected(self, original_string, completion): yield EuslispResult(None) def swank_completions_for_keyword(self, start, sexp): if sexp: sexp = unquote(sexp) scope, _ = current_scope(sexp) if scope: scope = scope[:-1] # remove marker if scope[-1] in ['', u'']: # remove null string scope = scope[:-1] else: scope = None # Try to eval from repl_socket to cope with thread special symbols lock = self.euslisp.euslime_connection_lock force_repl = True # But use internal_socket when repl is not available if lock.locked(): log.warning('Euslisp process is busy! ' + 'Calculating completions on internal process instead') lock = self.euslisp.euslime_internal_connection_lock force_repl = False else: log.debug('Acquiring lock: %s' % lock) lock.acquire() cmd = '(slime::slime-find-keyword "{}" (lisp:quote {}) "{}")'.format( qstr(start), dumps_lisp(scope), qstr(self.package)) try: result = self.euslisp.exec_internal(cmd, force_repl_socket=force_repl) yield EuslispResult(result) finally: if force_repl and lock.locked(): lock.release() def swank_completions_for_character(self, start): cmd = '(slime::slime-find-character "{0}")'.format(qstr(start)) yield EuslispResult(self.euslisp.exec_internal(cmd)) def swank_complete_form(self, *args): # (swank:complete-form # (quote ("float-vector" swank::%cursor-marker%)) return def swank_quit_lisp(self, *args): self.euslisp.stop() self.close_request.set() def swank_backtrace(self, start, end): res = self.euslisp.get_callstack(end) yield EuslispResult(res[start:]) def swank_throw_to_toplevel(self): lvl = len(self.debugger) return self.swank_invoke_nth_restart_for_emacs(lvl, 0) def swank_invoke_nth_restart_for_emacs(self, level, num): # if everything goes well, it should be the self.debugger[level -1] deb = next(x for x in self.debugger if x.level == level) res_dict = deb.restarts_dict clear_stack = False def check_key(key): return key in res_dict and num == res_dict[key] def debug_return(db): msg = db.message.split(self.euslisp.delim)[0] msg = repr(msg.rsplit(' in ', 1)[0]) yield [Symbol(':debug-return'), 0, db.level, Symbol('nil')] yield [Symbol(':return'), {'abort': msg}, db.id] if check_key('QUIT'): clear_stack = True self.euslisp.reset() elif check_key('CONTINUE'): pass elif check_key('RESTART'): clear_stack = True self.restart_euslisp_process() else: log.error("Restart number %s not found!" % num) yield EuslispResult(None) return yield EuslispResult(None, response_type='abort') if clear_stack: for val in self.maybe_new_prompt(): yield val for db in reversed(self.debugger): for val in debug_return(db): yield val self.debugger = [] else: self.debugger.remove(deb) # Only test for new prompts if we are exitting the debugger if not self.debugger: for val in self.maybe_new_prompt(): yield val for val in debug_return(deb): yield val # Pop previous debugger, if any if self.debugger: yield self.debugger[-1].make_debug_response() def swank_sldb_return_from_frame(self, num, value): return def swank_restart_frame(self, num): return def swank_swank_require(self, *sexp): return def swank_swank_add_load_paths(self, *sexp): return def swank_init_presentations(self, *sexp): return def swank_compile_string_for_emacs(self, cmd_str, *args): # (sexp buffer-name (:position 1) (:line 1) () ()) # FIXME: This does not compile actually, just eval instead. # Although compiling it would have effect on the Call Stack cmd_str = "(lisp:progn " + cmd_str + ")" messages = [] sexp = loads(cmd_str, nil=None) for exp in sexp[1:]: if len(exp) > 2: messages.append(dumps(exp[:2] + [None], none_as='...')) else: messages.append(dumps(exp)) lock = self.euslisp.euslime_connection_lock log.debug('Acquiring lock: %s' % lock) lock.acquire() try: for res in self.euslisp.eval(cmd_str): if isinstance(res, list): yield res for msg in messages: yield [Symbol(":write-string"), "; Loaded {}\n".format(msg)] errors = [] seconds = 0.01 yield EuslispResult([ Symbol(":compilation-result"), errors, True, seconds, None, None ]) lock.release() except AbortEvaluation as e: if lock.locked(): lock.release() log.info('Aborting evaluation...') # Force-print the message, which is # by default only displayed on the minibuffer if e.message: yield [ Symbol(":write-string"), "; Evaluation aborted on {}\n".format(e.message), Symbol(":repl-result") ] yield EuslispResult(None) except Exception: if lock.locked(): lock.release() raise def swank_compile_notes_for_emacs(self, *args): return self.swank_compile_string_for_emacs(*args) def swank_compile_file_for_emacs(self, *args): return self.swank_compile_file_if_needed(*args) def swank_compile_file_if_needed(self, filename, loadp): # FIXME: This returns without checking/compiling the file errors = [] seconds = 0.01 yield EuslispResult([ Symbol(":compilation-result"), errors, True, seconds, loadp, filename ]) def swank_load_file(self, filename): lock = self.euslisp.euslime_connection_lock log.debug('Acquiring lock: %s' % lock) lock.acquire() yield [Symbol(":write-string"), "Loading file: %s ...\n" % filename] try: cmd = '(slime::load-file-and-tags "{0}")'.format(qstr(filename)) output_str = '' for r in self.euslisp.eval(cmd): if isinstance(r, list): # read-string yield r if isinstance(r, str): output_str += r res = loads(output_str, nil=None) if res == Symbol("lisp:nil") or res == Symbol("nil"): res = None yield [Symbol(":write-string"), "Loaded.\n"] yield EuslispResult(res) lock.release() except AbortEvaluation as e: if lock.locked(): lock.release() log.info('Aborting evaluation...') # Force-print the message, which is # by default only displayed on the minibuffer if e.message: yield [ Symbol(":write-string"), "; Evaluation aborted on {}\n".format(e.message), Symbol(":repl-result") ] yield EuslispResult(None) except Exception: if lock.locked(): lock.release() raise def swank_inspect_current_condition(self): # (swank:inspect-current-condition) return def swank_sldb_abort(self, *args): return def swank_sldb_out(self, *args): return def swank_frame_locals_and_catch_tags(self, *args): # [RET] on sldb Backtrace entry # Display local bindings at the given frame # e.g. (:return (:ok (((:name "NUMBER" :id 0 :value "NIL")) nil)) 7) return def swank_find_definitions_for_emacs(self, keyword): return def swank_find_tag_name_for_emacs(self, name, pkg): cmd = '(slime::find-tag-name-for-emacs "{0}" "{1}")'.format( qstr(name), qstr(pkg)) yield EuslispResult(self.euslisp.exec_internal(cmd)) def swank_describe_symbol(self, sym): cmd = '(slime::slime-describe-symbol "{0}" "{1}")'.format( qstr(sym.strip()), qstr(self.package)) yield EuslispResult(self.euslisp.exec_internal(cmd)) def swank_describe_function(self, func): return self.swank_describe_symbol(func) def swank_describe_definition_for_emacs(self, name, type): return self.swank_describe_symbol(name) def swank_swank_expand_1(self, form): cmd = '(slime::slime-macroexpand "{0}" "{1}")'.format( qstr(form), qstr(self.package)) yield EuslispResult(self.euslisp.exec_internal(cmd)) def swank_list_all_package_names(self, nicknames=None): cmd = '(slime::slime-all-packages {0})'.format(dumps_lisp(nicknames)) yield EuslispResult(self.euslisp.exec_internal(cmd)) def swank_apropos_list_for_emacs(self, key, external_only=None, case_sensitive=None, package=None): # ignore 'external_only' and 'case_sensitive' arguments package = unquote(package) cmd = '(slime::slime-apropos-list "{0}" {1})'.format( qstr(key), dumps_lisp(package)) yield EuslispResult(self.euslisp.exec_internal(cmd)) def swank_repl_clear_repl_variables(self): lock = self.euslisp.euslime_connection_lock log.debug('Acquiring lock: %s' % lock) if lock.locked(): log.error('Could not acquire lock: %s' % lock) yield EuslispResult("'Process busy'", response_type='abort') return lock.acquire() try: cmd = '(slime::clear-repl-variables)' res = self.euslisp.exec_internal(cmd, force_repl_socket=True) yield EuslispResult(res) lock.release() finally: if lock.locked(): lock.release() def swank_clear_repl_results(self): return def swank_set_package(self, name): lock = self.euslisp.euslime_connection_lock log.debug('Acquiring lock: %s' % lock) if not check_lock(lock, 0.5): log.error('Could not acquire lock: %s' % lock) yield [ Symbol(":write-string"), "; No responses from inferior process\n" ] yield EuslispResult(False, response_type='abort') return lock.acquire() try: cmd = '(slime::set-package "{0}")'.format(qstr(name)) res = self.euslisp.exec_internal(cmd, force_repl_socket=True) yield EuslispResult(res) except AbortEvaluation: # the abort signal sometimes comes earlier than the # evaluation result, for example when attaching a gdb # instance and passing a SIGINT. # Retry the evaluation in such cases log.info('AbortEvaluation received during swank_set_package.' + ' Retrying...') res = self.euslisp.exec_internal(cmd, force_repl_socket=True) yield EuslispResult(res) finally: if lock.locked(): lock.release() def swank_default_directory(self): cmd = '(lisp:pwd)' yield EuslispResult(self.euslisp.exec_internal(cmd)) def swank_set_default_directory(self, dir): cmd = '(lisp:progn (lisp:cd "{0}") (lisp:pwd))'.format(qstr(dir)) yield EuslispResult(self.euslisp.exec_internal(cmd))