Skip to content

Commit bf37cf0

Browse files
committed
Merge branch 'master' into capture_popen
2 parents a96939b + 6fd9cc6 commit bf37cf0

File tree

3 files changed

+35
-20
lines changed

3 files changed

+35
-20
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
## 0.9.12 (March TBD, 2019)
22
* Bug Fixes
33
* Fixed a bug in how redirection and piping worked inside ``py`` or ``pyscript`` commands
4+
* Fixed bug in `async_alert` where it didn't account for prompts that contained newline characters
45
* Enhancements
56
* Added ability to include command name placeholders in the message printed when trying to run a disabled command.
67
* See docstring for ``disable_command()`` or ``disable_category()`` for more details.

cmd2/cmd2.py

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2153,7 +2153,7 @@ def pseudo_raw_input(self, prompt: str) -> str:
21532153
else:
21542154
line = input()
21552155
if self.echo:
2156-
sys.stdout.write('{}{}\n'.format(self.prompt, line))
2156+
sys.stdout.write('{}{}\n'.format(prompt, line))
21572157
except EOFError:
21582158
line = 'eof'
21592159
finally:
@@ -2163,7 +2163,7 @@ def pseudo_raw_input(self, prompt: str) -> str:
21632163
else:
21642164
if self.stdin.isatty():
21652165
# on a tty, print the prompt first, then read the line
2166-
self.poutput(self.prompt, end='')
2166+
self.poutput(prompt, end='')
21672167
self.stdout.flush()
21682168
line = self.stdin.readline()
21692169
if len(line) == 0:
@@ -2176,7 +2176,7 @@ def pseudo_raw_input(self, prompt: str) -> str:
21762176
if len(line):
21772177
# we read something, output the prompt and the something
21782178
if self.echo:
2179-
self.poutput('{}{}'.format(self.prompt, line))
2179+
self.poutput('{}{}'.format(prompt, line))
21802180
else:
21812181
line = 'eof'
21822182

@@ -3652,24 +3652,35 @@ def async_alert(self, alert_msg: str, new_prompt: Optional[str] = None) -> None:
36523652
if new_prompt is not None and new_prompt != self.prompt:
36533653
self.prompt = new_prompt
36543654

3655-
# If we aren't at a continuation prompt, then redraw the prompt now
3655+
# If we aren't at a continuation prompt, then it's OK to update it
36563656
if not self.at_continuation_prompt:
36573657
rl_set_prompt(self.prompt)
36583658
update_terminal = True
36593659

36603660
if update_terminal:
3661-
# Get the display width of the prompt
3662-
prompt_width = utils.ansi_safe_wcswidth(current_prompt)
3663-
36643661
# Get the size of the terminal
36653662
terminal_size = shutil.get_terminal_size()
36663663

3667-
# Figure out how many lines the prompt and user input take up
3668-
total_str_size = prompt_width + utils.ansi_safe_wcswidth(readline.get_line_buffer())
3669-
num_input_lines = int(total_str_size / terminal_size.columns) + 1
3664+
# Split the prompt lines since it can contain newline characters.
3665+
prompt_lines = current_prompt.splitlines()
3666+
3667+
# Calculate how many terminal lines are taken up by all prompt lines except for the last one.
3668+
# That will be included in the input lines calculations since that is where the cursor is.
3669+
num_prompt_terminal_lines = 0
3670+
for line in prompt_lines[:-1]:
3671+
line_width = utils.ansi_safe_wcswidth(line)
3672+
num_prompt_terminal_lines += int(line_width / terminal_size.columns) + 1
3673+
3674+
# Now calculate how many terminal lines are take up by the input
3675+
last_prompt_line = prompt_lines[-1]
3676+
last_prompt_line_width = utils.ansi_safe_wcswidth(last_prompt_line)
3677+
3678+
input_width = last_prompt_line_width + utils.ansi_safe_wcswidth(readline.get_line_buffer())
3679+
3680+
num_input_terminal_lines = int(input_width / terminal_size.columns) + 1
36703681

36713682
# Get the cursor's offset from the beginning of the first input line
3672-
cursor_input_offset = prompt_width + rl_get_point()
3683+
cursor_input_offset = last_prompt_line_width + rl_get_point()
36733684

36743685
# Calculate what input line the cursor is on
36753686
cursor_input_line = int(cursor_input_offset / terminal_size.columns) + 1
@@ -3678,14 +3689,17 @@ def async_alert(self, alert_msg: str, new_prompt: Optional[str] = None) -> None:
36783689
terminal_str = ''
36793690

36803691
# Move the cursor down to the last input line
3681-
if cursor_input_line != num_input_lines:
3682-
terminal_str += Cursor.DOWN(num_input_lines - cursor_input_line)
3692+
if cursor_input_line != num_input_terminal_lines:
3693+
terminal_str += Cursor.DOWN(num_input_terminal_lines - cursor_input_line)
3694+
3695+
# Clear each line from the bottom up so that the cursor ends up on the first prompt line
3696+
total_lines = num_prompt_terminal_lines + num_input_terminal_lines
3697+
terminal_str += (ansi.clear_line() + Cursor.UP(1)) * (total_lines - 1)
36833698

3684-
# Clear each input line from the bottom up so that the cursor ends up on the original first input line
3685-
terminal_str += (ansi.clear_line() + Cursor.UP(1)) * (num_input_lines - 1)
3699+
# Clear the first prompt line
36863700
terminal_str += ansi.clear_line()
36873701

3688-
# Move the cursor to the beginning of the first input line and print the alert
3702+
# Move the cursor to the beginning of the first prompt line and print the alert
36893703
terminal_str += '\r' + alert_msg
36903704

36913705
if rl_type == RlType.GNU:

examples/async_printing.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,17 +126,17 @@ def _generate_alert_str(self) -> str:
126126
alerts = self._get_alerts()
127127

128128
longest_alert = max(ALERTS, key=len)
129-
num_astericks = len(longest_alert) + 8
129+
num_asterisks = len(longest_alert) + 8
130130

131131
for i, cur_alert in enumerate(alerts):
132132
# Use padding to center the alert
133-
padding = ' ' * int((num_astericks - len(cur_alert)) / 2)
133+
padding = ' ' * int((num_asterisks - len(cur_alert)) / 2)
134134

135135
if i > 0:
136136
alert_str += '\n'
137-
alert_str += '*' * num_astericks + '\n'
137+
alert_str += '*' * num_asterisks + '\n'
138138
alert_str += padding + cur_alert + padding + '\n'
139-
alert_str += '*' * num_astericks + '\n'
139+
alert_str += '*' * num_asterisks + '\n'
140140

141141
return alert_str
142142

0 commit comments

Comments
 (0)