reorganize init scripts into dfhack-config (#2232)

* reorganize init scripts into dfhack-config

allows player init scripts to build on defaults instead of replace them
this also moves the init scripts out of the main df directory

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* escape asterisks in docs

* remove unneeded dfhack.init file creation for test

* write the test init script to the new init dir

* create the init dir before trying to write a file

* rename default init files for clarity

* Update changelog

* Update docs/changelog.txt

Co-authored-by: Alan <lethosor@users.noreply.github.com>

* Try to get buildmaster to work with old branches

* Update changelog

* get keybindings from all init scripts

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Fix spacing in changelog

* split default loading into its own file

* update docs with new changes

* update help text wording in default init files

* Apply suggestions from code review

Co-authored-by: Alan <lethosor@users.noreply.github.com>

* Alphabetize changelog

* Update onMapLoad.default.init

* Update onMapLoad.init

* Update Core.rst

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Alan <lethosor@users.noreply.github.com>
develop
Myk 2022-07-10 08:54:55 -07:00 committed by GitHub
parent b560bcc256
commit 28e15162a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 329 additions and 208 deletions

@ -100,7 +100,6 @@ jobs:
run: |
export TERM=dumb
status=0
mv "$DF_FOLDER"/dfhack.init-example "$DF_FOLDER"/dfhack.init
script -qe -c "python ci/run-tests.py --headless --keep-status \"$DF_FOLDER\"" || status=$((status + 1))
python ci/check-rpc.py "$DF_FOLDER/dfhack-rpc.txt" || status=$((status + 2))
mkdir -p artifacts

@ -68,7 +68,16 @@ init_contents = change_setting(init_contents, 'FPS', 'YES')
if args.headless:
init_contents = change_setting(init_contents, 'PRINT_MODE', 'TEXT')
test_init_file = 'dfhackzzz_test.init' # Core sorts these alphabetically
init_path = 'dfhack-config/init'
if not os.path.isdir('hack/init'):
# we're on an old branch that still reads init files from the root dir
init_path = '.'
try:
os.mkdir(init_path)
except OSError as error:
# ignore already exists errors
pass
test_init_file = os.path.join(init_path, 'dfhackzzz_test.init') # Core sorts these alphabetically
with open(test_init_file, 'w') as f:
f.write('''
devel/dump-rpc dfhack-rpc.txt

@ -24,32 +24,40 @@ import sys
# -- Support :dfhack-keybind:`command` ------------------------------------
# this is a custom directive that pulls info from dfhack.init-example
# this is a custom directive that pulls info from default keybindings
from docutils import nodes
from docutils.parsers.rst import roles
sphinx_major_version = sphinx.version_info[0]
def get_keybinds():
def get_keybinds(root, files, keybindings):
"""Add keybindings in the specified files to the
given keybindings dict.
"""
for file in files:
with open(os.path.join(root, file)) as f:
lines = [l.replace('keybinding add', '').strip() for l in f.readlines()
if l.startswith('keybinding add')]
for k in lines:
first, command = k.split(' ', 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)]
def get_all_keybinds(root_dir):
"""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(' ', 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)]
for root, _, files in os.walk(root_dir):
get_keybinds(root, files, keybindings)
return keybindings
KEYBINDS = get_keybinds()
KEYBINDS = get_all_keybinds('data/init')
# pylint:disable=unused-argument,dangerous-default-value,too-many-arguments

@ -1,3 +1,6 @@
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/init/
DESTINATION "${DFHACK_DATA_DESTINATION}/init")
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/quickfort/
DESTINATION "${DFHACK_DATA_DESTINATION}/data/quickfort")

@ -0,0 +1,8 @@
# Default DFHack commands to run on program init
# Please do not edit this file directly. It will be overwritten with new
# defaults when you update DFHack. Instead, add your configuration to
# dfhack-config/init/dfhack.init
script hack/init/dfhack.keybindings.init
script hack/init/dfhack.tools.init

@ -1,3 +1,9 @@
# Default DFHack keybindings
# Please do not edit this file directly. It will be overwritten with new
# defaults when you update DFHack. Instead, add your configuration to
# dfhack-config/init/dfhack.init
##############################
# Generic dwarfmode bindings #
##############################
@ -164,137 +170,3 @@ keybinding add Shift-B@pet/List/Unit "gui/autobutcher"
# view pathable tiles from active cursor
keybinding add Alt-Shift-P@dwarfmode/LookAround gui/pathable
############################
# UI and game logic tweaks #
############################
# stabilize the cursor of dwarfmode when switching menus
tweak stable-cursor
# stop stacked liquid/bar/thread/cloth items from lasting forever
# if used in reactions that use only a fraction of the dimension.
# might be fixed by DF
# tweak fix-dimensions
# make reactions requiring containers usable in advmode - the issue is
# that the screen asks for those reagents to be selected directly
tweak advmode-contained
# support Shift-Enter in Trade and Move Goods to Depot screens for faster
# selection; it selects the current item or stack and scrolls down one line
tweak fast-trade
# stop the right list in military->positions from resetting to top all the time
tweak military-stable-assign
# in same list, color units already assigned to squads in brown & green
tweak military-color-assigned
# make crafted cloth items wear out with time like in old versions (bug 6003)
tweak craft-age-wear
# stop adamantine clothing from wearing out (bug 6481)
#tweak adamantine-cloth-wear
# Add "Select all" and "Deselect all" options to farm plot menus
tweak farm-plot-select
# Add Shift-Left/Right controls to import agreement screen
tweak import-priority-category
# Fixes a crash in the work order contition material list (bug 9905).
tweak condition-material
# Adds an option to clear currently-bound hotkeys
tweak hotkey-clear
# Allows lowercase letters in embark profile names, and allows exiting the name prompt without saving
tweak embark-profile-name
# Reduce performance impact of temperature changes
tweak fast-heat 100
# Misc. UI tweaks
tweak block-labors # Prevents labors that can't be used from being toggled
tweak burrow-name-cancel
tweak cage-butcher
tweak civ-view-agreement
tweak do-job-now
tweak eggs-fertile
tweak fps-min
tweak hide-priority
tweak kitchen-prefs-all
tweak kitchen-prefs-empty
tweak max-wheelbarrow
tweak partial-items
tweak shift-8-scroll
tweak stone-status-all
tweak title-start-rename
tweak tradereq-pet-gender
###########################
# Globally acting plugins #
###########################
# Display DFHack version on title screen
enable title-version
# Dwarf Manipulator (simple in-game Dwarf Therapist replacement)
enable manipulator
# Search tool in various screens (by falconne)
enable search
# Improved build material selection interface (by falconne)
enable automaterial
# Other interface improvement tools
enable \
confirm \
dwarfmonitor \
mousequery \
autogems \
autodump \
automelt \
autotrade \
buildingplan \
resume \
trackstop \
zone \
stocks \
autochop \
stockpiles
#end a line with a backslash to make it continue to the next line. The \ is deleted for the final command.
# Multiline commands are ONLY supported for scripts like dfhack.init. You cannot do multiline command manually on the DFHack console.
# You cannot extend a commented line.
# You can comment out the extension of a line.
# enable mouse controls and sand indicator in embark screen
embark-tools enable sticky sand mouse
# enable option to enter embark assistant
enable embark-assistant
###########
# Scripts #
###########
# write extra information to the gamelog
modtools/extra-gamelog enable
# extended status screen (bedrooms page)
enable gui/extended-status
# add information to item viewscreens
view-item-info enable
# a replacement for the "load game" screen
gui/load-screen enable
##############################
# Extra DFHack command files #
##############################
# Create a file named "onLoad.init" to run commands when a world is loaded
# and/or create a file named "onMapLoad.init" to run commands when a map is
# loaded. See the hack/examples/init/ directory for useful pre-made init files.

@ -0,0 +1,131 @@
# Default DFHack tool configuration
# Please do not edit this file directly. It will be overwritten with new
# defaults when you update DFHack. Instead, add your configuration to
# dfhack-config/init/dfhack.init
############################
# UI and game logic tweaks #
############################
# stabilize the cursor of dwarfmode when switching menus
tweak stable-cursor
# stop stacked liquid/bar/thread/cloth items from lasting forever
# if used in reactions that use only a fraction of the dimension.
# might be fixed by DF
# tweak fix-dimensions
# make reactions requiring containers usable in advmode - the issue is
# that the screen asks for those reagents to be selected directly
tweak advmode-contained
# support Shift-Enter in Trade and Move Goods to Depot screens for faster
# selection; it selects the current item or stack and scrolls down one line
tweak fast-trade
# stop the right list in military->positions from resetting to top all the time
tweak military-stable-assign
# in same list, color units already assigned to squads in brown & green
tweak military-color-assigned
# make crafted cloth items wear out with time like in old versions (bug 6003)
tweak craft-age-wear
# stop adamantine clothing from wearing out (bug 6481)
#tweak adamantine-cloth-wear
# Add "Select all" and "Deselect all" options to farm plot menus
tweak farm-plot-select
# Add Shift-Left/Right controls to import agreement screen
tweak import-priority-category
# Fixes a crash in the work order contition material list (bug 9905).
tweak condition-material
# Adds an option to clear currently-bound hotkeys
tweak hotkey-clear
# Allows lowercase letters in embark profile names, and allows exiting the name prompt without saving
tweak embark-profile-name
# Reduce performance impact of temperature changes
tweak fast-heat 100
# Misc. UI tweaks
tweak block-labors # Prevents labors that can't be used from being toggled
tweak burrow-name-cancel
tweak cage-butcher
tweak civ-view-agreement
tweak do-job-now
tweak eggs-fertile
tweak fps-min
tweak hide-priority
tweak kitchen-prefs-all
tweak kitchen-prefs-empty
tweak max-wheelbarrow
tweak partial-items
tweak shift-8-scroll
tweak stone-status-all
tweak title-start-rename
tweak tradereq-pet-gender
###########################
# Globally acting plugins #
###########################
# Display DFHack version on title screen
enable title-version
# Dwarf Manipulator (simple in-game Dwarf Therapist replacement)
enable manipulator
# Search tool in various screens (by falconne)
enable search
# Improved build material selection interface (by falconne)
enable automaterial
# Other interface improvement tools
enable \
confirm \
dwarfmonitor \
mousequery \
autogems \
autodump \
automelt \
autotrade \
buildingplan \
resume \
trackstop \
zone \
stocks \
autochop \
stockpiles
#end a line with a backslash to make it continue to the next line. The \ is deleted for the final command.
# Multiline commands are ONLY supported for scripts like dfhack.init. You cannot do multiline command manually on the DFHack console.
# You cannot extend a commented line.
# You can comment out the extension of a line.
# enable mouse controls and sand indicator in embark screen
embark-tools enable sticky sand mouse
# enable option to enter embark assistant
enable embark-assistant
###########
# Scripts #
###########
# write extra information to the gamelog
modtools/extra-gamelog enable
# extended status screen (bedrooms page)
enable gui/extended-status
# add information to item viewscreens
view-item-info enable
# a replacement for the "load game" screen
gui/load-screen enable

@ -0,0 +1,5 @@
# Default DFHack commands to run when a world is loaded
# Please do not edit this file directly. It will be overwritten with new
# defaults when you update DFHack. Instead, add your configuration to
# dfhack-config/init/onLoad.init

@ -0,0 +1,6 @@
# Default DFHack commands to run when a map is loaded, either in
# adventure or fort mode.
# Please do not edit this file directly. It will be overwritten with new
# defaults when you update DFHack. Instead, add your configuration to
# dfhack-config/init/onMapLoad.init

@ -0,0 +1,5 @@
# Default DFHack commands to run when a map is unloaded
# Please do not edit this file directly. It will be overwritten with new
# defaults when you update DFHack. Instead, add your configuration to
# dfhack-config/init/onMapUnload.init

@ -0,0 +1,5 @@
# Default DFHack commands to run when a world is unloaded
# Please do not edit this file directly. It will be overwritten with new
# defaults when you update DFHack. Instead, add your configuration to
# dfhack-config/init/onUnload.init

@ -0,0 +1,7 @@
# Load DFHack defaults.
#
# If you delete this file, it will reappear when you restart DFHack.
# Instead, please comment out the following line if you do not want DFHack to
# load its default configuration.
script hack/init/dfhack.default.init

@ -0,0 +1,7 @@
# Load DFHack defaults.
#
# If you delete this file, it will reappear when you restart DFHack.
# Instead, please comment out the following line if you do not want DFHack to
# load its default configuration.
script hack/init/onLoad.default.init

@ -0,0 +1,7 @@
# Load DFHack defaults.
#
# If you delete this file, it will reappear when you restart DFHack.
# Instead, please comment out the following line if you do not want DFHack to
# load its default configuration.
script hack/init/onMapLoad.default.init

@ -0,0 +1,7 @@
# Load DFHack defaults.
#
# If you delete this file, it will reappear when you restart DFHack.
# Instead, please comment out the following line if you do not want DFHack to
# load its default configuration.
script hack/init/onMapUnload.default.init

@ -0,0 +1,7 @@
# Load DFHack defaults.
#
# If you delete this file, it will reappear when you restart DFHack.
# Instead, please comment out the following line if you do not want DFHack to
# load its default configuration.
script hack/init/onUnload.default.init

@ -0,0 +1,5 @@
# This file runs when DFHack is initialized, when Dwarf Fortress is first
# started, before any world or save data is loaded.
#
# You can extend or override DFHack's default configuration by adding commands
# to this file.

@ -0,0 +1,6 @@
# This file runs when a world is loaded. This happens when you open a save file
# in fort, adventure, or legends mode. If a fort is being loaded, this file runs
# before any onMapLoad.init files.
#
# You can extend or override DFHack's default configuration by adding commands
# to this file.

@ -0,0 +1,5 @@
# This file runs when a map is loaded in adventure or fort mode, after any
# onLoad.init files (which run earlier, when the world is loaded).
#
# You can extend or override DFHack's default configuration by adding commands
# to this file.

@ -0,0 +1,5 @@
# This file runs when a fortress map is unloaded, before any onUnload.init files
# (which run later, when the world is unloaded).
#
# You can extend or override DFHack's default configuration by adding commands
# to this file.

@ -0,0 +1,4 @@
# This file runs when a world is unloaded.
#
# You can extend or override DFHack's default configuration by adding commands
# to this file.

@ -366,16 +366,27 @@ The following commands are *not* built-in, but offer similarly useful functions.
* `repeat`
.. _dfhack-config:
Configuration Files
===================
Most DFHack settings can be changed by modifying files in the ``dfhack-config``
folder (which is in the DF folder). The default versions of these files, if they
exist, are in ``dfhack-config/default`` and are installed when DFHack starts if
necessary.
.. _init-files:
Init Files
==========
----------
.. contents::
:local:
DFHack allows users to automatically run commonly-used DFHack commands
when DF is first loaded, when a game is loaded, and when a game is unloaded.
when DF is first loaded, when a world is loaded, when a map is loaded, when a
map is unloaded, and when a world is unloaded.
Init scripts function the same way they would if the user manually typed
in their contents, but are much more convenient. In order to facilitate
@ -385,32 +396,33 @@ save-specific init files in the save folders.
DFHack looks for init files in three places each time they could be run:
#. The main DF directory
#. The :file:`dfhack-config/init` subdirectory in the main DF directory
#. :file:`data/save/{world}/raw`, where ``world`` is the current save, and
#. :file:`data/save/{world}/raw/objects`
When reading commands from dfhack.init or with the `script` command, if the final
character on a line is a backslash then the next uncommented line is considered a
continuation of that line, with the backslash deleted. Commented lines are skipped,
so it is possible to comment out parts of a command with the ``#`` character.
For each of those directories, all matching init files will be executed in
alphabetical order.
Before running matched init scripts in any of those locations, the
:file:`dfhack-config/init/default.*` file that matches the event will be run to
load DFHack defaults. Only the :file:`dfhack-config/init` directory is checked
for this file, not any :file:`raw` directories. If you want DFHack to load
without running any of its default configuration commands, edit the
:file:`dfhack-config/init/default.*` files and comment out the commands you see
there.
.. _dfhack.init:
When reading commands from the init files or with the `script` command, if the
final character on a line is a backslash then the next uncommented line is
considered a continuation of that line, with the backslash deleted. Commented
lines are skipped, so it is possible to comment out parts of a command with the
``#`` character.
dfhack*.init
------------
If your DF folder contains at least one file named ``dfhack*.init``
(where ``*`` is a placeholder for any string), then all such files
are executed in alphabetical order when DF is first started.
DFHack is distributed with :download:`/dfhack.init-example` as an example
with an up-to-date collection of basic commands; mostly setting standard
keybindings and `enabling <enable>` plugins. You are encouraged to look
through this file to learn which features it makes available under which
key combinations. You may also customise it and rename it to ``dfhack.init``.
.. _dfhack.init:
If your DF folder does not contain any ``dfhack*.init`` files, the example
will be run as a fallback.
dfhack\*.init
.............
On startup, DFHack looks for files of the form ``dfhack*.init`` (where ``*`` is
a placeholder for any string, including the empty string).
These files are best used for keybindings and enabling persistent plugins
which do not require a world to be loaded.
@ -418,51 +430,49 @@ which do not require a world to be loaded.
.. _onLoad.init:
onLoad*.init
------------
onLoad\*.init
.............
When a world is loaded, DFHack looks for files of the form ``onLoad*.init``,
where ``*`` can be any string, including the empty string.
All matching init files will be executed in alphabetical order.
A world being loaded can mean a fortress, an adventurer, or legends mode.
These files are best used for non-persistent commands, such as setting
a `fix <scripts-fix>` script to run on `repeat`.
.. _onUnload.init:
.. _onMapLoad.init:
onUnload*.init
--------------
When a world is unloaded, DFHack looks for files of the form ``onUnload*.init``.
Again, these files may be in any of the above three places.
All matching init files will be executed in alphebetical order.
onMapLoad\*.init
................
When a map is loaded, either in adventure or fort mode, DFHack looks for files
of the form ``onMapLoad*.init``, where ``*`` can be any string, including the
empty string.
Modders often use such scripts to disable tools which should not affect
an unmodded save.
These files are best used for commands that are only relevant once there is a
game map loaded.
.. _other_init_files:
Other init files
----------------
.. _onMapUnload.init:
.. _onUnload.init:
* ``onMapLoad*.init`` and ``onMapUnload*.init`` are run when a map,
distinct from a world, is loaded. This is good for map-affecting
commands (e.g. `clean`), or avoiding issues in Legends mode.
onMapUnload\*.init and onUnload\*.init
......................................
When a map or world is unloaded, DFHack looks for files of the form
``onMapUnload*.init`` or ``onUnload*.init``, respectively.
* Any lua script named ``raw/init.d/*.lua``, in the save or main DF
directory, will be run when any world or that save is loaded.
Modders often use unload init scripts to disable tools which should not run
after a modded save is unloaded.
.. _dfhack-config:
.. _other_init_files:
Configuration Files
===================
raw/init.d/\*.lua
.................
Any lua script named ``raw/init.d/*.lua``, in the save or main DF directory,
will be run when any world or that save is loaded.
Some DFHack settings can be changed by modifying files in the ``dfhack-config``
folder (which is in the DF folder). The default versions of these files, if they
exist, are in ``dfhack-config/default`` and are installed when DFHack starts if
necessary.
.. _script-paths:

@ -41,7 +41,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
- ``job.removeJob()``: ensure jobs are removed from the world list when they are canceled
## Misc Improvements
- Init scripts: ``dfhack.init`` and other init scripts have moved to ``dfhack-config/init/``. If you have customized your ``dfhack.init`` file and want to keep your changes, please move the part that you have customized to the new location at ``dfhack-config/init/dfhack.init``. If you do not have changes that you want to keep, do not copy anything, and the new defaults will be used automatically.
- `manipulator`: add a library of useful default professions
- `manipulator`: move professions configuration from ``professions/`` to ``dfhack-config/professions/`` to keep it together with other dfhack configuration. If you have saved professions that you would like to keep, please manually move them to the new folder.
- ``materials.ItemTraitsDialog``: added a default ``on_select``-handler which toggles the traits.

@ -460,9 +460,6 @@ endif()
# install the offset file
install(FILES xml/symbols.xml
DESTINATION ${DFHACK_DATA_DESTINATION})
# install the example autoexec file
install(FILES ../dfhack.init-example
DESTINATION ${DFHACK_BINARY_DESTINATION})
install(TARGETS dfhack-run dfhack-client binpatch
LIBRARY DESTINATION ${DFHACK_LIBRARY_DESTINATION}

@ -1450,13 +1450,12 @@ static void run_dfhack_init(color_ostream &out, Core *core)
return;
}
// load baseline defaults
core->loadScriptFile(out, "dfhack-config/init/default.dfhack.init", false);
// load user overrides
std::vector<std::string> prefixes(1, "dfhack");
size_t count = loadScriptFiles(core, out, prefixes, ".");
if (!count || !Filesystem::isfile("dfhack.init"))
{
core->runCommand(out, "gui/no-dfhack-init");
core->loadScriptFile(out, "dfhack.init-example", false);
}
loadScriptFiles(core, out, prefixes, "dfhack-config/init");
}
// Load dfhack.init in a dedicated thread (non-interactive console mode)
@ -2226,7 +2225,11 @@ void Core::handleLoadAndUnloadScripts(color_ostream& out, state_change_event eve
auto i = table.find(event);
if ( i != table.end() ) {
const std::vector<std::string>& set = i->second;
loadScriptFiles(this, out, set, "." );
// load baseline defaults
this->loadScriptFile(out, "dfhack-config/init/default." + set[0] + ".init", false);
loadScriptFiles(this, out, set, "dfhack-config/init");
loadScriptFiles(this, out, set, rawFolder);
loadScriptFiles(this, out, set, rawFolder + "objects/");
}