Skip to content

Commit

Permalink
let users disable horizontal-scroll-mode
Browse files Browse the repository at this point in the history
This commit adds an environment variable for controlling readline's
horizontal-scroll-mode. You can now disable the scroll mode by setting
OILS_READLINE_HORIZONTAL_SCROLL_MODE=off.

This should help with #2081
  • Loading branch information
melvinw committed Jan 30, 2025
1 parent b2da0db commit 52176b0
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 8 deletions.
25 changes: 20 additions & 5 deletions core/comp_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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,
Expand Down Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion core/comp_ui_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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('$ ')
Expand Down
4 changes: 3 additions & 1 deletion core/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion frontend/flag_def.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down

0 comments on commit 52176b0

Please sign in to comment.