Exemple #1
0
def _wizard(ns):
    env = builtins.__xonsh__.env
    shell = builtins.__xonsh__.shell.shell
    fname = env.get("XONSHRC")[-1] if ns.file is None else ns.file
    no_wiz = os.path.join(env.get("XONSH_CONFIG_DIR"), "no-wizard")
    w = make_xonfig_wizard(default_file=fname,
                           confirm=ns.confirm,
                           no_wizard_file=no_wiz)
    tempenv = {"PROMPT": "", "XONSH_STORE_STDOUT": False}
    pv = wiz.PromptVisitor(w, store_in_history=False, multiline=False)

    @contextlib.contextmanager
    def force_hide():
        if env.get("XONSH_STORE_STDOUT") and hasattr(shell, "_force_hide"):
            orig, shell._force_hide = shell._force_hide, False
            yield
            shell._force_hide = orig
        else:
            yield

    with force_hide(), env.swap(tempenv):
        try:
            pv.visit()
        except (KeyboardInterrupt, Exception):
            print()
            print_exception()
Exemple #2
0
def transform_command(src, show_diff=True):
    """Returns the results of firing the precommand handles."""
    i = 0
    limit = sys.getrecursionlimit()
    lst = ""
    raw = src
    while src != lst:
        lst = src
        srcs = events.on_transform_command.fire(cmd=src)
        for s in srcs:
            if s != lst:
                src = s
                break
        i += 1
        if i == limit:
            print_exception(
                "Modifications to source input took more than "
                "the recursion limit number of iterations to "
                "converge."
            )
    debug_level = builtins.__xonsh__.env.get("XONSH_DEBUG")
    if show_diff and debug_level > 1 and src != raw:
        sys.stderr.writelines(
            difflib.unified_diff(
                raw.splitlines(keepends=True),
                src.splitlines(keepends=True),
                fromfile="before precommand event",
                tofile="after precommand event",
            )
        )
    return src
Exemple #3
0
 def wait(self, timeout=None):
     """Runs the function and returns the result. Timeout argument only
     present for API compatibility.
     """
     if self.f is None:
         return 0
     env = builtins.__xonsh__.env
     enc = env.get("XONSH_ENCODING")
     err = env.get("XONSH_ENCODING_ERRORS")
     spec = self._wait_and_getattr("spec")
     # set file handles
     if self.stdin is None:
         stdin = None
     else:
         if isinstance(self.stdin, int):
             inbuf = io.open(self.stdin, "rb", -1)
         else:
             inbuf = self.stdin
         stdin = io.TextIOWrapper(inbuf, encoding=enc, errors=err)
     stdout = self._pick_buf(self.stdout, sys.stdout, enc, err)
     stderr = self._pick_buf(self.stderr, sys.stderr, enc, err)
     # run the actual function
     try:
         r = self.f(self.args, stdin, stdout, stderr, spec, spec.stack)
     except Exception:
         xt.print_exception()
         r = 1
     self.returncode = parse_proxy_return(r, stdout, stderr)
     safe_flush(stdout)
     safe_flush(stderr)
     return self.returncode
Exemple #4
0
    def _get_prompt_tokens(self, env_name: str, prompt_name: str, **kwargs):
        env = builtins.__xonsh__.env  # type:ignore
        p = env.get(env_name)

        if not p and "default" in kwargs:
            return kwargs.pop("default")

        try:
            p = self.prompt_formatter(template=p,
                                      threaded=env["ENABLE_ASYNC_PROMPT"],
                                      prompt_name=prompt_name)
        except Exception:  # pylint: disable=broad-except
            print_exception()

        p, osc_tokens = remove_ansi_osc(p)

        if kwargs.get("handle_osc_tokens"):
            # handle OSC tokens
            for osc in osc_tokens:
                if osc[2:4] == "0;":
                    env["TITLE"] = osc[4:-1]
                else:
                    print(osc, file=sys.__stdout__, flush=True)

        toks = partial_color_tokenize(p)

        return tokenize_ansi(PygmentsTokens(toks))
