Merge remote-tracking branch 'PeridexisErrant/doc-keybinds' into develop

develop
lethosor 2016-10-23 18:26:42 -04:00
commit a2525b92ac
3 changed files with 133 additions and 19 deletions

@ -72,6 +72,8 @@ Fixes
Misc Improvements
-----------------
- Documented all default keybindings (from :file:`dfhack.init-example`) in the
docs for the relevant commands; updates enforced by build system.
- `lua` and `gui/gm-editor` now support the same aliases (``scr``, ``unit``, etc.)
- `remotefortressreader`: Added support for

@ -15,15 +15,70 @@ serve to show the default.
# pylint:disable=redefined-builtin
import fnmatch
from io import open
from itertools import starmap
import os
import re
import shlex # pylint:disable=unused-import
import sys
# -- Support :dfhack-keybind:`command` ------------------------------------
# this is a custom directive that pulls info from dfhack.init-example
from docutils import nodes
from docutils.parsers.rst import roles
def get_keybinds():
"""Get the implemented keybinds, and return a dict of
{tool: [(full_command, keybinding, context), ...]}.
"""
with open('dfhack.init-example') as f:
lines = [l.replace('keybinding add', '').strip() for l in f.readlines()
if l.startswith('keybinding add')]
keybindings = dict()
for k in lines:
first, command = k.split(' ', maxsplit=1)
bind, context = (first.split('@') + [''])[:2]
if ' ' not in command:
command = command.replace('"', '')
tool = command.split(' ')[0].replace('"', '')
keybindings[tool] = keybindings.get(tool, []) + [
(command, bind.split('-'), context)]
return keybindings
KEYBINDS = get_keybinds()
# pylint:disable=unused-argument,dangerous-default-value,too-many-arguments
def dfhack_keybind_role_func(role, rawtext, text, lineno, inliner,
options={}, content=[]):
"""Custom role parser for DFHack default keybinds."""
roles.set_classes(options)
if text not in KEYBINDS:
msg = inliner.reporter.error(
'no keybinding for {} in dfhack.init-example'.format(text),
line=lineno)
prb = inliner.problematic(rawtext, rawtext, msg)
return [prb], [msg]
newnode = nodes.paragraph()
for cmd, key, ctx in KEYBINDS[text]:
n = nodes.paragraph()
newnode += n
n += nodes.strong('Keybinding: ', 'Keybinding: ')
for k in key:
n += nodes.inline(k, k, classes=['kbd'])
if cmd != text:
n += nodes.inline(' -> ', ' -> ')
n += nodes.literal(cmd, cmd, classes=['guilabel'])
if ctx:
n += nodes.inline(' in ', ' in ')
n += nodes.literal(ctx, ctx)
return [newnode], []
roles.register_canonical_role('dfhack-keybind', dfhack_keybind_role_func)
# -- Autodoc for DFhack scripts -------------------------------------------
def doc_dir(dirname, files):
@ -46,28 +101,41 @@ def doc_dir(dirname, files):
command = line
def doc_all_dirs():
"""Collect the commands and paths to include in our docs."""
scripts = []
for root, _, files in os.walk('scripts'):
scripts.extend(doc_dir(root, files))
return tuple(scripts)
DOC_ALL_DIRS = doc_all_dirs()
def document_scripts():
"""Autodoc for files with the magic script documentation marker strings.
Returns a dict of script-kinds to lists of .rst include directives.
"""
# First, we collect the commands and paths to include in our docs
scripts = []
for root, _, files in os.walk('scripts'):
scripts.extend(doc_dir(root, files))
# Next we split by type and create include directives sorted by command
kinds = {'base': [], 'devel': [], 'fix': [], 'gui': [], 'modtools': []}
for s in scripts:
for s in DOC_ALL_DIRS:
k_fname = s[0].split('/', 1)
if len(k_fname) == 1:
kinds['base'].append(s)
else:
kinds[k_fname[0]].append(s)
template = '.. _{}:\n\n.. include:: /{}\n' +\
' :start-after: {}\n :end-before: {}\n'
return {key: '\n\n'.join(starmap(template.format, sorted(value)))
def template(arg):
tmp = '.. _{}:\n\n.. include:: /{}\n' +\
' :start-after: {}\n :end-before: {}\n'
if arg[0] in KEYBINDS:
tmp += '\n:dfhack-keybind:`{}`\n'.format(arg[0])
return tmp.format(*arg)
return {key: '\n\n'.join(map(template, sorted(value)))
for key, value in kinds.items()}
def write_script_docs():
"""
Creates a file for eack kind of script (base/devel/fix/gui/modtools)
@ -97,10 +165,23 @@ def write_script_docs():
outfile.write(kinds[k])
# Actually call the docs generator
write_script_docs()
def all_keybinds_documented():
"""Check that all keybindings are documented with the :dfhack-keybind:
directive somewhere."""
configured_binds = set(KEYBINDS)
script_commands = set(i[0] for i in DOC_ALL_DIRS)
with open('./docs/Plugins.rst') as f:
plugin_binds = set(re.findall(':dfhack-keybind:`(.*?)`', f.read()))
undocumented_binds = configured_binds - script_commands - plugin_binds
if undocumented_binds:
raise ValueError('The following DFHack commands have undocumented'
'keybindings: {}'.format(sorted(undocumented_binds)))
# Actually call the docs generator and run test
write_script_docs()
all_keybinds_documented()
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.

@ -353,7 +353,8 @@ This plugin adds an option to the :kbd:`q` menu when `enabled <enable>`.
command-prompt
==============
An in-game DFHack terminal, where you can enter other commands.
Best used from a keybinding; by default :kbd:`Ctrl`:kbd:`Shift`:kbd:`P`.
:dfhack-keybind:`command-prompt`
Usage: ``command-prompt [entry]``
@ -372,13 +373,11 @@ Otherwise somewhat similar to `gui/quickcmd`.
hotkeys
=======
Opens an in-game screen showing which DFHack keybindings are
active in the current context.
active in the current context. See also `hotkey-notes`.
.. image:: images/hotkeys.png
Type ``hotkeys`` into the DFHack console to open the screen,
or bind the command to a globally active hotkey. The default
keybinding is :kbd:`Ctrl`:kbd:`F1`. See also `hotkey-notes`.
:dfhack-keybind:`hotkeys`
.. _rb:
@ -673,12 +672,16 @@ Unit order examples::
The orderings are defined in ``hack/lua/plugins/sort/*.lua``
:dfhack-keybind:`sort-units`
.. _stocks:
stocks
======
Replaces the DF stocks screen with an improved version.
:dfhack-keybind:`stocks`
.. _stocksettings:
.. _stockpiles:
@ -690,6 +693,7 @@ See `gui/stockpiles` for an in-game interface.
:copystock: Copies the parameters of the currently highlighted stockpile to the custom
stockpile settings and switches to custom stockpile placement mode, effectively
allowing you to copy/paste stockpiles easily.
:dfhack-keybind:`copystock`
:savestock: Saves the currently highlighted stockpile's settings to a file in your Dwarf
Fortress folder. This file can be used to copy settings between game saves or
@ -888,7 +892,7 @@ Invoked as::
job-material <inorganic-token>
Intended to be used as a keybinding:
:dfhack-keybind:`job-material`
* In :kbd:`q` mode, when a job is highlighted within a workshop or furnace,
changes the material of the job. Only inorganic materials can be used
@ -901,6 +905,8 @@ job-duplicate
In :kbd:`q` mode, when a job is highlighted within a workshop or furnace
building, calling ``job-duplicate`` instantly duplicates the job.
:dfhack-keybind:`job-duplicate`
.. _autogems:
autogems
@ -1090,6 +1096,8 @@ spotclean
Works like ``clean map snow mud``, but only for the tile under the cursor. Ideal
if you want to keep that bloody entrance ``clean map`` would clean up.
:dfhack-keybind:`spotclean`
.. _autodump:
autodump
@ -1112,10 +1120,16 @@ Options:
:destroy-here: As ``destroy``, but only the selected item in the :kbd:`k` list,
or inside a container.
Alias ``autodump-destroy-here``, for keybindings.
:dfhack-keybind:`autodump-destroy-here`
:visible: Only process items that are not hidden.
:hidden: Only process hidden items.
:forbidden: Only process forbidden items (default: only unforbidden).
``autodump-destroy-item`` destroys the selected item, which may be selected
in the :kbd:`k` list, or inside a container. If called again before the game
is resumed, cancels destruction of the item.
:dfhack-keybind:`autodump-destroy-item`
cleanowned
==========
@ -1153,6 +1167,8 @@ Options:
:prefs: Show dwarf preferences summary
:reload: Reload configuration file (``dfhack-config/dwarfmonitor.json``)
:dfhack-keybind:`dwarfmonitor`
Widget configuration:
The following types of widgets (defined in :file:`hack/lua/plugins/dwarfmonitor.lua`)
@ -1240,7 +1256,16 @@ Options:
workNow
=======
Force all dwarves to look for a job immediately, or as soon as the game is unpaused.
Don't allow dwarves to idle if any jobs are available.
When workNow is active, every time the game pauses, DF will make dwarves
perform any appropriate available jobs. This includes when you one step
through the game using the pause menu. Usage:
:workNow: print workNow status
:workNow 0: deactivate workNow
:workNow 1: activate workNow (look for jobs on pause, and only then)
:workNow 2: make dwarves look for jobs whenever a job completes
.. _seedwatch:
@ -1278,6 +1303,8 @@ zone
====
Helps a bit with managing activity zones (pens, pastures and pits) and cages.
:dfhack-keybind:`zone`
Options:
:set: Set zone or cage under cursor as default for future assigns.
@ -1752,6 +1779,8 @@ Basic commands:
to remove designations, for if you accidentally set 50 levels at once.
:diglx: Also cross z-levels, digging stairs as needed. Alias for ``digl x``.
:dfhack-keybind:`digv`
.. _digexp:
digexp
@ -2223,6 +2252,8 @@ Usage:
* When viewing unit details, body-swaps into that unit.
* In the main adventure mode screen, reverts transient swap.
:dfhack-keybind:`adv-bodyswap`
.. _createitem:
createitem