Skip to content

Commit 5b96488

Browse files
committed
Refactored async_alert
1 parent d80aeb3 commit 5b96488

File tree

1 file changed

+43
-56
lines changed

1 file changed

+43
-56
lines changed

cmd2/cmd2.py

Lines changed: 43 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3436,52 +3436,6 @@ class TestMyAppCase(Cmd2TestCase):
34363436
runner = unittest.TextTestRunner()
34373437
runner.run(testcase)
34383438

3439-
def _clear_input_lines_str(self, current_prompt: str) -> str: # pragma: no cover
3440-
"""
3441-
Returns a string that if printed will clear the prompt and input lines in the terminal,
3442-
leaving the cursor at the beginning of the first input line
3443-
3444-
:param current_prompt: the currently displayed prompt
3445-
"""
3446-
if not (vt100_support and self.use_rawinput):
3447-
return ''
3448-
3449-
import shutil
3450-
import colorama.ansi as ansi
3451-
from colorama import Cursor
3452-
3453-
# Remove ansi characters to get the visible width of the prompt
3454-
prompt_width = wcswidth(utils.strip_ansi(current_prompt))
3455-
3456-
# Get the size of the terminal
3457-
terminal_size = shutil.get_terminal_size()
3458-
3459-
# Figure out how many lines the prompt and user input take up
3460-
total_str_size = prompt_width + wcswidth(readline.get_line_buffer())
3461-
num_input_lines = int(total_str_size / terminal_size.columns) + 1
3462-
3463-
# Get the cursor's offset from the beginning of the first input line
3464-
cursor_input_offset = prompt_width + rl_get_point()
3465-
3466-
# Calculate what input line the cursor is on
3467-
cursor_input_line = int(cursor_input_offset / terminal_size.columns) + 1
3468-
3469-
# Create a string that will clear all input lines and print the alert
3470-
terminal_str = ''
3471-
3472-
# Move the cursor down to the last input line
3473-
if cursor_input_line != num_input_lines:
3474-
terminal_str += Cursor.DOWN(num_input_lines - cursor_input_line)
3475-
3476-
# Clear each input line from the bottom up so that the cursor ends up on the original first input line
3477-
terminal_str += (ansi.clear_line() + Cursor.UP(1)) * (num_input_lines - 1)
3478-
terminal_str += ansi.clear_line()
3479-
3480-
# Move the cursor to the beginning of the first input line
3481-
terminal_str += '\r'
3482-
3483-
return terminal_str
3484-
34853439
def async_alert(self, alert_msg: str, new_prompt: Optional[str] = None) -> None: # pragma: no cover
34863440
"""
34873441
Display an important message to the user while they are at the prompt in between commands.
@@ -3500,30 +3454,63 @@ def async_alert(self, alert_msg: str, new_prompt: Optional[str] = None) -> None:
35003454
if not (vt100_support and self.use_rawinput):
35013455
return
35023456

3457+
import shutil
3458+
import colorama.ansi as ansi
3459+
from colorama import Cursor
3460+
35033461
# Sanity check that can't fail if self.terminal_lock was acquired before calling this function
35043462
if self.terminal_lock.acquire(blocking=False):
35053463

3506-
# Only update if there are changes
3507-
do_update = False
3508-
3509-
# Generate a string to clear the prompt and input lines and replace with the alert
3464+
# Figure out what prompt is displaying
35103465
current_prompt = self.continuation_prompt if self.at_continuation_prompt else self.prompt
3511-
terminal_str = self._clear_input_lines_str(current_prompt)
3466+
3467+
# Only update terminal if there are changes
3468+
update_terminal = False
35123469

35133470
if alert_msg:
3514-
terminal_str += alert_msg + '\n'
3515-
do_update = True
3471+
alert_msg += '\n'
3472+
update_terminal = True
35163473

35173474
# Set the prompt if its changed
35183475
if new_prompt is not None and new_prompt != self.prompt:
35193476
self.prompt = new_prompt
35203477

3478+
# If we aren't at a continuation prompt, then redraw the prompt now
35213479
if not self.at_continuation_prompt:
35223480
rl_set_prompt(self.prompt)
3523-
do_update = True
3481+
update_terminal = True
3482+
3483+
if update_terminal:
3484+
# Remove ansi characters to get the visible width of the prompt
3485+
prompt_width = wcswidth(utils.strip_ansi(current_prompt))
3486+
3487+
# Get the size of the terminal
3488+
terminal_size = shutil.get_terminal_size()
3489+
3490+
# Figure out how many lines the prompt and user input take up
3491+
total_str_size = prompt_width + wcswidth(readline.get_line_buffer())
3492+
num_input_lines = int(total_str_size / terminal_size.columns) + 1
3493+
3494+
# Get the cursor's offset from the beginning of the first input line
3495+
cursor_input_offset = prompt_width + rl_get_point()
3496+
3497+
# Calculate what input line the cursor is on
3498+
cursor_input_line = int(cursor_input_offset / terminal_size.columns) + 1
3499+
3500+
# Create a string that when printed will clear all input lines and display the alert
3501+
terminal_str = ''
3502+
3503+
# Move the cursor down to the last input line
3504+
if cursor_input_line != num_input_lines:
3505+
terminal_str += Cursor.DOWN(num_input_lines - cursor_input_line)
3506+
3507+
# Clear each input line from the bottom up so that the cursor ends up on the original first input line
3508+
terminal_str += (ansi.clear_line() + Cursor.UP(1)) * (num_input_lines - 1)
3509+
terminal_str += ansi.clear_line()
3510+
3511+
# Move the cursor to the beginning of the first input line and print the alert
3512+
terminal_str += '\r' + alert_msg
35243513

3525-
if do_update:
3526-
# Print terminal_str to erase the lines
35273514
if rl_type == RlType.GNU:
35283515
sys.stderr.write(terminal_str)
35293516
elif rl_type == RlType.PYREADLINE:

0 commit comments

Comments
 (0)