summaryrefslogtreecommitdiff
path: root/docs/features
diff options
context:
space:
mode:
authorTodd Leonhardt <todd.leonhardt@gmail.com>2019-11-02 15:37:44 -0400
committerTodd Leonhardt <todd.leonhardt@gmail.com>2019-11-02 15:37:44 -0400
commit12ade7ba7b3adde4c225b965cd4a558574c6c304 (patch)
treed92c70454f890d19d0eef5d053274c633475715e /docs/features
parenta18eef6f6aa89280b5f9b92d4e681f22a438ff8b (diff)
downloadcmd2-git-12ade7ba7b3adde4c225b965cd4a558574c6c304.tar.gz
Added documentation for empty sections of the Sphinx docs
Diffstat (limited to 'docs/features')
-rw-r--r--docs/features/initialization.rst52
-rw-r--r--docs/features/plugins.rst154
-rw-r--r--docs/features/startup_commands.rst11
3 files changed, 215 insertions, 2 deletions
diff --git a/docs/features/initialization.rst b/docs/features/initialization.rst
index f167a55a..936208f1 100644
--- a/docs/features/initialization.rst
+++ b/docs/features/initialization.rst
@@ -1,5 +1,53 @@
Initialization
==============
-Show how to properly initialize a ``cmd2`` app, showing parameters, sequencing,
-etc.
+Here is a basic example ``cmd2`` application which demonstrates many
+capabilities which you may wish to utilize while initializing the app::
+
+ #!/usr/bin/env python3
+ # coding=utf-8
+ """A simple example cmd2 appliction demonstrating the following:
+ 1) Colorizing/stylizing output
+ 2) Using multiline commands
+ 3) Persistent history
+ 4) How to run an initialization script at startup
+ 5) How to group and categorize commands when displaying them in help
+ 6) Opting-in to using the ipy command to run an IPython shell
+ 7) Allowing access to your application in py and ipy
+ 8) Displaying an intro banner upon starting your application
+ 9) Using a custom prompt
+ """
+ import cmd2
+ from cmd2 import style
+
+
+ class BasicApp(cmd2.Cmd):
+ CUSTOM_CATEGORY = 'My Custom Commands'
+
+ def __init__(self):
+ super().__init__(multiline_commands=['echo'], persistent_history_file='cmd2_history.dat',
+ startup_script='scripts/startup.txt', use_ipython=True)
+
+ self.intro = style('Welcome to cmd2!', fg='red', bg='white', bold=True)
+ self.prompt = 'myapp> '
+
+ # Allow access to your application in py and ipy via self
+ self.locals_in_py = True
+
+ # Set the default category name
+ self.default_category = 'cmd2 Built-in Commands'
+
+ @cmd2.with_category(CUSTOM_CATEGORY)
+ def do_intro(self, _):
+ """Display the intro banner"""
+ self.poutput(self.intro)
+
+ @cmd2.with_category(CUSTOM_CATEGORY)
+ def do_echo(self, arg):
+ """Example of a multiline command"""
+ self.poutput(arg)
+
+
+ if __name__ == '__main__':
+ app = BasicApp()
+ app.cmdloop()
diff --git a/docs/features/plugins.rst b/docs/features/plugins.rst
index 253666e7..caa46b8c 100644
--- a/docs/features/plugins.rst
+++ b/docs/features/plugins.rst
@@ -1,3 +1,157 @@
Plugins
=======
+``cmd2`` has a built-in plugin framework which allows developers to create a
+a ``cmd2`` plugin which can extend basic ``cmd2`` functionality and can be
+used by multiple applications.
+
+Adding functionality
+--------------------
+
+There are many ways to add functionality to ``cmd2`` using a plugin. Most
+plugins will be implemented as a mixin. A mixin is a class that encapsulates
+and injects code into another class. Developers who use a plugin in their
+``cmd2`` project, will inject the plugin's code into their subclass of
+``cmd2.Cmd``.
+
+
+Mixin and Initialization
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following short example shows how to mix in a plugin and how the plugin
+gets initialized.
+
+Here's the plugin::
+
+ class MyPlugin:
+ def __init__(self, *args, **kwargs):
+ # code placed here runs before cmd2.Cmd initializes
+ super().__init__(*args, **kwargs)
+ # code placed here runs after cmd2.Cmd initializes
+
+
+and an example app which uses the plugin::
+
+ import cmd2
+ import cmd2_myplugin
+
+ class Example(cmd2_myplugin.MyPlugin, cmd2.Cmd):
+ """An class to show how to use a plugin"""
+ def __init__(self, *args, **kwargs):
+ # code placed here runs before cmd2.Cmd or
+ # any plugins initialize
+ super().__init__(*args, **kwargs)
+ # code placed here runs after cmd2.Cmd and
+ # all plugins have initialized
+
+Note how the plugin must be inherited (or mixed in) before ``cmd2.Cmd``.
+This is required for two reasons:
+
+- The ``cmd.Cmd.__init__()`` method in the python standard library does not
+ call ``super().__init__()``. Because of this oversight, if you don't
+ inherit from ``MyPlugin`` first, the ``MyPlugin.__init__()`` method will
+ never be called.
+- You may want your plugin to be able to override methods from ``cmd2.Cmd``.
+ If you mixin the plugin after ``cmd2.Cmd``, the python method resolution
+ order will call ``cmd2.Cmd`` methods before it calls those in your plugin.
+
+Add commands
+~~~~~~~~~~~~
+
+Your plugin can add user visible commands. You do it the same way in a plugin
+that you would in a ``cmd2.Cmd`` app::
+
+ class MyPlugin:
+ def do_say(self, statement):
+ """Simple say command"""
+ self.poutput(statement)
+
+You have all the same capabilities within the plugin that you do inside a
+``cmd2.Cmd`` app, including argument parsing via decorators and custom help
+methods.
+
+Add (or hide) settings
+~~~~~~~~~~~~~~~~~~~~~~
+
+A plugin may add user controllable settings to the application. Here's an
+example::
+
+ class MyPlugin:
+ def __init__(self, *args, **kwargs):
+ # code placed here runs before cmd2.Cmd initializes
+ super().__init__(*args, **kwargs)
+ # code placed here runs after cmd2.Cmd initializes
+ self.mysetting = 'somevalue'
+ self.settable.update({'mysetting': 'short help message for mysetting'})
+
+You can also hide settings from the user by removing them from
+``self.settable``.
+
+Decorators
+~~~~~~~~~~
+
+Your plugin can provide a decorator which users of your plugin can use to
+wrap functionality around their own commands.
+
+Override methods
+~~~~~~~~~~~~~~~~
+
+Your plugin can override core ``cmd2.Cmd`` methods, changing their behavior.
+This approach should be used sparingly, because it is very brittle. If a
+developer chooses to use multiple plugins in their application, and several
+of the plugins override the same method, only the first plugin to be mixed in
+will have the overridden method called.
+
+Hooks are a much better approach.
+
+Hooks
+~~~~~
+
+Plugins can register hooks, which are called by ``cmd2.Cmd`` during various
+points in the application and command processing lifecycle. Plugins should
+not override any of the deprecated hook methods, instead they should register
+their hooks as described in the :ref:`features/hooks:Hooks` section.
+
+You should name your hooks so that they begin with the name of your plugin.
+Hook methods get mixed into the ``cmd2`` application and this naming
+convention helps avoid unintentional method overriding.
+
+Here's a simple example::
+
+ class MyPlugin:
+ def __init__(self, *args, **kwargs):
+ # code placed here runs before cmd2 initializes
+ super().__init__(*args, **kwargs)
+ # code placed here runs after cmd2 initializes
+ # this is where you register any hook functions
+ self.register_postparsing_hook(self.cmd2_myplugin_postparsing_hook)
+
+ def cmd2_myplugin_postparsing_hook(self, data: cmd2.plugin.PostparsingData) -> cmd2.plugin.PostparsingData:
+ """Method to be called after parsing user input, but before running the command"""
+ self.poutput('in postparsing_hook')
+ return data
+
+Registration allows multiple plugins (or even the application itself) to each
+inject code to be called during the application or command processing
+lifecycle.
+
+See the :ref:`features/hooks:Hooks` documentation for full details of the
+application and command lifecycle, including all available hooks and the
+ways hooks can influence the lifecycle.
+
+
+Classes and Functions
+~~~~~~~~~~~~~~~~~~~~~
+
+Your plugin can also provide classes and functions which can be used by
+developers of ``cmd2`` based applications. Describe these classes and
+functions in your documentation so users of your plugin will know what's
+available.
+
+
+Examples
+--------
+
+.. _cmd2_plugin_template: https://github.com/python-cmd2/cmd2-plugin-template
+
+See cmd2_plugin_template_ for more info.
diff --git a/docs/features/startup_commands.rst b/docs/features/startup_commands.rst
index 1efcc014..4fb165a5 100644
--- a/docs/features/startup_commands.rst
+++ b/docs/features/startup_commands.rst
@@ -1,2 +1,13 @@
Startup Commands
================
+
+``cmd2`` provides a couple different ways for running commands immediately
+after your application starts up:
+
+1. :ref:`features/misc:Commands At Invocation`
+1. :ref:`features/misc:Initialization Script`
+
+Commands run as part of a startup (initialization) script are always run
+immediately after the application finishes initializing so they are
+guaranteed to run before any *Commands At Invocation*.
+