def wrapper(self, *args, **kwargs): if not self.kernel_client.check_connection_or_warn(): echom( f"Pythonx _jupyter_session.{fct.__name__}() needs a connected client", style='Error') return None return fct(self, *args, **kwargs)
def update_msgs(self): """Launch pending messages grabbers (Sync but not for long) Param: console (boolean): should I update console prompt (boolean): should I update prompt last_cmd (string): not used already """ # Open the Jupyter terminal in vim, and move cursor to it if -1 == vim.eval('jupyter#monitor_console#OpenJupyterTerm()'): echom('__jupyter_term__ failed to open!', 'Error') return # Define time: thread (additive) sleep and timer wait timer_intervals = self.si.vim_client.get_timer_intervals() thread_intervals = [50] for i in range(len(timer_intervals) - 1): thread_intervals.append(timer_intervals[i + 1] - timer_intervals[i] - 50) # Create thread self.si.sync.start_thread(target=self.thread_fetch_msgs, args=[thread_intervals]) # Launch timers for sleep_ms in timer_intervals: vim_cmd = ('call timer_start(' + str(sleep_ms) + ', "jupyter#monitor_console#UpdateConsoleBuffer")') vim.command(vim_cmd)
def run_file(self, flags='', filename=''): """Run an entire file in the kernel. .. note:: vim command `:JupyterRunFile`. Parameters ---------- flags : str, optional, default='' Flags to pass with language-specific `run` command. filename : str, optional, default='' Specific filename to run. """ # Special cpython cases if self.kernel_client.kernel_info['kernel_type'] == 'python': return self.run_file_in_ipython(flags=flags, filename=filename) # Message warning to user if flags != '': echom( 'RunFile in other kernel than "python" doesn\'t support flags.' ' All arguments except the file location will be ignored.', style='Error') # Get command and read file if not implemented cmd_run = self.lang.run_file.format(filename) if cmd_run == '-1': with open(filename, 'r') as file_run: cmd_run = file_run.read() # Run it return self.run_command(cmd_run)
def timer_write_console_msgs(self): """Write kernel <-> vim messages to console buffer""" # Check in if self.si.sync.line_queue.empty(): return if not self.si.vim_client.monitor_console and not self.si.vim_client.verbose: return # Get buffer (same indexes as vim) if self.si.vim_client.monitor_console: b_nb = int(vim.eval('bufnr("__jupyter_term__")')) b = vim.buffers[b_nb] # Append mesage to jupyter terminal buffer while not self.si.sync.line_queue.empty(): msg = self.si.sync.line_queue.get_nowait() for line in msg.splitlines(): line = unquote_string(str_to_vim(line)) if self.si.vim_client.monitor_console: b.append(line) if self.si.vim_client.verbose: echom(line) # Update view (moving cursor) if self.si.vim_client.monitor_console: cur_win = vim.eval('win_getid()') term_win = vim.eval('bufwinid({})'.format(str(b_nb))) vim.command('call win_gotoid({})'.format(term_win)) vim.command('normal! G') vim.command('call win_gotoid({})'.format(cur_win))
def disconnect_from_kernel(self): """Disconnect from the kernel client (Sync). .. note:: vim command `:JupyterDisconnect`. """ self.kernel_client.disconnnect() echom(f"Disconnected: {self.kernel_client.kernel_info['id']}", style='Directory')
def timer_echom(self): """Call echom sync on all messages in queue.""" # Check in if self.message_queue.empty(): return # Show user the force while not self.message_queue.empty(): (arg, args) = self.message_queue.get_nowait() echom(arg, **args) # Restore peace in the galaxy vim.command('redraw')
def check_connection_or_warn(self): """Echo warning if not connected. Returns ------- bool True if client is connected, False if not. """ if self.check_connection(): return True echom( 'WARNING: Not connected to Jupyter!' '\nRun :JupyterConnect to find the kernel', style='WarningMsg') return False
def change_directory(self, directory): """Change current working directory in kernel. .. note:: vim command `:JupyterCd`. Parameters ---------- directory : str Directory into which to change. """ msg = self.lang.cd.format(directory) msg_id = self.kernel_client.send(msg) # Print cwd try: cwd = self.kernel_client.send_code_and_get_reply(self.lang.cwd) echom('CWD: ', style='Question') vim.command("echon \"{}\"".format(cwd)) except Exception: pass # Return to decorators return (msg, msg_id)
def get_kernel_info(self, language): """Explicitly ask the jupyter kernel for its pid .. note:: Thread: <- cfile <- vim_pid -> lang -> kernel_pid Returns ------- dict dict with keys: {'kernel_type', 'pid', 'cwd', 'hostname'} """ # Check in if self.kernel_info['kernel_type'] not in list_languages(): echom( 'I don' 't know how to get infos for a Jupyter kernel of type "{}"'. format(self.kernel_info['kernel_type']), 'WarningMsg') # Fill kernel_info self.kernel_info.update({ 'connection_file': self.cfile, 'id': match_kernel_id(self.cfile), # int id of cfile # Get from kernel info 'pid': self.send_code_and_get_reply(language.pid), # PID of kernel 'cwd': self.send_code_and_get_reply(language.cwd), 'hostname': self.send_code_and_get_reply(language.hostname), }) # Return return self.kernel_info
def signal_kernel(self, sig=signal.SIGTERM): """Send a signal to the remote kernel via the kill command. This command side steps the non-functional jupyter interrupt. Only works on posix. .. note:: vim command `:JupyterTerminateKernel` Parameters ---------- sig : :obj:`signal`, optional, default=signal.SIGTERM Signal to send to the kernel. """ # Clause: valid signal if isinstance(sig, str): try: sig = getattr(signal, sig) except (AttributeError, NameError) as err: echom(f"Cannot send signal {sig} on this OS: {err}", style='Error') return # Clause: valid pid pid = self.kernel_client.kernel_info['pid'] if not is_integer(pid): echom(f"Cannot kill kernel: pid is not a number {pid}", style='Error') return pid = int(pid) if pid < 1: echom(f"Cannot kill kernel: unknown pid retrieved {pid}", style='Error') return # Kill process try: kill(pid, int(sig)) echom("kill pid {p:d} with signal #{v:d}, {n:s}".format( p=pid, v=sig.value, n=sig.name), style='WarningMsg') except ProcessLookupError: echom( ("pid {p:d} does not exist! " + "Kernel may have been terminated by outside process").format( p=pid, style='Error')) except OSError as err: echom("signal #{v:d}, {n:s} failed to kill pid {p:d}".format( v=sig.value, n=sig.name, p=pid), style='Error') raise err # Delete connection file sig_list = [signal.SIGTERM] if system() != 'Windows': sig_list.append(signal.SIGKILL) if sig in sig_list: try: remove(self.kernel_client.cfile) except OSError: pass