Exemple #5
0
    def __init__(self, specs):
        """
        Parameters
        ----------
        specs : list of SubprocSpec
            Process specifications

        Attributes
        ----------
        spec : SubprocSpec
            The last specification in specs
        proc : Popen-like
            The process in procs
        ended : bool
            Boolean for if the command has stopped executing.
        input : str
            A string of the standard input.
        output : str
            A string of the standard output.
        errors : str
            A string of the standard error.
        lines : list of str
            The output lines
        starttime : floats or None
            Pipeline start timestamp.
        """
        self.starttime = None
        self.ended = False
        self.procs = []
        self.specs = specs
        self.spec = specs[-1]
        self.captured = specs[-1].captured
        self.input = self._output = self.errors = self.endtime = None
        self._closed_handle_cache = {}
        self.lines = []
        self._stderr_prefix = self._stderr_postfix = None
        self.term_pgid = None

        background = self.spec.background
        pipeline_group = None
        for spec in specs:
            if self.starttime is None:
                self.starttime = time.time()
            try:
                proc = spec.run(pipeline_group=pipeline_group)
            except Exception:
                xt.print_exception()
                self._return_terminal()
                self.proc = None
                return
            if (proc.pid and pipeline_group is None and not spec.is_proxy
                    and self.captured != "object"):
                pipeline_group = proc.pid
                if update_fg_process_group(pipeline_group, background):
                    self.term_pgid = pipeline_group
            self.procs.append(proc)
        self.proc = self.procs[-1]
Exemple #6
0
def _failover_template_format(template):
    if callable(template):
        try:
            # Exceptions raises from function of producing $PROMPT
            # in user's xonshrc should not crash xonsh
            return template()
        except Exception:
            xt.print_exception()
            return "$ "
    return template
Exemple #7
0
 def _no_cache_field_value(self, field, field_value, **_):
     try:
         value = field_value() if callable(field_value) else field_value
         self.cache[field_value] = value
     except Exception:
         print("prompt: error: on field {!r}"
               "".format(field),
               file=sys.stderr)
         xt.print_exception()
         value = "{{BACKGROUND_RED}}{{ERROR:{}}}{{RESET}}".format(field)
     return value
Exemple #8
0
 def wrapper(*args, **kwargs):
     anchor = Path(os.getcwd()).anchor
     os.chdir(anchor)
     try:
         out = func(*args, **kwargs)
     finally:
         try:
             pwd = env.get("PWD", anchor)
             os.chdir(pwd)
         except (FileNotFoundError, NotADirectoryError):
             print_exception()
             newpath = _chdir_up(pwd)
             builtins.__xonsh__.env["PWD"] = newpath
             raise KeyboardInterrupt
     return out
Exemple #9
0
    def complete(self, prefix, line, begidx, endidx, ctx=None):
        """Complete the string, given a possible execution context.

        Parameters
        ----------
        prefix : str
            The string to match
        line : str
            The line that prefix appears on.
        begidx : int
            The index in line that prefix starts on.
        endidx : int
            The index in line that prefix ends on.
        ctx : Iterable of str (ie dict, set, etc), optional
            Names in the current execution context.

        Returns
        -------
        rtn : list of str
            Possible completions of prefix, sorted alphabetically.
        lprefix : int
            Length of the prefix to be replaced in the completion.
        """
        ctx = ctx or {}
        for func in builtins.__xonsh__.completers.values():
            try:
                out = func(prefix, line, begidx, endidx, ctx)
            except StopIteration:
                return set(), len(prefix)
            except Exception as e:
                print_exception(
                    f"Completer {func.__name__} raises exception when get "
                    f"(prefix={repr(prefix)}, line={repr(line)}, begidx={repr(begidx)}, endidx={repr(endidx)}):\n"
                    f"{e}"
                )
                return set(), len(prefix)
            if isinstance(out, cabc.Sequence):
                res, lprefix = out
            else:
                res = out
                lprefix = len(prefix)
            if res is not None and len(res) != 0:

                def sortkey(s):
                    return s.lstrip(''''"''').lower()

                return tuple(sorted(res, key=sortkey)), lprefix
        return set(), lprefix
