diff --git a/core/comp_ui.py b/core/comp_ui.py index 383edba42..6400e30e2 100644 --- a/core/comp_ui.py +++ b/core/comp_ui.py @@ -2,6 +2,7 @@ from __future__ import print_function from core import completion +from core import state from display import ansi from display import pp_value import libc @@ -26,6 +27,7 @@ PROMPT_UNDERLINE = '\x01%s\x02' % ansi.UNDERLINE PROMPT_REVERSE = '\x01%s\x02' % ansi.REVERSE +HORIZONTAL_SCROLL_ENV = 'OILS_READLINE_HORIZONTAL_SCROLL_MODE' def _PromptLen(prompt_str): # type: (str) -> int @@ -85,13 +87,14 @@ def __init__(self): class _IDisplay(object): """Interface for completion displays.""" - def __init__(self, comp_state, prompt_state, num_lines_cap, f, debug_f): - # type: (State, PromptState, int, mylib.Writer, _DebugFile) -> None + def __init__(self, comp_state, prompt_state, num_lines_cap, f, debug_f, horizontal_scroll_mode): + # type: (State, PromptState, int, mylib.Writer, _DebugFile, str) -> None self.comp_state = comp_state self.prompt_state = prompt_state self.num_lines_cap = num_lines_cap self.f = f self.debug_f = debug_f + self.horizontal_scroll_mode = horizontal_scroll_mode def PrintCandidates(self, unused_subst, matches, unused_match_len): # type: (Optional[str], List[str], int) -> None @@ -145,7 +148,7 @@ class MinimalDisplay(_IDisplay): def __init__(self, comp_state, prompt_state, debug_f): # type: (State, PromptState, _DebugFile) -> None _IDisplay.__init__(self, comp_state, prompt_state, 10, mylib.Stdout(), - debug_f) + debug_f, 'on') def _RedrawPrompt(self): # type: () -> None @@ -315,15 +318,18 @@ def __init__( debug_f, # type: _DebugFile readline, # type: Optional[Readline] signal_safe, # type: iolib.SignalSafe + mem, # type: state.Mem ): # type: (...) -> None """ Args: bold_line: Should user's entry be bold? """ + environ = mem.GetEnv() _IDisplay.__init__(self, comp_state, prompt_state, 10, mylib.Stdout(), - debug_f) + debug_f, environ.get(HORIZONTAL_SCROLL_ENV, 'on')) + self.mem = mem self.term_width = term_width # initial terminal width; will be invalidated self.readline = readline @@ -346,6 +352,15 @@ def Reset(self): self.num_lines_last_displayed = 0 self.dupes.clear() + environ = self.mem.GetEnv() + horizontal_scroll_mode = environ.get( + HORIZONTAL_SCROLL_ENV, self.horizontal_scroll_mode) + if horizontal_scroll_mode != self.horizontal_scroll_mode: + self.horizontal_scroll_mode = horizontal_scroll_mode + self.readline.parse_and_bind( + 'set horizontal-scroll-mode %s' % horizontal_scroll_mode) + + def _ReturnToPrompt(self, num_lines): # type: (int) -> None # NOTE: We can't use ANSI terminal codes to save and restore the prompt, @@ -548,7 +563,7 @@ def InitReadline( readline.parse_and_bind('tab: complete') - readline.parse_and_bind('set horizontal-scroll-mode on') + readline.parse_and_bind('set horizontal-scroll-mode %s' % display.horizontal_scroll_mode) # How does this map to C? # https://cnswww.cns.cwru.edu/php/chet/readline/readline.html#SEC45 diff --git a/core/comp_ui_test.py b/core/comp_ui_test.py index e4bd4a619..e2a0b47be 100755 --- a/core/comp_ui_test.py +++ b/core/comp_ui_test.py @@ -7,6 +7,7 @@ import unittest from core import comp_ui # module under test +from core import state from core import util from mycpp import iolib @@ -118,10 +119,11 @@ def testDisplays(self): prompt_state = comp_ui.PromptState() debug_f = util.DebugFile(sys.stdout) signal_safe = iolib.InitSignalSafe() + mem = state.Mem() # terminal width d1 = comp_ui.NiceDisplay(80, comp_ui_state, prompt_state, debug_f, - line_input, signal_safe) + line_input, signal_safe, mem) d2 = comp_ui.MinimalDisplay(comp_ui_state, prompt_state, debug_f) prompt_state.SetLastPrompt('$ ') diff --git a/core/shell.py b/core/shell.py index 2630ab328..2bf9c6bfc 100644 --- a/core/shell.py +++ b/core/shell.py @@ -1093,7 +1093,8 @@ def Main( if term_width != 0: display = comp_ui.NiceDisplay( term_width, comp_ui_state, prompt_state, debug_f, readline, - signal_safe) # type: comp_ui._IDisplay + signal_safe, mem) # type: comp_ui._IDisplay + else: display = comp_ui.MinimalDisplay(comp_ui_state, prompt_state, debug_f) @@ -1126,6 +1127,7 @@ def Main( assert line_reader is not None line_reader.Reset() # After sourcing startup file, render $PS1 + display.Reset() prompt_plugin = prompt.UserPlugin(mem, parse_ctx, cmd_ev, errfmt) try: diff --git a/frontend/flag_def.py b/frontend/flag_def.py index 497fd9a04..511923ae9 100644 --- a/frontend/flag_def.py +++ b/frontend/flag_def.py @@ -272,7 +272,7 @@ def _AddShellOptions(spec): default='abbrev-text') # Defines completion style. -MAIN_SPEC.LongFlag('--completion-display', ['minimal', 'nice'], default='nice') +MAIN_SPEC.LongFlag('--completion-display', ['bash', 'minimal', 'nice'], default='nice') # TODO: Add option for YSH prompt style? RHS prompt? MAIN_SPEC.LongFlag('--completion-demo')