chloop is a Redis-backed character-driven REPL framework designed for
developers who want to build custom interactive tools quickly and
efficiently while providing progressive complexity. The library
optimizes for single-keystroke efficiency while also leveraging vim’s
colon command paradigm to transform command-line interactions from
sequential operations into immediate context-aware experiences.
The core philosophy centers on **cognitive load reduction through muscle
memory development**. Instead of forcing users to remember complex
command syntax or navigate menus, chloop enables the creation of
interfaces where common actions become instinctive single keystrokes,
while advanced functionality remains accessible through discoverable
colon commands.
**Who benefits from this library:** - **Domain experts** who need
immediate control over complex systems (audio/video exploration, API
testing, data analysis) - **Interactive application developers**
building tools for power users who value efficiency over discovery -
**CLI tool creators** who want to provide both accessibility for
beginners and efficiency for experts - **Content analysts** needing
distraction-free, keyboard-driven workflows for media exploration -
**Researchers** who need to rapidly navigate and annotate large datasets
or media collections
Real-world implementations include the **mocp-cli** package for
interactive audio exploration with timestamp marking, and **vlc-helper**
for precise video control and screenshot capture, demonstrating chloop’s
effectiveness in media analysis workflows.
Install
-------
If you don’t have `docker <https://docs.docker.com/get-docker>`__
installed, install Redis and start server
::
sudo apt-get install -y redis-server
or
::
brew install redis
brew services start redis
Install with ``pip``
::
pip install chloop
..
Optionally install ipython with ``pip install ipython`` to enable
``:ipython`` colon command on a GetCharLoop instance. Also
``pip install pdbpp`` for an improved debug experience when using
``:pdb`` colon command.
QuickStart
----------
The ``GetCharLoop`` class is provided by the ``chloop`` package. Calling
an **instance** of this class starts a REPL session, which the user can
end by pressing ``Ctrl`` + ``d`` or ``Ctrl`` + ``c``.
The **first** character you type at the REPL prompt is significant.
The colon
~~~~~~~~~
Hitting the ``:`` key at the prompt will allow you to enter a command
and any arguments you need to pass to that command.
- ``:docstrings`` to view docstrings of methods defined on the class
- ``:errors`` to view colon commands that raised exceptions
- ``:history`` view colon commands issued
- ``:pdb`` to start a pdb session (debugging/inspection)
- ``:ipython`` to start ipython shell
- ``:shortcuts`` to view hotkey shortcuts
Any methods added to your sub-class of ``GetCharLoop`` are callable as
**colon commands**, as long as they do not start with an underscore
(``_``). Methods should **only accept ``*args``**, if anything.
For any methods/commands that should not be logged to the history,
append the method name to the end of the ``self._DONT_LOG_CMDS``
list.
The dash
~~~~~~~~
Hitting the ``-`` key at the prompt will allow you to type a note.
The question mark
~~~~~~~~~~~~~~~~~
Hitting the ``?`` key at the prompt will display the class docstring(s)
and the startup message.
Hitting the ``?`` key a second time will show the available colon
commands and shortcuts (equivalent to issuing ``:docstrings`` and
``:shortcuts``)
Other keys
~~~~~~~~~~
Hitting any other key at the prompt will do one of the following:
- call a **registered shortcut function** bound to the key (use
``:shortcuts`` command to see what is available)
- display the character and its integer ordinal
A hotkey can be bound to any callable object that accepts no arguments.
Use ``functools.partial`` (if necessary) to create a callable accepting
no arguments.
Basic example
~~~~~~~~~~~~~
The default prompt if none is specified is ``>``.
::
% python3 -c 'from chloop import GetCharLoop; GetCharLoop()()'
> ?
Loop forever, receiving character input from user and performing actions
- ctrl+d or ctrl+c to break the loop
- ':' to enter a command (and any arguments)
- any method defined on GetCharLoop (or a sub-class) will be callable
as a "colon command" (if its name does not start with '_')
- the method for the `:command` should only accept `*args`
- '-' to allow user to provide input that will be processed by the `input_hook`
- '?' to show class doc and the startup message
- '??' to show class doc, the startup message, docstrings (:commands), and shortcuts
:docstrings to see all colon commands
:shortcuts to see all hotkeys
> :docstrings
.:: chars ::.
Show chars (hotkeys) pressed during current session
.:: cmds ::.
Show colon commands typed during current session
.:: docstrings ::.
Print/return the docstrings of methods defined on this class
.:: errors ::.
Print/return any colon commands that raised exceptions (w/ traceback)
.:: history ::.
Print/return successful colon commands used (default 10)
.:: ipython ::.
Start ipython shell. To continue back to the input loop, use 'ctrl + d'
.:: pdb ::.
Start pdb (debugger). To continue back to the input loop, use 'c'
.:: shortcuts ::.
Print/return any hotkey shortcuts defined on this class
.:: wishlist ::.
Show the wishlist (of hotkeys and commands that don't exist yet)
Sub-class example
~~~~~~~~~~~~~~~~~
- Import ``GetCharLoop`` and sub-class it
- Initialize the sub-class and call it
..
Save the following to ``mine.py``
::
from functools import partial
from chloop import GetCharLoop
class Mine(GetCharLoop):
"""A sub-class of GetCharLoop"""
def __init__(self, *args, **kwargs):
# Process any extra/custom kwargs here and set some attributes
self._mything = kwargs.pop('mything', 'some default value')
super(Mine, self).__init__(*args, **kwargs)
# Add some single-key shorcuts that call methods on `self`
self._chfunc_dict_update([
('h', (self.history,
'display recent command history')),
('e', (self.errors,
'display recent errors')),
])
def somefunc(self, *args):
"""Joins the args passed to it into a string"""
args_as_one = ' '.join(args)
print(repr(args_as_one))
return args_as_one
def lame(self):
"""raise exception"""
return 1/0
if __name__ == '__main__':
m = Mine(prompt='\nmyprompt> ')
m._add_hotkey('a', lambda: print('hello'), 'say hello')
m()
..
Assuming the above code is in a file called ``mine.py``
::
% python mine.py
myprompt> :somefunc here are some args
u'here are some args'
myprompt> :shortcuts
'e' -- display recent errors
'h' -- display recent command history
'a' -- say hello
myprompt> a
hello
myprompt> :lame
======================================================================
Traceback (most recent call last):
File "/home/ken/chloop/chloop/__init__.py", line 232, in __call__
value = cmd_func()
File "main.py", line 33, in lame
return 1/0
ZeroDivisionError: integer division or modulo by zero
cmd: u'lame'
args: []
Extended example
~~~~~~~~~~~~~~~~
This example shows a subset of actual functionality from mocp-cli and
assumes the moc wrapper is avaialbe.
.. code:: python
from functools import partial
from collections import OrderedDict
from chloop import GetCharLoop
import moc
class SimpleMusicPlayer(GetCharLoop):
"""Simplified music player interface using MOC backend"""
def seek(self, num):
"""Seek forward or backward by specified seconds"""
moc.seek(int(num))
def go(self, timestamp):
"""Jump to a particular timestamp"""
moc.go(timestamp)
def find(self, *glob_patterns):
"""Find and select audio files at specified glob patterns"""
moc.find_select_and_play(*glob_patterns)
shortcuts = OrderedDict([
(' ', (moc.toggle_pause, 'pause/unpause')),
('i', (lambda: print(moc.info_string()), 'show info about currently playing file')),
('f', (partial(moc.find_and_play, '.'), 'find and play audio files found in current directory')),
('F', (partial(moc.find_select_and_play, '.'), 'find, select, and play audio files found in current directory')),
('Q', (moc.stop_server, 'stop MOC server and quit')),
('n', (moc.next, 'next file in playlist')),
('p', (moc.previous, 'previous file in playlist')),
('H', (partial(moc.seek, -30), 'rewind 30 seconds')),
('h', (partial(moc.seek, -5), 'rewind 5 seconds')),
('L', (partial(moc.seek, 30), 'fast forward 30 seconds')),
('l', (partial(moc.seek, 5), 'fast forward 5 seconds')),
('j', (moc.volume_down, 'lower volume')),
('k', (moc.volume_up, 'raise volume')),
('q', (lambda: None, 'quit')),
])
# Create and start the music player interface
player = SimpleMusicPlayer(
chfunc_dict=shortcuts,
name='simple-music',
prompt='music> ',
break_chars=['q', 'Q']
)
if __name__ == '__main__':
player()
Then after starting the repl:
::
music> :shortcuts
Space -- pause/unpause
i -- show info about currently playing file
f -- find and play audio files found in current directory
F -- find, select, and play audio files found in current directory
Q -- stop MOC server and quit
n -- next file in playlist
p -- previous file in playlist
H -- rewind 30 seconds
h -- rewind 5 seconds
L -- fast foward 30 seconds
l -- fast foward 5 seconds
j -- lower volume
k -- raise volume
q -- quit
API Overview
------------
Core Class
~~~~~~~~~~
- **``GetCharLoop(*args, **kwargs)``** - Main framework class for
building character-driven interactive tools
- ``chfunc_dict``: OrderedDict mapping characters to (function,
help_text) tuples for hotkeys
- ``prompt``: String to display when asking for input (default:
``'\n> '``)
- ``name``: Value for Redis collection naming to isolate different
tool instances
- ``break_chars``: List of characters that exit the loop (can
trigger functions before exit)
- ``input_hook``: Callable receiving ``**kwargs`` to process user
input after ‘-’ key pressed
- ``pre_input_hook``: Callable receiving no args executed when ``-``
is pressed, returning dict of data to input_hook
- ``post_input_hook``: Callable receiving no args executed after
input collection, returning dict of data to input_hook
- Returns: Configured GetCharLoop instance ready for direct use
- Internal calls: ``rh.Collection()``
Primary Methods
~~~~~~~~~~~~~~~
- **``GetCharLoop.__call__()``** - Start the interactive character loop
- Returns: None (runs until interrupted with Ctrl+C or Ctrl+D)
- Internal calls: ``ih.getchar()``, ``self.docstrings()``,
``self.shortcuts()``, ``ih.user_input_fancy()``,
``bh.call_func()``, ``ih.user_input()``, ``ih.start_ipython()``
Built-in Commands
~~~~~~~~~~~~~~~~~
All public methods automatically become ``:commands`` through naming
convention:
- **``GetCharLoop.docstrings(*args)``** - Display all available
commands with their documentation
- Returns: String containing formatted docstring output
- Internal calls: None
- **``GetCharLoop.shortcuts(*args)``** - Show configured hotkey
mappings and their descriptions
- Returns: String containing formatted shortcut output
- Internal calls: None
- **``GetCharLoop.history(*args)``** - Display recent successful
commands
- ``*args`` - Optional limit parameter (default 10)
- Returns: None (prints formatted history)
- Internal calls: ``ih.from_string()``
- **``GetCharLoop.errors(*args)``** - Show recent command errors with
full tracebacks
- ``*args`` - Optional limit parameter (default 10)
- Returns: None (prints formatted error output)
- Internal calls: ``ih.from_string()``
- **``GetCharLoop.chars()``** - Display characters pressed during
current session
- Returns: None (prints character history)
- Internal calls: None
- **``GetCharLoop.cmds()``** - Show colon commands typed during current
session
- Returns: None (prints command history)
- Internal calls: None
- **``GetCharLoop.wishlist()``** - Display captured user intent for
non-existent commands and hotkeys
- Returns: None (prints formatted wishlist)
- Internal calls: None
Special Commands
~~~~~~~~~~~~~~~~
- **``:pdb``** - Launch Python debugger
- **``:ipython``** - Start IPython shell with ``self`` available for
inspection
Extension Methods
~~~~~~~~~~~~~~~~~
- **``GetCharLoop._add_hotkey(ch, func, help_string)``** - Register
single-character hotkey
- ``ch``: Character to trigger the hotkey
- ``func``: Callable object accepting no arguments (use
``functools.partial`` if needed)
- ``help_string``: Description shown in ``:shortcuts`` output
- Returns: None
- Internal calls: None
- **``GetCharLoop._chfunc_dict_update(obj)``** - Bulk update hotkey
mappings
- ``obj``: List of tuples or dict containing (character, (function,
help_text)) mappings
- Returns: None
- Internal calls: None
Raw data
{
"_id": null,
"home_page": "https://github.com/kenjyco/chloop",
"name": "chloop",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "repl, redis, cli, command-line, command, history, kenjyco",
"author": "Ken",
"author_email": "kenjyco@gmail.com",
"download_url": "https://github.com/kenjyco/chloop/tarball/v0.2.24",
"platform": null,
"description": "chloop is a Redis-backed character-driven REPL framework designed for\ndevelopers who want to build custom interactive tools quickly and\nefficiently while providing progressive complexity. The library\noptimizes for single-keystroke efficiency while also leveraging vim\u2019s\ncolon command paradigm to transform command-line interactions from\nsequential operations into immediate context-aware experiences.\n\nThe core philosophy centers on **cognitive load reduction through muscle\nmemory development**. Instead of forcing users to remember complex\ncommand syntax or navigate menus, chloop enables the creation of\ninterfaces where common actions become instinctive single keystrokes,\nwhile advanced functionality remains accessible through discoverable\ncolon commands.\n\n**Who benefits from this library:** - **Domain experts** who need\nimmediate control over complex systems (audio/video exploration, API\ntesting, data analysis) - **Interactive application developers**\nbuilding tools for power users who value efficiency over discovery -\n**CLI tool creators** who want to provide both accessibility for\nbeginners and efficiency for experts - **Content analysts** needing\ndistraction-free, keyboard-driven workflows for media exploration -\n**Researchers** who need to rapidly navigate and annotate large datasets\nor media collections\n\nReal-world implementations include the **mocp-cli** package for\ninteractive audio exploration with timestamp marking, and **vlc-helper**\nfor precise video control and screenshot capture, demonstrating chloop\u2019s\neffectiveness in media analysis workflows.\n\nInstall\n-------\n\nIf you don\u2019t have `docker <https://docs.docker.com/get-docker>`__\ninstalled, install Redis and start server\n\n::\n\n sudo apt-get install -y redis-server\n\nor\n\n::\n\n brew install redis\n brew services start redis\n\nInstall with ``pip``\n\n::\n\n pip install chloop\n\n..\n\n Optionally install ipython with ``pip install ipython`` to enable\n ``:ipython`` colon command on a GetCharLoop instance. Also\n ``pip install pdbpp`` for an improved debug experience when using\n ``:pdb`` colon command.\n\nQuickStart\n----------\n\nThe ``GetCharLoop`` class is provided by the ``chloop`` package. Calling\nan **instance** of this class starts a REPL session, which the user can\nend by pressing ``Ctrl`` + ``d`` or ``Ctrl`` + ``c``.\n\nThe **first** character you type at the REPL prompt is significant.\n\nThe colon\n~~~~~~~~~\n\nHitting the ``:`` key at the prompt will allow you to enter a command\nand any arguments you need to pass to that command.\n\n- ``:docstrings`` to view docstrings of methods defined on the class\n- ``:errors`` to view colon commands that raised exceptions\n- ``:history`` view colon commands issued\n- ``:pdb`` to start a pdb session (debugging/inspection)\n- ``:ipython`` to start ipython shell\n- ``:shortcuts`` to view hotkey shortcuts\n\nAny methods added to your sub-class of ``GetCharLoop`` are callable as\n**colon commands**, as long as they do not start with an underscore\n(``_``). Methods should **only accept ``*args``**, if anything.\n\n For any methods/commands that should not be logged to the history,\n append the method name to the end of the ``self._DONT_LOG_CMDS``\n list.\n\nThe dash\n~~~~~~~~\n\nHitting the ``-`` key at the prompt will allow you to type a note.\n\nThe question mark\n~~~~~~~~~~~~~~~~~\n\nHitting the ``?`` key at the prompt will display the class docstring(s)\nand the startup message.\n\nHitting the ``?`` key a second time will show the available colon\ncommands and shortcuts (equivalent to issuing ``:docstrings`` and\n``:shortcuts``)\n\nOther keys\n~~~~~~~~~~\n\nHitting any other key at the prompt will do one of the following:\n\n- call a **registered shortcut function** bound to the key (use\n ``:shortcuts`` command to see what is available)\n- display the character and its integer ordinal\n\nA hotkey can be bound to any callable object that accepts no arguments.\nUse ``functools.partial`` (if necessary) to create a callable accepting\nno arguments.\n\nBasic example\n~~~~~~~~~~~~~\n\n The default prompt if none is specified is ``>``.\n\n::\n\n % python3 -c 'from chloop import GetCharLoop; GetCharLoop()()'\n\n > ?\n Loop forever, receiving character input from user and performing actions\n\n - ctrl+d or ctrl+c to break the loop\n - ':' to enter a command (and any arguments)\n - any method defined on GetCharLoop (or a sub-class) will be callable\n as a \"colon command\" (if its name does not start with '_')\n - the method for the `:command` should only accept `*args`\n - '-' to allow user to provide input that will be processed by the `input_hook`\n - '?' to show class doc and the startup message\n - '??' to show class doc, the startup message, docstrings (:commands), and shortcuts\n\n :docstrings to see all colon commands\n :shortcuts to see all hotkeys\n\n\n > :docstrings\n .:: chars ::.\n Show chars (hotkeys) pressed during current session\n\n .:: cmds ::.\n Show colon commands typed during current session\n\n .:: docstrings ::.\n Print/return the docstrings of methods defined on this class\n\n .:: errors ::.\n Print/return any colon commands that raised exceptions (w/ traceback)\n\n .:: history ::.\n Print/return successful colon commands used (default 10)\n\n .:: ipython ::.\n Start ipython shell. To continue back to the input loop, use 'ctrl + d'\n\n .:: pdb ::.\n Start pdb (debugger). To continue back to the input loop, use 'c'\n\n .:: shortcuts ::.\n Print/return any hotkey shortcuts defined on this class\n\n .:: wishlist ::.\n Show the wishlist (of hotkeys and commands that don't exist yet)\n\nSub-class example\n~~~~~~~~~~~~~~~~~\n\n- Import ``GetCharLoop`` and sub-class it\n- Initialize the sub-class and call it\n\n..\n\n Save the following to ``mine.py``\n\n::\n\n from functools import partial\n from chloop import GetCharLoop\n\n\n class Mine(GetCharLoop):\n \"\"\"A sub-class of GetCharLoop\"\"\"\n def __init__(self, *args, **kwargs):\n # Process any extra/custom kwargs here and set some attributes\n self._mything = kwargs.pop('mything', 'some default value')\n\n super(Mine, self).__init__(*args, **kwargs)\n\n # Add some single-key shorcuts that call methods on `self`\n self._chfunc_dict_update([\n ('h', (self.history,\n 'display recent command history')),\n ('e', (self.errors,\n 'display recent errors')),\n ])\n\n\n def somefunc(self, *args):\n \"\"\"Joins the args passed to it into a string\"\"\"\n args_as_one = ' '.join(args)\n print(repr(args_as_one))\n return args_as_one\n\n def lame(self):\n \"\"\"raise exception\"\"\"\n return 1/0\n\n\n if __name__ == '__main__':\n m = Mine(prompt='\\nmyprompt> ')\n m._add_hotkey('a', lambda: print('hello'), 'say hello')\n m()\n\n..\n\n Assuming the above code is in a file called ``mine.py``\n\n::\n\n % python mine.py\n\n myprompt> :somefunc here are some args\n u'here are some args'\n\n myprompt> :shortcuts\n 'e' -- display recent errors\n 'h' -- display recent command history\n 'a' -- say hello\n\n myprompt> a\n hello\n\n myprompt> :lame\n ======================================================================\n Traceback (most recent call last):\n File \"/home/ken/chloop/chloop/__init__.py\", line 232, in __call__\n value = cmd_func()\n File \"main.py\", line 33, in lame\n return 1/0\n ZeroDivisionError: integer division or modulo by zero\n\n cmd: u'lame'\n args: []\n\nExtended example\n~~~~~~~~~~~~~~~~\n\n This example shows a subset of actual functionality from mocp-cli and\n assumes the moc wrapper is avaialbe.\n\n.. code:: python\n\n from functools import partial\n from collections import OrderedDict\n from chloop import GetCharLoop\n import moc\n\n\n class SimpleMusicPlayer(GetCharLoop):\n \"\"\"Simplified music player interface using MOC backend\"\"\"\n\n def seek(self, num):\n \"\"\"Seek forward or backward by specified seconds\"\"\"\n moc.seek(int(num))\n\n def go(self, timestamp):\n \"\"\"Jump to a particular timestamp\"\"\"\n moc.go(timestamp)\n\n def find(self, *glob_patterns):\n \"\"\"Find and select audio files at specified glob patterns\"\"\"\n moc.find_select_and_play(*glob_patterns)\n\n\n shortcuts = OrderedDict([\n (' ', (moc.toggle_pause, 'pause/unpause')),\n ('i', (lambda: print(moc.info_string()), 'show info about currently playing file')),\n ('f', (partial(moc.find_and_play, '.'), 'find and play audio files found in current directory')),\n ('F', (partial(moc.find_select_and_play, '.'), 'find, select, and play audio files found in current directory')),\n ('Q', (moc.stop_server, 'stop MOC server and quit')),\n ('n', (moc.next, 'next file in playlist')),\n ('p', (moc.previous, 'previous file in playlist')),\n ('H', (partial(moc.seek, -30), 'rewind 30 seconds')),\n ('h', (partial(moc.seek, -5), 'rewind 5 seconds')),\n ('L', (partial(moc.seek, 30), 'fast forward 30 seconds')),\n ('l', (partial(moc.seek, 5), 'fast forward 5 seconds')),\n ('j', (moc.volume_down, 'lower volume')),\n ('k', (moc.volume_up, 'raise volume')),\n ('q', (lambda: None, 'quit')),\n ])\n\n # Create and start the music player interface\n player = SimpleMusicPlayer(\n chfunc_dict=shortcuts,\n name='simple-music',\n prompt='music> ',\n break_chars=['q', 'Q']\n )\n\n if __name__ == '__main__':\n player()\n\nThen after starting the repl:\n\n::\n\n music> :shortcuts\n Space -- pause/unpause\n i -- show info about currently playing file\n f -- find and play audio files found in current directory\n F -- find, select, and play audio files found in current directory\n Q -- stop MOC server and quit\n n -- next file in playlist\n p -- previous file in playlist\n H -- rewind 30 seconds\n h -- rewind 5 seconds\n L -- fast foward 30 seconds\n l -- fast foward 5 seconds\n j -- lower volume\n k -- raise volume\n q -- quit\n\nAPI Overview\n------------\n\nCore Class\n~~~~~~~~~~\n\n- **``GetCharLoop(*args, **kwargs)``** - Main framework class for\n building character-driven interactive tools\n\n - ``chfunc_dict``: OrderedDict mapping characters to (function,\n help_text) tuples for hotkeys\n - ``prompt``: String to display when asking for input (default:\n ``'\\n> '``)\n - ``name``: Value for Redis collection naming to isolate different\n tool instances\n - ``break_chars``: List of characters that exit the loop (can\n trigger functions before exit)\n - ``input_hook``: Callable receiving ``**kwargs`` to process user\n input after \u2018-\u2019 key pressed\n - ``pre_input_hook``: Callable receiving no args executed when ``-``\n is pressed, returning dict of data to input_hook\n - ``post_input_hook``: Callable receiving no args executed after\n input collection, returning dict of data to input_hook\n - Returns: Configured GetCharLoop instance ready for direct use\n - Internal calls: ``rh.Collection()``\n\nPrimary Methods\n~~~~~~~~~~~~~~~\n\n- **``GetCharLoop.__call__()``** - Start the interactive character loop\n\n - Returns: None (runs until interrupted with Ctrl+C or Ctrl+D)\n - Internal calls: ``ih.getchar()``, ``self.docstrings()``,\n ``self.shortcuts()``, ``ih.user_input_fancy()``,\n ``bh.call_func()``, ``ih.user_input()``, ``ih.start_ipython()``\n\nBuilt-in Commands\n~~~~~~~~~~~~~~~~~\n\nAll public methods automatically become ``:commands`` through naming\nconvention:\n\n- **``GetCharLoop.docstrings(*args)``** - Display all available\n commands with their documentation\n\n - Returns: String containing formatted docstring output\n - Internal calls: None\n\n- **``GetCharLoop.shortcuts(*args)``** - Show configured hotkey\n mappings and their descriptions\n\n - Returns: String containing formatted shortcut output\n - Internal calls: None\n\n- **``GetCharLoop.history(*args)``** - Display recent successful\n commands\n\n - ``*args`` - Optional limit parameter (default 10)\n - Returns: None (prints formatted history)\n - Internal calls: ``ih.from_string()``\n\n- **``GetCharLoop.errors(*args)``** - Show recent command errors with\n full tracebacks\n\n - ``*args`` - Optional limit parameter (default 10)\n - Returns: None (prints formatted error output)\n - Internal calls: ``ih.from_string()``\n\n- **``GetCharLoop.chars()``** - Display characters pressed during\n current session\n\n - Returns: None (prints character history)\n - Internal calls: None\n\n- **``GetCharLoop.cmds()``** - Show colon commands typed during current\n session\n\n - Returns: None (prints command history)\n - Internal calls: None\n\n- **``GetCharLoop.wishlist()``** - Display captured user intent for\n non-existent commands and hotkeys\n\n - Returns: None (prints formatted wishlist)\n - Internal calls: None\n\nSpecial Commands\n~~~~~~~~~~~~~~~~\n\n- **``:pdb``** - Launch Python debugger\n- **``:ipython``** - Start IPython shell with ``self`` available for\n inspection\n\nExtension Methods\n~~~~~~~~~~~~~~~~~\n\n- **``GetCharLoop._add_hotkey(ch, func, help_string)``** - Register\n single-character hotkey\n\n - ``ch``: Character to trigger the hotkey\n - ``func``: Callable object accepting no arguments (use\n ``functools.partial`` if needed)\n - ``help_string``: Description shown in ``:shortcuts`` output\n - Returns: None\n - Internal calls: None\n\n- **``GetCharLoop._chfunc_dict_update(obj)``** - Bulk update hotkey\n mappings\n\n - ``obj``: List of tuples or dict containing (character, (function,\n help_text)) mappings\n - Returns: None\n - Internal calls: None\n\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A Redis-backed REPL that saves command history, output, & errors",
"version": "0.2.24",
"project_urls": {
"Download": "https://github.com/kenjyco/chloop/tarball/v0.2.24",
"Homepage": "https://github.com/kenjyco/chloop"
},
"split_keywords": [
"repl",
" redis",
" cli",
" command-line",
" command",
" history",
" kenjyco"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "a2e5c08948973ee5574e9b4b0b5dcb3316287b325eec0eb4344d09da8fa6b665",
"md5": "af21dab85b964d710151460b05db0c53",
"sha256": "4ca05a4794a3a2ec36b10dbdbb7ec8b4b1246ddf7b541cd76bcb41276e229feb"
},
"downloads": -1,
"filename": "chloop-0.2.24-py3-none-any.whl",
"has_sig": false,
"md5_digest": "af21dab85b964d710151460b05db0c53",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 10080,
"upload_time": "2025-07-23T18:31:40",
"upload_time_iso_8601": "2025-07-23T18:31:40.880804Z",
"url": "https://files.pythonhosted.org/packages/a2/e5/c08948973ee5574e9b4b0b5dcb3316287b325eec0eb4344d09da8fa6b665/chloop-0.2.24-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-23 18:31:40",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "kenjyco",
"github_project": "chloop",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "bg-helper",
"specs": []
},
{
"name": "click",
"specs": [
[
">=",
"6.0"
]
]
},
{
"name": "fs-helper",
"specs": []
},
{
"name": "redis-helper",
"specs": []
}
],
"lcname": "chloop"
}