Exemple #10
0
def xontribs_load(names, verbose=False):
    """Load xontribs from a list of names"""
    ctx = builtins.__xonsh__.ctx
    res = ExitCode.OK
    for name in names:
        if verbose:
            print("loading xontrib {0!r}".format(name))
        try:
            update_context(name, ctx=ctx)
        except Exception:
            res = ExitCode.INIT_FAILED
            print_exception("Failed to load xontrib {}.".format(name))
    if hasattr(update_context, "bad_imports"):
        res = ExitCode.NOT_FOUND
        prompt_xontrib_install(update_context.bad_imports)
        del update_context.bad_imports
    return res
Exemple #11
0
 def prompt(self):
     """Obtains the current prompt string."""
     if self.need_more_lines:
         if self.mlprompt is None:
             try:
                 self.mlprompt = multiline_prompt()
             except Exception:  # pylint: disable=broad-except
                 print_exception()
                 self.mlprompt = "<multiline prompt error> "
         return self.mlprompt
     env = builtins.__xonsh__.env  # pylint: disable=no-member
     p = env.get("PROMPT")
     try:
         p = self.prompt_formatter(p)
     except Exception:  # pylint: disable=broad-except
         print_exception()
     self.settitle()
     return p
Exemple #12
0
    def default(self, line):
        """Implements code execution."""
        line = line if line.endswith("\n") else line + "\n"
        src, code = self.push(line)
        if code is None:
            return

        events.on_precommand.fire(cmd=src)

        env = builtins.__xonsh__.env
        hist = builtins.__xonsh__.history  # pylint: disable=no-member
        ts1 = None
        enc = env.get("XONSH_ENCODING")
        err = env.get("XONSH_ENCODING_ERRORS")
        tee = Tee(encoding=enc, errors=err)
        try:
            ts0 = time.time()
            run_compiled_code(code, self.ctx, None, "single")
            ts1 = time.time()
            if hist is not None and hist.last_cmd_rtn is None:
                hist.last_cmd_rtn = 0  # returncode for success
        except XonshError as e:
            print(e.args[0], file=sys.stderr)
            if hist is not None and hist.last_cmd_rtn is None:
                hist.last_cmd_rtn = 1  # return code for failure
        except Exception:  # pylint: disable=broad-except
            print_exception()
            if hist is not None and hist.last_cmd_rtn is None:
                hist.last_cmd_rtn = 1  # return code for failure
        finally:
            ts1 = ts1 or time.time()
            tee_out = tee.getvalue()
            self._append_history(inp=src, ts=[ts0, ts1], tee_out=tee_out)
            self.accumulated_inputs += src
            if (
                tee_out
                and env.get("XONSH_APPEND_NEWLINE")
                and not tee_out.endswith(os.linesep)
            ):
                print(os.linesep, end="")
            tee.close()
            self._fix_cwd()
        if builtins.__xonsh__.exit:  # pylint: disable=no-member
            return True
Exemple #13
0
def _xhj_get_history_files(sort=True, newest_first=False):
    """Find and return the history files. Optionally sort files by
    modify time.
    """
    data_dir = builtins.__xonsh__.env.get("XONSH_DATA_DIR")
    data_dir = xt.expanduser_abs_path(data_dir)
    try:
        files = [
            os.path.join(data_dir, f)
            for f in os.listdir(data_dir)
            if f.startswith("xonsh-") and f.endswith(".json")
        ]
    except OSError:
        files = []
        if builtins.__xonsh__.env.get("XONSH_DEBUG"):
            xt.print_exception("Could not collect xonsh history files.")
    if sort:
        files.sort(key=lambda x: os.path.getmtime(x), reverse=newest_first)
    return files
