def test_replace_logical_line(src, idx, exp_line, exp_n, xonsh_builtins): lines = src.splitlines() logical = exp_line while idx > 0 and lines[idx - 1].endswith("\\"): idx -= 1 replace_logical_line(lines, logical, idx, exp_n) exp = src.replace("\\\n", "").strip() lc = get_line_continuation() + "\n" obs = "\n".join(lines).replace(lc, "").strip() assert exp == obs
def test_replace_logical_line(src, idx, exp_line, exp_n): lines = src.splitlines() logical = exp_line while idx > 0 and lines[idx - 1].endswith("\\"): idx -= 1 replace_logical_line(lines, logical, idx, exp_n) exp = src.replace("\\\n", "").strip() lc = get_line_continuation() + "\n" obs = "\n".join(lines).replace(lc, "").strip() assert exp == obs
def LINE_CONT_REPLACEMENT_DIFF(): """Returns (line_continuation, replacement, diff). Diff is the diff in length for each replacement. """ line_cont = get_line_continuation() if " \\" == line_cont: # interactive windows replacement = " " else: replacement = "" line_cont += "\n" return line_cont, replacement, len(replacement) - len(line_cont)
def carriage_return(b, cli, *, autoindent=True): """Preliminary parser to determine if 'Enter' key should send command to the xonsh parser for execution or should insert a newline for continued input. Current 'triggers' for inserting a newline are: - Not on first line of buffer and line is non-empty - Previous character is a colon (covers if, for, etc...) - User is in an open paren-block - Line ends with backslash - Any text exists below cursor position (relevant when editing previous multiline blocks) """ doc = b.document at_end_of_line = _is_blank(doc.current_line_after_cursor) current_line_blank = _is_blank(doc.current_line) env = builtins.__xonsh__.env indent = env.get("INDENT") if autoindent else "" partial_string_info = check_for_partial_string(doc.text) in_partial_string = ( partial_string_info[0] is not None and partial_string_info[1] is None ) # indent after a colon if doc.current_line_before_cursor.strip().endswith(":") and at_end_of_line: b.newline(copy_margin=autoindent) b.insert_text(indent, fire_event=False) # if current line isn't blank, check dedent tokens elif ( not current_line_blank and doc.current_line.split(maxsplit=1)[0] in DEDENT_TOKENS and doc.line_count > 1 ): b.newline(copy_margin=autoindent) b.delete_before_cursor(count=len(indent)) elif not doc.on_first_line and not current_line_blank: b.newline(copy_margin=autoindent) elif doc.current_line.endswith(get_line_continuation()): b.newline(copy_margin=autoindent) elif doc.find_next_word_beginning() is not None and ( any(not _is_blank(i) for i in doc.lines_from_current[1:]) ): b.newline(copy_margin=autoindent) elif not current_line_blank and not can_compile(doc.text): b.newline(copy_margin=autoindent) elif current_line_blank and in_partial_string: b.newline(copy_margin=autoindent) else: b.validate_and_handle()
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, filename="<stdin>", compile_empty_tree=False, ) 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
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