Skip to content

Commit

Permalink
Added a couple simple example for using tmux or byobu to launch cmd2 …
Browse files Browse the repository at this point in the history
…applications (#1399)

* Added a couple simple example shell scripts demonstrating how to use tmux or byobu to launch a cmd2 application in a terminal multiplexer along with another application such as a shell.

One example uses windows/tabs and the other uses a split screen mode.

* Improved the documentation for all cmd2 examples

* Added info on the tmux examples to the examples/README.md

* Added a link to the example applications from top-level README

* Fix spelling and grammar errors
  • Loading branch information
tleonhardt authored Dec 29, 2024
1 parent 9d3f227 commit e4ab25f
Show file tree
Hide file tree
Showing 8 changed files with 207 additions and 38 deletions.
53 changes: 28 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,30 +39,30 @@ The price we pay for beautifully colored displays is complexity required to aggr
The `cmd2` framework provides a great mixture of both worlds. Application designers can easily create complex applications and rely on the cmd2 library to offer effortless user facing help and extensive tab completion.
When users become comfortable with functionality, cmd2 turns into a feature rich library enabling a smooth transition to full automation. If designed with enough forethought, a well implemented cmd2 application can serve as a boutique workflow tool. `cmd2` pulls off this flexibility based on two pillars of philosophy:

- Tab Completion
- Automation Transition
- Tab Completion
- Automation Transition

## Philosophy

<a href="https://imgflip.com/i/63h03x"><img src="https://i.imgflip.com/63h03x.jpg" title="made at imgflip.com" width="70%" height="%70"/></a>

Deep extensive tab completion and help text generation based on the argparse library create the first pillar of 'ease of command discovery'. The following is a list of features in this category.

- Great tab completion of commands, subcommands, file system paths, and shell commands.
- Custom tab completion for user designed commands via simple function overloading.
- Tab completion from `persistent_history_file` sources added with very little friction.
- Automatic tab completion of `argparse` flags and optional arguments.
- Path completion easily enabled.
- When all else fails, custom tab completion based on `choices_provider` can fill any gaps.
- Great tab completion of commands, subcommands, file system paths, and shell commands.
- Custom tab completion for user designed commands via simple function overloading.
- Tab completion from `persistent_history_file` sources added with very little friction.
- Automatic tab completion of `argparse` flags and optional arguments.
- Path completion easily enabled.
- When all else fails, custom tab completion based on `choices_provider` can fill any gaps.

<a href="https://imgflip.com/i/66t0y0"><img src="https://i.imgflip.com/66t0y0.jpg" title="made at imgflip.com" width="70%" height="70%"/></a>

cmd2 creates the second pillar of 'ease of transition to automation' through alias/macro creation, command line argument parsing and execution of cmd2 scripting.

- Flexible alias and macro creation for quick abstraction of commands.
- Text file scripting of your application with `run_script` (`@`) and `_relative_run_script` (`@@`)
- Powerful and flexible built-in Python scripting of your application using the `run_pyscript` command
- Transcripts for use with built-in regression can be automatically generated from `history -t` or `run_script -t`
- Flexible alias and macro creation for quick abstraction of commands.
- Text file scripting of your application with `run_script` (`@`) and `_relative_run_script` (`@@`)
- Powerful and flexible built-in Python scripting of your application using the `run_pyscript` command
- Transcripts for use with built-in regression can be automatically generated from `history -t` or `run_script -t`

## Installation

Expand All @@ -88,14 +88,17 @@ The best way to learn the cmd2 api is to delve into the example applications loc

## Tutorials

- PyOhio 2019 presentation:
- [video](https://www.youtube.com/watch?v=pebeWrTqIIw)
- [slides](https://github.com/python-cmd2/talks/blob/master/PyOhio_2019/cmd2-PyOhio_2019.pdf)
- [example code](https://github.com/python-cmd2/talks/tree/master/PyOhio_2019/examples)
- [Cookiecutter](https://github.com/cookiecutter/cookiecutter) Templates from community
- Basic cookiecutter template for cmd2 application : https://github.com/jayrod/cookiecutter-python-cmd2
- Advanced cookiecutter template with external plugin support : https://github.com/jayrod/cookiecutter-python-cmd2-ext-plug
- [Example Applications](https://github.com/jayrod/cmd2-example-apps)
- PyOhio 2019 presentation:
- [video](https://www.youtube.com/watch?v=pebeWrTqIIw)
- [slides](https://github.com/python-cmd2/talks/blob/master/PyOhio_2019/cmd2-PyOhio_2019.pdf)
- [example code](https://github.com/python-cmd2/talks/tree/master/PyOhio_2019/examples)
- [Cookiecutter](https://github.com/cookiecutter/cookiecutter) Templates from community
- Basic cookiecutter template for cmd2 application : https://github.com/jayrod/cookiecutter-python-cmd2
- Advanced cookiecutter template with external plugin support : https://github.com/jayrod/cookiecutter-python-cmd2-ext-plug
- [cmd2 example applications](https://github.com/python-cmd2/cmd2/tree/master/examples)
- Basic cmd2 examples to demonstrate how to use various features
- [Advanced Examples](https://github.com/jayrod/cmd2-example-apps)
- More complex examples that demonstrate more featuers about how to put together a complete application

## Hello World

Expand All @@ -122,11 +125,11 @@ if __name__ == '__main__':

If you think you've found a bug, please first read through the open [Issues](https://github.com/python-cmd2/cmd2/issues). If you're confident it's a new bug, go ahead and create a new GitHub issue. Be sure to include as much information as possible so we can reproduce the bug. At a minimum, please state the following:

- `cmd2` version
- Python version
- OS name and version
- What you did to cause the bug to occur
- Include any traceback or error message associated with the bug
- `cmd2` version
- Python version
- OS name and version
- What you did to cause the bug to occur
- Include any traceback or error message associated with the bug

## Projects using cmd2

Expand Down
5 changes: 5 additions & 0 deletions docs/examples/examples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# List of cmd2 examples

{%
include-markdown "../../examples/README.md"
%}
5 changes: 3 additions & 2 deletions docs/examples/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

<!--intro-start-->

- [First Application](first_app.md)
- [Alternate Event Loops](alternate_event_loops.md)
- [First Application](first_app.md)
- [Alternate Event Loops](alternate_event_loops.md)
- [List of cmd2 examples](examples.md)

<!--intro-end-->
88 changes: 88 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# cmd2 Examples

The [examples](https://github.com/python-cmd2/cmd2/tree/master/examples) directory within the `cmd2` repository contains a number of simple self-contained examples which each demonstrate a few particular features of `cmd2`. None of them are representative of a full real-world complex `cmd2` application, if you are looking for that then see [Projects using cmd2](https://github.com/python-cmd2/cmd2?tab=readme-ov-file#projects-using-cmd2).

## List of cmd2 examples

Here is the list of examples in alphabetical order by filename along with a brief description of each:

- [alias_startup.py](https://github.com/python-cmd2/cmd2/blob/master/examples/alias_startup.py)
- Demonstrates how to add custom command aliases and how to run an initialization script at startup
- [arg_decorators.py](https://github.com/python-cmd2/cmd2/blob/master/examples/arg_decorators.py)
- Demonstrates how to use the `cmd2.with_argparser` decorator to specify command arguments using [argparse](https://docs.python.org/3/library/argparse.html)
- [arg_print.py](https://github.com/python-cmd2/cmd2/blob/master/examples/arg_print.py)
- Demonstrates how arguments and options get parsed and passed to commands and shows how shortcuts work
- [argparse_completion.py](https://github.com/python-cmd2/cmd2/blob/master/examples/argparse_completion.py)
- Shows how to integrate tab-completion with argparse-based commands
- [async_printing.py](https://github.com/python-cmd2/cmd2/blob/master/examples/async_printing.py)
- Shows how to asynchronously print alerts, update the prompt in realtime, and change the window title
- [basic.py](https://github.com/python-cmd2/cmd2/blob/master/examples/basic.py)
- Shows how to add a command, add help for it, and create persistent command history for your application
- [basic_completion.py](https://github.com/python-cmd2/cmd2/blob/master/examples/basic_completion.py)
- Show how to enable custom tab completion by assigning a completer function to `do_*` commands
- [cmd2_as_argument.py](https://github.com/python-cmd2/cmd2/blob/master/examples/cmd_as_argument.py)
- Demonstrates how to accept and parse command-line arguments when invoking a cmd2 application
- [colors.py](https://github.com/python-cmd2/cmd2/blob/master/examples/colors.py)
- Show various ways of using colorized output within a cmd2 application
- [custom_parser.py](https://github.com/python-cmd2/cmd2/blob/master/examples/custom_parser.py)
- Demonstrates how to create your own customer `Cmd2ArgumentParser`; used by the `override_parser.py` example
- [decorator_example.py](https://github.com/python-cmd2/cmd2/blob/master/examples/decorator_example.py)
- Shows how to use cmd2's various argparse decorators to processes command-line arguments
- [default_categories.py](https://github.com/python-cmd2/cmd2/blob/master/examples/default_categories.py)
- Demonstrates usage of `@with_default_category` decorator to group and categorize commands and `CommandSet` use
- [dynamic_commands.py](https://github.com/python-cmd2/cmd2/blob/master/examples/dynamic_commands.py)
- Shows how `do_*` commands can be dynamically created programatically at runtime
- [environment.py](https://github.com/python-cmd2/cmd2/blob/master/examples/environment.py)
- Shows how to create custom `cmd2.Settable` parameters which serve as internal environment variables
- [event_loops.py](https://github.com/python-cmd2/cmd2/blob/master/examples/event_loops.py)
- Shows how to integrate a `cmd2` application with an external event loop which isn't managed by `cmd2`
- [example.py](https://github.com/python-cmd2/cmd2/blob/master/examples/example.py)
- This example is intended to demonstrate `cmd2's` build-in transcript testing capability
- [exit_code.py](https://github.com/python-cmd2/cmd2/blob/master/examples/exit_code.py)
- Show how to emit a non-zero exit code from your `cmd2` application when it exits
- [first_app.py](https://github.com/python-cmd2/cmd2/blob/master/examples/first_app.py)
- Short application that demonstrates 8 key features: Settings, Commands, Argument Parsing, Generating Output, Help, Shortcuts, Multiple Commands, and History
- [hello_cmd2.py](https://github.com/python-cmd2/cmd2/blob/master/examples/hello_cmd2.py)
- Completely bare-bones `cmd2` application suitable for rapid testing and debugging of `cmd2` itself
- [help_categories.py](https://github.com/python-cmd2/cmd2/blob/master/examples/help_categories.py)
- Demonstrates command categorization and its impact on the output of the built-in `help` command
- [hooks.py](https://github.com/python-cmd2/cmd2/blob/master/examples/hooks.py)
- Shows how to use various `cmd2` application lifecycle hooks
- [initialization.py](https://github.com/python-cmd2/cmd2/blob/master/examples/initialization.py)
- Shows how to colorize output, use multiline command, add persistent history, and more
- [migrating.py](https://github.com/python-cmd2/cmd2/blob/master/examples/migrating.py)
- A simple `cmd` application that you can migrate to `cmd2` by changing one line
- [modular_commands_basic.py](https://github.com/python-cmd2/cmd2/blob/master/examples/modular_commands_basic.py)
- Demonstrates based `CommandSet` usage
- [modular_commands_dynamic.py](https://github.com/python-cmd2/cmd2/blob/master/examples/modular_commands_dynamic.py)
- Demonstrates dynamic `CommandSet` loading and unloading
- [modular_commands_main.py](https://github.com/python-cmd2/cmd2/blob/master/examples/modular_commands_main.py)
- Complex example demonstrating a variety of methods to load `CommandSets` using a mix of command decorators
- [modular_subcommands.py](https://github.com/python-cmd2/cmd2/blob/master/examples/modular_subcommands.py)
- Shows how to dynamically add and remove subcommands at runtime using `CommandSets`
- [override-parser.py](https://github.com/python-cmd2/cmd2/blob/master/examples/override_parser.py)
- Shows how to override cmd2's default `Cmd2ArgumentParser` with your own customer parser class
- [paged_output.py](https://github.com/python-cmd2/cmd2/blob/master/examples/paged_output.py)
- Shows how to use output pagination within `cmd2` apps via the `ppaged` method
- [persistent_history.py](https://github.com/python-cmd2/cmd2/blob/master/examples/persistent_history.py)
- Shows how to enable persistent history in your `cmd2` application
- [pirate.py](https://github.com/python-cmd2/cmd2/blob/master/examples/pirate.py)
- Demonstrates many features including colorized output, multiline commands, shorcuts, defaulting to shell, etc.
- [python_scripting.py](https://github.com/python-cmd2/cmd2/blob/master/examples/python_scripting.py)
- Shows how cmd2's built-in `run_pyscript` command can provide advanced Python scripting of cmd2 applications
- [read_input.py](https://github.com/python-cmd2/cmd2/blob/master/examples/read_input.py)
- Demonstrates the various ways to call `cmd2.Cmd.read_input()` for input history and tab completion
- [remove_builtin_commands.py](https://github.com/python-cmd2/cmd2/blob/master/examples/remove_builtin_commands.py)
- Shows how to remove any built-in cmd2 commands you do not want to be present in your cmd2 application
- [remove_settable.py](https://github.com/python-cmd2/cmd2/blob/master/examples/remove_settable.py)
- Shows how to remove any of the built-in cmd2 `Settables` you do not want in your cmd2 application
- [subcommands.py](https://github.com/python-cmd2/cmd2/blob/master/examples/subcommands.py)
- Shows how to use `argparse` to easily support sub-commands within your cmd2 commands
- [table_creation.py](https://github.com/python-cmd2/cmd2/blob/master/examples/table_creation.py)
- Contains various examples of using cmd2's table creation capabilities
- [tmux_launch.sh](https://github.com/python-cmd2/cmd2/blob/master/examples/tmux_launch.sh)
- Shell script that launches two applications using tmux in different windows/tabs
- [tmux_split.sh](https://github.com/python-cmd2/cmd2/blob/master/examples/tmux_split.sh)
- Shell script that launches two applications using tmux in a split pane view
- [unicode_commands.py](https://github.com/python-cmd2/cmd2/blob/master/examples/unicode_commands.py)
- Shows that cmd2 supports unicode everywhere, including within command names
5 changes: 3 additions & 2 deletions examples/migrating.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#!/usr/bin/env python
# coding=utf-8
"""
A sample application for cmd which can be used to show how to migrate to cmd2.
A sample cmd application that shows how to trivially migrate a cmd application to use cmd2.
"""

import cmd
# import cmd2 as cmd
import cmd # Comment this line and uncomment the one above to migrate to cmd2
import random


Expand Down
36 changes: 36 additions & 0 deletions examples/tmux_launch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env zsh

# This script launches two applications using tmux in different windows/tabs.
# The user is required to enter the name of at least the first application.
# If the second isn't provided, then the user's default shell is launched for this.
# You must have tmux installed and that can be done using your operating system's package manager.
#
# See the tmux Wiki for info on how to use it: https://github.com/tmux/tmux/wiki.
# To shift focus between different windows in tmux use Ctrl-b followed by l (lowercase "L").
#
# NOTE: If you have byobu installed, it is a wrapper around tmux and will likely run instead of tmux.
# For info on how to use Byobu, see: https://www.byobu.org/
# To shift focus between windows/tabs in byobu, simply hit F3.

# Function to print in red
print_red() {
echo -e "\e[31m$*\e[0m"
}

if [ $# -eq 0 ];
then
print_red "No arguments supplied and this script requires at least one"
exit 1
fi

FIRST_COMMAND=$1

if [ $# -eq 1 ]
then
SECOND_COMMAND=$SHELL
else
SECOND_COMMAND=$2
fi

tmux new-session -s "tmux window demo" -n "$FIRST_COMMAND" "$FIRST_COMMAND ;read" \; \
new-window -n "$SECOND_COMMAND" "$SECOND_COMMAND ; read" \; previous-window
34 changes: 34 additions & 0 deletions examples/tmux_split.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env zsh

# This script launches two applications using byobu in different tabs.
# The user is required to enter the name of at least the first application.
# If the second isn't provided, then the user's default shell is launched for this.
#
# byobu must be installed for this script to work and you can install it using your
# operating system package manager. For info on how to use Byobu, see: https://www.byobu.org/
#
# To shift focus between tabs in byobu, just hit F3.

# Function to print in red
print_red() {
echo -e "\e[31m$*\e[0m"
}

if [ $# -eq 0 ];
then
print_red "No arguments supplied and this script requires at least one"
exit 1
fi

FIRST_COMMAND=$1

if [ $# -eq 1 ]
then
SECOND_COMMAND=$SHELL
else
SECOND_COMMAND=$2
fi

tmux new-session -s "tmux split pane demo" "$FIRST_COMMAND ; read" \; \
split-window "$SECOND_COMMAND ; read" \; \
select-layout even-vertical
19 changes: 10 additions & 9 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
site_name: cmd2
site_description: cmd2 - quickly build feature-rich and user-friendly interactive command line applications in Python.
site_dir: build/html
site_url: !ENV [READTHEDOCS_CANONICAL_URL, https://cmd2.readthedocs.io/]
site_url: !ENV [READTHEDOCS_CANONICAL_URL, https://cmd2.readthedocs.io/]

# Repository
repo_name: cmd2
Expand Down Expand Up @@ -72,18 +72,18 @@ plugins:
python:
options:
extensions:
- griffe_typingdoc
- griffe_typingdoc
show_root_heading: true
show_if_no_docstring: true
preload_modules:
- argparse
- cmd
- argparse
- cmd
inherited_members: true
members_order: source
separate_signature: true
unwrap_annotated: true
filters:
- '!^_'
- "!^_"
merge_init_into_class: true
docstring_section_style: spacy
signature_crossrefs: true
Expand Down Expand Up @@ -122,9 +122,9 @@ markdown_extensions:
- pymdownx.smartsymbols
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format
- pymdownx.tabbed:
alternate_style: true

Expand Down Expand Up @@ -189,6 +189,7 @@ nav:
- examples/index.md
- examples/first_app.md
- examples/alternate_event_loops.md
- examples/examples.md
- Plugins:
- plugins/index.md
- plugins/external_test.md
Expand Down Expand Up @@ -219,4 +220,4 @@ extra_css:

# Include extra JS to setup Read the Docs addons integrations
extra_javascript:
- javascripts/readthedocs.js
- javascripts/readthedocs.js

0 comments on commit e4ab25f

Please sign in to comment.