Exemple #14
0
 def _push(self, line):
     """Pushes a line onto the buffer and compiles the code in a way that
     enables multiline input.
     """
     code = None
     self.buffer.append(line)
     if self.need_more_lines:
         return None, code
     src = "".join(self.buffer)
     src = transform_command(src)
     try:
         code = self.execer.compile(src,
                                    mode="single",
                                    glbs=self.ctx,
                                    locs=None)
         self.reset_buffer()
     except Exception:  # pylint: disable=broad-except
         self.reset_buffer()
         print_exception()
         return src, None
     return src, code
Exemple #15
0
def ulimit(args, stdin, stdout, stderr):
    """An ulimit implementation"""
    rc, actions = _ul_parse_args(args, stderr)

    # could not parse arguments; message already printed to stderr
    if not rc:
        return 1
    # args OK, but nothing to do; print help
    elif not actions:
        _ul_show_usage(stdout)
        return 0

    # if there's more than one resource to be printed, use the long format
    long = len([a for a in actions if a[0] == _ul_show]) > 1
    try:
        for fn, args in actions:
            fn(stdout=stdout, long=long, **args)
        return 0
    except:
        print_exception()
        return 2
Exemple #16
0
 def compile(self, src):
     """Compiles source code and returns the (possibly modified) source and
     a valid code object.
     """
     _cache = should_use_cache(self.execer, "single")
     if _cache:
         codefname = code_cache_name(src)
         cachefname = get_cache_filename(codefname, code=True)
         usecache, code = code_cache_check(cachefname)
         if usecache:
             self.reset_buffer()
             return src, code
     lincont = get_line_continuation()
     if src.endswith(lincont + "\n"):
         self.need_more_lines = True
         return src, None
     try:
         code = self.execer.compile(src, mode="single", glbs=self.ctx, locs=None)
         if _cache:
             update_cache(code, cachefname)
         self.reset_buffer()
     except SyntaxError:
         partial_string_info = check_for_partial_string(src)
         in_partial_string = (
             partial_string_info[0] is not None and partial_string_info[1] is None
         )
         if (src == "\n" or src.endswith("\n\n")) and not in_partial_string:
             self.reset_buffer()
             print_exception()
             return src, None
         self.need_more_lines = True
         code = None
     except Exception:  # pylint: disable=broad-except
         self.reset_buffer()
         print_exception()
         code = None
     return src, code
Exemple #17
0
    def fire(self, **kwargs):
        """
        Fires an event, calling registered handlers with the given arguments. A non-unique iterable
        of the results is returned.

        Each handler is called immediately. Exceptions are turned in to warnings.

        Parameters
        ----------
        **kwargs :
            Keyword arguments to pass to each handler

        Returns
        -------
        vals : iterable
            Return values of each handler. If multiple handlers return the same value, it will
            appear multiple times.
        """
        vals = []
        self._firing = True
        for handler in self._filterhandlers(self._handlers, **kwargs):
            try:
                rv = handler(**kwargs)
            except Exception:
                print_exception("Exception raised in event handler; ignored.")
            else:
                vals.append(rv)
        # clean up
        self._firing = False
        if self._delayed_adds is not None:
            self._handlers.update(self._delayed_adds)
            self._delayed_adds = None
        if self._delayed_discards is not None:
            self._handlers.difference_update(self._delayed_discards)
            self._delayed_discards = None
        return vals
