summaryrefslogtreecommitdiff
path: root/cmd2/cmd2.py
diff options
context:
space:
mode:
authorKevin Van Brunt <kmvanbrunt@gmail.com>2018-09-19 02:05:08 -0400
committerKevin Van Brunt <kmvanbrunt@gmail.com>2018-09-19 02:05:08 -0400
commitbd34fee86d66a610d1e0bb392186dc73e883e2db (patch)
treeaeb522388f6c28e7cfa3d5a1e2a948123c4b1ff3 /cmd2/cmd2.py
parent36d9ec82c50b037becc204f9fc05d94c4d391ccf (diff)
downloadcmd2-git-bd34fee86d66a610d1e0bb392186dc73e883e2db.tar.gz
Wrote function and test command to print alerts
Diffstat (limited to 'cmd2/cmd2.py')
-rw-r--r--cmd2/cmd2.py70
1 files changed, 69 insertions, 1 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index 888d9531..874fdf6c 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -50,7 +50,7 @@ from .clipboard import can_clip, get_paste_buffer, write_to_paste_buffer
from .parsing import StatementParser, Statement
# Set up readline
-from .rl_utils import rl_type, RlType
+from .rl_utils import rl_type, RlType, rl_get_point
if rl_type == RlType.NONE: # pragma: no cover
rl_warning = "Readline features including tab completion have been disabled since no \n" \
"supported version of readline was found. To resolve this, install \n" \
@@ -3191,6 +3191,74 @@ Script should contain one command per line, just like command would be typed in
runner = unittest.TextTestRunner()
runner.run(testcase)
+ def print_alert(self, alert_msg: str) -> None:
+ """
+ Used to display an important message to the user while they are at the prompt.
+ The current prompt and input lines are erased, then the alert is printed in their place, and
+ finally the prompt and input lines restored below the alert. To the user it appears as if
+ an alert message is printed above the prompt.
+
+ :param alert_msg: the message to display to the user
+ """
+ if rl_type == RlType.NONE:
+ return
+
+ import shutil
+ import colorama.ansi as ansi
+ from colorama import Cursor
+
+ visible_prompt = self.visible_prompt
+
+ # Get the size of the terminal
+ terminal_size = shutil.get_terminal_size()
+
+ # Figure out how many lines the prompt and user input take up
+ total_str_size = len(visible_prompt) + len(readline.get_line_buffer())
+ num_input_lines = int(total_str_size / terminal_size.columns) + 1
+
+ # Get the cursor's offset from the beginning of the first input line
+ cursor_input_offset = len(visible_prompt) + rl_get_point()
+
+ # Calculate what input line the cursor is on
+ cursor_input_line = int(cursor_input_offset / terminal_size.columns) + 1
+
+ # Create a string that will clear all input lines and print the alert
+ terminal_str = ''
+
+ # Move the cursor down to the last input line
+ if cursor_input_line != num_input_lines:
+ terminal_str += Cursor.DOWN(num_input_lines - cursor_input_line)
+
+ # Clear each input line from the bottom up so that the cursor ends up on the original first input line
+ terminal_str += (ansi.clear_line() + Cursor.UP(1)) * (num_input_lines - 1)
+ terminal_str += ansi.clear_line()
+
+ # Print the alert
+ terminal_str += alert_msg + '\n'
+
+ # Write the string to the terminal
+ if rl_type == RlType.GNU:
+ sys.stdout.write(terminal_str)
+ elif rl_type == RlType.PYREADLINE:
+ readline.rl.mode.console.write(terminal_str)
+
+ # Redraw the prompt and input line
+ rl_force_redisplay()
+
+ def worker(self):
+ import time
+ while True:
+ alert_msg = "\n***********************************************\n" \
+ " Message failed to send\n" \
+ "***********************************************"
+ time.sleep(5)
+ self.print_alert(alert_msg)
+
+ def do_alert(self, args):
+ import threading
+ printer = threading.Thread(target=self.worker, daemon=True)
+ printer.start()
+
def cmdloop(self, intro: Optional[str]=None) -> None:
"""This is an outer wrapper around _cmdloop() which deals with extra features provided by cmd2.