Exemple #18
0
    def singleline(self,
                   auto_suggest=None,
                   enable_history_search=True,
                   multiline=True,
                   **kwargs):
        """Reads a single line of input from the shell. The store_in_history
        kwarg flags whether the input should be stored in PTK's in-memory
        history.
        """
        events.on_pre_prompt_format.fire()
        env = builtins.__xonsh__.env
        mouse_support = env.get("MOUSE_SUPPORT")
        auto_suggest = auto_suggest if env.get("AUTO_SUGGEST") else None
        refresh_interval = env.get("PROMPT_REFRESH_INTERVAL")
        refresh_interval = refresh_interval if refresh_interval > 0 else None
        complete_in_thread = env.get("COMPLETION_IN_THREAD")
        completions_display = env.get("COMPLETIONS_DISPLAY")
        complete_style = self.completion_displays_to_styles[
            completions_display]

        complete_while_typing = env.get("UPDATE_COMPLETIONS_ON_KEYPRESS")
        if complete_while_typing:
            # PTK requires history search to be none when completing while typing
            enable_history_search = False
        if HAS_PYGMENTS:
            self.styler.style_name = env.get("XONSH_COLOR_STYLE")
        completer = None if completions_display == "none" else self.pt_completer

        events.on_timingprobe.fire(name="on_pre_prompt_tokenize")
        get_bottom_toolbar_tokens = self.bottom_toolbar_tokens
        if env.get("UPDATE_PROMPT_ON_KEYPRESS"):
            get_prompt_tokens = self.prompt_tokens
            get_rprompt_tokens = self.rprompt_tokens
        else:
            get_prompt_tokens = self.prompt_tokens()
            get_rprompt_tokens = self.rprompt_tokens()
            if get_bottom_toolbar_tokens:
                get_bottom_toolbar_tokens = get_bottom_toolbar_tokens()
        events.on_timingprobe.fire(name="on_post_prompt_tokenize")

        if env.get("VI_MODE"):
            editing_mode = EditingMode.VI
        else:
            editing_mode = EditingMode.EMACS

        if env.get("XONSH_HISTORY_MATCH_ANYWHERE"):
            self.prompter.default_buffer._history_matches = MethodType(
                _cust_history_matches, self.prompter.default_buffer)
        elif (self.prompter.default_buffer._history_matches
              is not self._history_matches_orig):
            self.prompter.default_buffer._history_matches = self._history_matches_orig

        prompt_args = {
            "mouse_support": mouse_support,
            "auto_suggest": auto_suggest,
            "message": get_prompt_tokens,
            "rprompt": get_rprompt_tokens,
            "bottom_toolbar": get_bottom_toolbar_tokens,
            "completer": completer,
            "multiline": multiline,
            "editing_mode": editing_mode,
            "prompt_continuation": self.continuation_tokens,
            "enable_history_search": enable_history_search,
            "reserve_space_for_menu": 0,
            "key_bindings": self.key_bindings,
            "complete_style": complete_style,
            "complete_while_typing": complete_while_typing,
            "include_default_pygments_style": False,
            "refresh_interval": refresh_interval,
            "complete_in_thread": complete_in_thread,
        }

        if env.get("COLOR_INPUT"):
            events.on_timingprobe.fire(name="on_pre_prompt_style")
            if HAS_PYGMENTS:
                prompt_args["lexer"] = PygmentsLexer(pyghooks.XonshLexer)
                style = style_from_pygments_cls(
                    pyghooks.xonsh_style_proxy(self.styler))
            else:
                style = style_from_pygments_dict(DEFAULT_STYLE_DICT)
            prompt_args["style"] = style
            events.on_timingprobe.fire(name="on_post_prompt_style")

            style_overrides_env = env.get("PTK_STYLE_OVERRIDES")
            if style_overrides_env:
                try:
                    style_overrides = Style.from_dict(style_overrides_env)
                    prompt_args["style"] = merge_styles(
                        [style, style_overrides])
                except (AttributeError, TypeError, ValueError):
                    print_exception()

        if env["ENABLE_ASYNC_PROMPT"]:
            # once the prompt is done, update it in background as each future is completed
            prompt_args["pre_run"] = self.prompt_formatter.start_update

        events.on_pre_prompt.fire()
        line = self.prompter.prompt(**prompt_args)
        events.on_post_prompt.fire()
        return line
Exemple #19
0
 def run(self):
     """Set up input/output streams and execute the child function in a new
     thread.  This is part of the `threading.Thread` interface and should
     not be called directly.
     """
     if self.f is None:
         return
     spec = self._wait_and_getattr("spec")
     last_in_pipeline = spec.last_in_pipeline
     if last_in_pipeline:
         capout = spec.captured_stdout  # NOQA
         caperr = spec.captured_stderr  # NOQA
     env = builtins.__xonsh__.env
     enc = env.get("XONSH_ENCODING")
     err = env.get("XONSH_ENCODING_ERRORS")
     if xp.ON_WINDOWS:
         if self.p2cread != -1:
             self.p2cread = xli.msvcrt.open_osfhandle(
                 self.p2cread.Detach(), 0)
         if self.c2pwrite != -1:
             self.c2pwrite = xli.msvcrt.open_osfhandle(
                 self.c2pwrite.Detach(), 0)
         if self.errwrite != -1:
             self.errwrite = xli.msvcrt.open_osfhandle(
                 self.errwrite.Detach(), 0)
     # get stdin
     if self.stdin is None:
         sp_stdin = None
     elif self.p2cread != -1:
         sp_stdin = io.TextIOWrapper(io.open(self.p2cread, "rb", -1),
                                     encoding=enc,
                                     errors=err)
     else:
         sp_stdin = sys.stdin
     # stdout
     if self.c2pwrite != -1:
         sp_stdout = io.TextIOWrapper(io.open(self.c2pwrite, "wb", -1),
                                      encoding=enc,
                                      errors=err)
     else:
         sp_stdout = sys.stdout
     # stderr
     if self.errwrite == self.c2pwrite:
         sp_stderr = sp_stdout
     elif self.errwrite != -1:
         sp_stderr = io.TextIOWrapper(io.open(self.errwrite, "wb", -1),
                                      encoding=enc,
                                      errors=err)
     else:
         sp_stderr = sys.stderr
     # run the function itself
     try:
         with STDOUT_DISPATCHER.register(
                 sp_stdout
         ), STDERR_DISPATCHER.register(sp_stderr), xt.redirect_stdout(
                 STDOUT_DISPATCHER), xt.redirect_stderr(STDERR_DISPATCHER):
             r = self.f(self.args, sp_stdin, sp_stdout, sp_stderr, spec,
                        spec.stack)
     except SystemExit as e:
         r = e.code if isinstance(e.code, int) else int(bool(e.code))
     except OSError:
         status = still_writable(self.c2pwrite) and still_writable(
             self.errwrite)
         if status:
             # stdout and stderr are still writable, so error must
             # come from function itself.
             xt.print_exception()
             r = 1
         else:
             # stdout and stderr are no longer writable, so error must
             # come from the fact that the next process in the pipeline
             # has closed the other side of the pipe. The function then
             # attempted to write to this side of the pipe anyway. This
             # is not truly an error and we should exit gracefully.
             r = 0
     except Exception:
         xt.print_exception()
         r = 1
     safe_flush(sp_stdout)
     safe_flush(sp_stderr)
     self.returncode = parse_proxy_return(r, sp_stdout, sp_stderr)
     if not last_in_pipeline and not xp.ON_WINDOWS:
         # mac requires us *not to* close the handles here while
         # windows requires us *to* close the handles here
         return
     # clean up
     # scopz: not sure why this is needed, but stdin cannot go here
     # and stdout & stderr must.
     handles = [self.stdout, self.stderr]
     for handle in handles:
         safe_fdclose(handle, cache=self._closed_handle_cache)
Exemple #20
0
 def _call(self, handler):
     try:
         handler(**self._kwargs)
     except Exception:
         print_exception("Exception raised in event handler; ignored.")