|
|
@ -32,58 +32,75 @@ local ENTRY_TYPES = {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
local HELP_SOURCES = {
|
|
|
|
local HELP_SOURCES = {
|
|
|
|
STUB='stub',
|
|
|
|
RENDERED='rendered', -- from the installed, rendered help text
|
|
|
|
RENDERED='rendered',
|
|
|
|
PLUGIN='plugin', -- from the plugin source code
|
|
|
|
PLUGIN='plugin',
|
|
|
|
SCRIPT='script', -- from the script source code
|
|
|
|
SCRIPT='script',
|
|
|
|
STUB='stub', -- from a generated stub
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
-- builtins
|
|
|
|
-- builtin command names, with aliases mapped to their canonical form
|
|
|
|
local BUILTINS = {
|
|
|
|
local BUILTINS = {
|
|
|
|
'alias',
|
|
|
|
alias=true,
|
|
|
|
'clear',
|
|
|
|
clear='cls',
|
|
|
|
'cls',
|
|
|
|
cls=true,
|
|
|
|
'devel/dump-rpc',
|
|
|
|
['devel/dump-rpc']=true,
|
|
|
|
'die',
|
|
|
|
die=true,
|
|
|
|
'dir',
|
|
|
|
dir='ls',
|
|
|
|
'disable',
|
|
|
|
disable=true,
|
|
|
|
'enable',
|
|
|
|
enable=true,
|
|
|
|
'fpause',
|
|
|
|
fpause=true,
|
|
|
|
'help',
|
|
|
|
help=true,
|
|
|
|
'hide',
|
|
|
|
hide=true,
|
|
|
|
'keybinding',
|
|
|
|
keybinding=true,
|
|
|
|
'kill-lua',
|
|
|
|
['kill-lua']=true,
|
|
|
|
'load',
|
|
|
|
['load']=true,
|
|
|
|
'ls',
|
|
|
|
ls=true,
|
|
|
|
'man',
|
|
|
|
man='help',
|
|
|
|
'plug',
|
|
|
|
plug=true,
|
|
|
|
'reload',
|
|
|
|
reload=true,
|
|
|
|
'script',
|
|
|
|
script=true,
|
|
|
|
'sc-script',
|
|
|
|
['sc-script']=true,
|
|
|
|
'show',
|
|
|
|
show=true,
|
|
|
|
'tags',
|
|
|
|
tags=true,
|
|
|
|
'type',
|
|
|
|
['type']=true,
|
|
|
|
'unload',
|
|
|
|
unload=true,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
-- data structures
|
|
|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- help text database, keys are a subset of the entry database
|
|
|
|
-- entry name -> {
|
|
|
|
-- entry name -> {
|
|
|
|
-- entry_types (set of ENTRY_TYPES),
|
|
|
|
-- help_source (element of HELP_SOURCES),
|
|
|
|
-- short_help (string),
|
|
|
|
-- short_help (string),
|
|
|
|
-- long_help (string),
|
|
|
|
-- long_help (string),
|
|
|
|
-- tags (set),
|
|
|
|
-- tags (set),
|
|
|
|
-- help_source (element of HELP_SOURCES),
|
|
|
|
|
|
|
|
-- source_timestamp (mtime, 0 for non-files),
|
|
|
|
-- source_timestamp (mtime, 0 for non-files),
|
|
|
|
-- source_path (string, nil for non-files)
|
|
|
|
-- source_path (string, nil for non-files)
|
|
|
|
-- }
|
|
|
|
-- }
|
|
|
|
|
|
|
|
textdb = textdb or {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- entry database, points to text in textdb
|
|
|
|
|
|
|
|
-- entry name -> {
|
|
|
|
|
|
|
|
-- entry_types (set of ENTRY_TYPES),
|
|
|
|
|
|
|
|
-- short_help (string, if not nil then overrides short_help in text_entry),
|
|
|
|
|
|
|
|
-- text_entry (string)
|
|
|
|
|
|
|
|
-- }
|
|
|
|
--
|
|
|
|
--
|
|
|
|
-- entry_types is a set because plugin commands can also be the plugin names.
|
|
|
|
-- entry_types is a set because plugin commands can also be the plugin names.
|
|
|
|
db = db or {}
|
|
|
|
entrydb = entrydb or {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- tag name -> list of entry names
|
|
|
|
-- tag name -> list of entry names
|
|
|
|
-- Tags defined in the TAG_DEFINITIONS file that have no associated db entries
|
|
|
|
-- Tags defined in the TAG_DEFINITIONS file that have no associated db entries
|
|
|
|
-- will have an empty list.
|
|
|
|
-- will have an empty list.
|
|
|
|
tag_index = tag_index or {}
|
|
|
|
tag_index = tag_index or {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
-- data ingestion
|
|
|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
local function get_rendered_path(entry_name)
|
|
|
|
local function get_rendered_path(entry_name)
|
|
|
|
return RENDERED_PATH .. entry_name .. '.txt'
|
|
|
|
return RENDERED_PATH .. entry_name .. '.txt'
|
|
|
|
end
|
|
|
|
end
|
|
|
@ -98,18 +115,16 @@ local DEFAULT_HELP_TEMPLATE = [[
|
|
|
|
|
|
|
|
|
|
|
|
No help available.
|
|
|
|
No help available.
|
|
|
|
]]
|
|
|
|
]]
|
|
|
|
local function make_default_entry(entry_name, entry_types, source,
|
|
|
|
local function make_default_entry(entry_name, help_source, kwargs)
|
|
|
|
source_timestamp, source_path)
|
|
|
|
|
|
|
|
local default_long_help = DEFAULT_HELP_TEMPLATE:format(
|
|
|
|
local default_long_help = DEFAULT_HELP_TEMPLATE:format(
|
|
|
|
entry_name, ('*'):rep(#entry_name))
|
|
|
|
entry_name, ('*'):rep(#entry_name))
|
|
|
|
return {
|
|
|
|
return {
|
|
|
|
entry_types=entry_types,
|
|
|
|
help_source=help_source,
|
|
|
|
short_help='No help available.',
|
|
|
|
short_help='No help available.',
|
|
|
|
long_help=default_long_help,
|
|
|
|
long_help=default_long_help,
|
|
|
|
tags={},
|
|
|
|
tags={},
|
|
|
|
help_source=source,
|
|
|
|
source_timestamp=kwargs.source_timestamp or 0,
|
|
|
|
source_timestamp=source_timestamp or 0,
|
|
|
|
source_path=kwargs.source_path}
|
|
|
|
source_path=source_path}
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-- updates the short_text, the long_text, and the tags in the given entry based
|
|
|
|
-- updates the short_text, the long_text, and the tags in the given entry based
|
|
|
@ -129,7 +144,8 @@ local function update_entry(entry, iterator, opts)
|
|
|
|
local lines = {}
|
|
|
|
local lines = {}
|
|
|
|
local first_line_is_short_help = opts.first_line_is_short_help
|
|
|
|
local first_line_is_short_help = opts.first_line_is_short_help
|
|
|
|
local begin_marker_found,header_found = not opts.begin_marker,opts.no_header
|
|
|
|
local begin_marker_found,header_found = not opts.begin_marker,opts.no_header
|
|
|
|
local tags_found, short_help_found, in_short_help = false, false, false
|
|
|
|
local tags_found, short_help_found = false, opts.skip_short_help
|
|
|
|
|
|
|
|
local in_short_help = false
|
|
|
|
for line in iterator do
|
|
|
|
for line in iterator do
|
|
|
|
if not short_help_found and first_line_is_short_help then
|
|
|
|
if not short_help_found and first_line_is_short_help then
|
|
|
|
line = line:trim()
|
|
|
|
line = line:trim()
|
|
|
@ -193,31 +209,30 @@ local function update_entry(entry, iterator, opts)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-- create db entry based on parsing sphinx-rendered help text
|
|
|
|
-- create db entry based on parsing sphinx-rendered help text
|
|
|
|
local function make_rendered_entry(old_entry, entry_name, entry_types)
|
|
|
|
local function make_rendered_entry(old_entry, entry_name, kwargs)
|
|
|
|
local rendered_path = get_rendered_path(entry_name)
|
|
|
|
local source_path = get_rendered_path(entry_name)
|
|
|
|
local source_timestamp = dfhack.filesystem.mtime(rendered_path)
|
|
|
|
local source_timestamp = dfhack.filesystem.mtime(source_path)
|
|
|
|
if old_entry and old_entry.source == HELP_SOURCES.RENDERED and
|
|
|
|
if old_entry and old_entry.help_source == HELP_SOURCES.RENDERED and
|
|
|
|
old_entry.source_timestamp >= source_timestamp then
|
|
|
|
old_entry.source_timestamp >= source_timestamp then
|
|
|
|
-- we already have the latest info
|
|
|
|
-- we already have the latest info
|
|
|
|
return old_entry
|
|
|
|
return old_entry
|
|
|
|
end
|
|
|
|
end
|
|
|
|
local entry = make_default_entry(entry_name, entry_types,
|
|
|
|
kwargs.source_path, kwargs.source_timestamp = source_path, source_timestamp
|
|
|
|
HELP_SOURCES.RENDERED, source_timestamp, rendered_path)
|
|
|
|
local entry = make_default_entry(entry_name, HELP_SOURCES.RENDERED, kwargs)
|
|
|
|
update_entry(entry, io.lines(rendered_path))
|
|
|
|
update_entry(entry, io.lines(source_path))
|
|
|
|
return entry
|
|
|
|
return entry
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-- create db entry based on the help text in the plugin source (used by
|
|
|
|
-- create db entry based on the help text in the plugin source (used by
|
|
|
|
-- out-of-tree plugins)
|
|
|
|
-- out-of-tree plugins)
|
|
|
|
local function make_plugin_entry(old_entry, entry_name, entry_types)
|
|
|
|
local function make_plugin_entry(old_entry, entry_name, kwargs)
|
|
|
|
if old_entry and old_entry.source == HELP_SOURCES.PLUGIN then
|
|
|
|
if old_entry and old_entry.source == HELP_SOURCES.PLUGIN then
|
|
|
|
-- we can't tell when a plugin is reloaded, so we can either choose to
|
|
|
|
-- we can't tell when a plugin is reloaded, so we can either choose to
|
|
|
|
-- always refresh or never refresh. let's go with never for now for
|
|
|
|
-- always refresh or never refresh. let's go with never for now for
|
|
|
|
-- performance.
|
|
|
|
-- performance.
|
|
|
|
return old_entry
|
|
|
|
return old_entry
|
|
|
|
end
|
|
|
|
end
|
|
|
|
local entry = make_default_entry(entry_name, entry_types,
|
|
|
|
local entry = make_default_entry(entry_name, HELP_SOURCES.PLUGIN, kwargs)
|
|
|
|
HELP_SOURCES.PLUGIN)
|
|
|
|
|
|
|
|
local long_help = dfhack.internal.getCommandHelp(entry_name)
|
|
|
|
local long_help = dfhack.internal.getCommandHelp(entry_name)
|
|
|
|
if long_help and #long_help:trim() > 0 then
|
|
|
|
if long_help and #long_help:trim() > 0 then
|
|
|
|
update_entry(entry, long_help:trim():gmatch('[^\n]*'), {no_header=true})
|
|
|
|
update_entry(entry, long_help:trim():gmatch('[^\n]*'), {no_header=true})
|
|
|
@ -227,19 +242,22 @@ end
|
|
|
|
|
|
|
|
|
|
|
|
-- create db entry based on the help text in the script source (used by
|
|
|
|
-- create db entry based on the help text in the script source (used by
|
|
|
|
-- out-of-tree scripts)
|
|
|
|
-- out-of-tree scripts)
|
|
|
|
local function make_script_entry(old_entry, entry_name, script_source_path)
|
|
|
|
local function make_script_entry(old_entry, entry_name, kwargs)
|
|
|
|
local source_timestamp = dfhack.filesystem.mtime(script_source_path)
|
|
|
|
local source_path = kwargs.source_path
|
|
|
|
|
|
|
|
local source_timestamp = dfhack.filesystem.mtime(source_path)
|
|
|
|
if old_entry and old_entry.source == HELP_SOURCES.SCRIPT and
|
|
|
|
if old_entry and old_entry.source == HELP_SOURCES.SCRIPT and
|
|
|
|
old_entry.script_source_path == script_source_path and
|
|
|
|
old_entry.source_path == source_path and
|
|
|
|
old_entry.source_timestamp >= source_timestamp then
|
|
|
|
old_entry.source_timestamp >= source_timestamp then
|
|
|
|
-- we already have the latest info
|
|
|
|
-- we already have the latest info
|
|
|
|
return old_entry
|
|
|
|
return old_entry
|
|
|
|
end
|
|
|
|
end
|
|
|
|
local entry = make_default_entry(entry_name, {[ENTRY_TYPES.COMMAND]=true},
|
|
|
|
kwargs.source_timestamp, kwargs.entry_type = source_timestamp
|
|
|
|
HELP_SOURCES.SCRIPT, source_timestamp, script_source_path)
|
|
|
|
local entry = make_default_entry(entry_name, HELP_SOURCES.SCRIPT, kwargs)
|
|
|
|
local ok, lines = pcall(io.lines, script_source_path)
|
|
|
|
local ok, lines = pcall(io.lines, source_path)
|
|
|
|
if not ok then return entry end
|
|
|
|
if not ok then
|
|
|
|
local is_rb = script_source_path:endswith('.rb')
|
|
|
|
return entry
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
local is_rb = source_path:endswith('.rb')
|
|
|
|
update_entry(entry, lines,
|
|
|
|
update_entry(entry, lines,
|
|
|
|
{begin_marker=(is_rb and SCRIPT_DOC_BEGIN_RUBY or SCRIPT_DOC_BEGIN),
|
|
|
|
{begin_marker=(is_rb and SCRIPT_DOC_BEGIN_RUBY or SCRIPT_DOC_BEGIN),
|
|
|
|
end_marker=(is_rb and SCRIPT_DOC_BEGIN_RUBY or SCRIPT_DOC_END),
|
|
|
|
end_marker=(is_rb and SCRIPT_DOC_BEGIN_RUBY or SCRIPT_DOC_END),
|
|
|
@ -247,78 +265,81 @@ local function make_script_entry(old_entry, entry_name, script_source_path)
|
|
|
|
return entry
|
|
|
|
return entry
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-- updates the db (and associated tag index) with a new entry if the entry_name
|
|
|
|
-- updates the dbs (and associated tag index) with a new entry if the entry_name
|
|
|
|
-- doesn't already exist in the db.
|
|
|
|
-- doesn't already exist in the dbs.
|
|
|
|
local function update_db(old_db, db, source, entry_name, kwargs)
|
|
|
|
local function update_db(old_db, entry_name, text_entry, help_source, kwargs)
|
|
|
|
if db[entry_name] then
|
|
|
|
if entrydb[entry_name] then
|
|
|
|
-- already in db (e.g. from a higher-priority script dir); skip
|
|
|
|
-- already in db (e.g. from a higher-priority script dir); skip
|
|
|
|
return
|
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
|
|
|
local entry, old_entry = nil, old_db[entry_name]
|
|
|
|
entrydb[entry_name] = {
|
|
|
|
if source == HELP_SOURCES.RENDERED then
|
|
|
|
entry_types=kwargs.entry_types,
|
|
|
|
entry = make_rendered_entry(old_entry, entry_name, kwargs.entry_types)
|
|
|
|
short_help=kwargs.short_help,
|
|
|
|
elseif source == HELP_SOURCES.PLUGIN then
|
|
|
|
text_entry=text_entry
|
|
|
|
entry = make_plugin_entry(old_entry, entry_name, kwargs.entry_types)
|
|
|
|
}
|
|
|
|
elseif source == HELP_SOURCES.SCRIPT then
|
|
|
|
if entry_name ~= text_entry then
|
|
|
|
entry = make_script_entry(old_entry, entry_name, kwargs.script_source)
|
|
|
|
return
|
|
|
|
elseif source == HELP_SOURCES.STUB then
|
|
|
|
|
|
|
|
entry = make_default_entry(entry_name, kwargs.entry_types,
|
|
|
|
|
|
|
|
HELP_SOURCES.STUB)
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
error('unhandled help source: ' .. source)
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
db[entry_name] = entry
|
|
|
|
|
|
|
|
for tag in pairs(entry.tags) do
|
|
|
|
local text_entry, old_entry = nil, old_db[entry_name]
|
|
|
|
-- ignore unknown tags
|
|
|
|
if help_source == HELP_SOURCES.RENDERED then
|
|
|
|
if tag_index[tag] then
|
|
|
|
text_entry = make_rendered_entry(old_entry, entry_name, kwargs)
|
|
|
|
table.insert(tag_index[tag], entry_name)
|
|
|
|
elseif help_source == HELP_SOURCES.PLUGIN then
|
|
|
|
end
|
|
|
|
text_entry = make_plugin_entry(old_entry, entry_name, kwargs)
|
|
|
|
|
|
|
|
elseif help_source == HELP_SOURCES.SCRIPT then
|
|
|
|
|
|
|
|
text_entry = make_script_entry(old_entry, entry_name, kwargs)
|
|
|
|
|
|
|
|
elseif help_source == HELP_SOURCES.STUB then
|
|
|
|
|
|
|
|
text_entry = make_default_entry(entry_name, HELP_SOURCES.STUB, kwargs)
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
error('unhandled help source: ' .. help_source)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
textdb[entry_name] = text_entry
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-- add the builtin commands to the db
|
|
|
|
-- add the builtin commands to the db
|
|
|
|
local function scan_builtins(old_db, db)
|
|
|
|
local function scan_builtins(old_db)
|
|
|
|
local entry_types = {[ENTRY_TYPES.BUILTIN]=true, [ENTRY_TYPES.COMMAND]=true}
|
|
|
|
local entry_types = {[ENTRY_TYPES.BUILTIN]=true, [ENTRY_TYPES.COMMAND]=true}
|
|
|
|
for _,builtin in ipairs(BUILTINS) do
|
|
|
|
for builtin,canonical in pairs(BUILTINS) do
|
|
|
|
update_db(old_db, db,
|
|
|
|
if canonical == true then canonical = builtin end
|
|
|
|
has_rendered_help(builtin) and
|
|
|
|
update_db(old_db, builtin, canonical,
|
|
|
|
HELP_SOURCES.RENDERED or HELP_SOURCES.STUB,
|
|
|
|
has_rendered_help(canonical) and
|
|
|
|
builtin,
|
|
|
|
HELP_SOURCES.RENDERED or HELP_SOURCES.STUB,
|
|
|
|
{entry_types=entry_types})
|
|
|
|
{entry_types=entry_types})
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-- scan for plugins and plugin-provided commands and add their help to the db
|
|
|
|
-- scan for enableable plugins and plugin-provided commands and add their help
|
|
|
|
local function scan_plugins(old_db, db)
|
|
|
|
-- to the db
|
|
|
|
|
|
|
|
local function scan_plugins(old_db)
|
|
|
|
local plugin_names = dfhack.internal.listPlugins()
|
|
|
|
local plugin_names = dfhack.internal.listPlugins()
|
|
|
|
for _,plugin in ipairs(plugin_names) do
|
|
|
|
for _,plugin in ipairs(plugin_names) do
|
|
|
|
local commands = dfhack.internal.listCommands(plugin)
|
|
|
|
local commands = dfhack.internal.listCommands(plugin)
|
|
|
|
local includes_plugin = false
|
|
|
|
local includes_plugin, has_commands = false, false
|
|
|
|
for _,command in ipairs(commands) do
|
|
|
|
for _,command in ipairs(commands) do
|
|
|
|
local entry_types = {[ENTRY_TYPES.COMMAND]=true}
|
|
|
|
local kwargs = {entry_types={[ENTRY_TYPES.COMMAND]=true}}
|
|
|
|
if command == plugin then
|
|
|
|
if command == plugin then
|
|
|
|
entry_types[ENTRY_TYPES.PLUGIN]=true
|
|
|
|
kwargs.entry_types[ENTRY_TYPES.PLUGIN]=true
|
|
|
|
includes_plugin = true
|
|
|
|
includes_plugin = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
update_db(old_db, db,
|
|
|
|
kwargs.short_help = dfhack.internal.getCommandDescription(command)
|
|
|
|
has_rendered_help(command) and
|
|
|
|
update_db(old_db, command, plugin,
|
|
|
|
|
|
|
|
has_rendered_help(plugin) and
|
|
|
|
HELP_SOURCES.RENDERED or HELP_SOURCES.PLUGIN,
|
|
|
|
HELP_SOURCES.RENDERED or HELP_SOURCES.PLUGIN,
|
|
|
|
command, {entry_types=entry_types})
|
|
|
|
kwargs)
|
|
|
|
|
|
|
|
has_commands = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if not includes_plugin and
|
|
|
|
if not includes_plugin and (has_commands or
|
|
|
|
dfhack.internal.isPluginEnableable(plugin) then
|
|
|
|
dfhack.internal.isPluginEnableable(plugin)) then
|
|
|
|
update_db(old_db, db,
|
|
|
|
update_db(old_db, plugin, plugin,
|
|
|
|
has_rendered_help(plugin) and
|
|
|
|
has_rendered_help(plugin) and
|
|
|
|
HELP_SOURCES.RENDERED or HELP_SOURCES.STUB,
|
|
|
|
HELP_SOURCES.RENDERED or HELP_SOURCES.STUB,
|
|
|
|
plugin, {entry_types={[ENTRY_TYPES.PLUGIN]=true}})
|
|
|
|
{entry_types={[ENTRY_TYPES.PLUGIN]=true}})
|
|
|
|
goto continue
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
::continue::
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-- scan for scripts and add their help to the db
|
|
|
|
-- scan for scripts and add their help to the db
|
|
|
|
local function scan_scripts(old_db, db)
|
|
|
|
local function scan_scripts(old_db)
|
|
|
|
local entry_types = {[ENTRY_TYPES.COMMAND]=true}
|
|
|
|
local entry_types = {[ENTRY_TYPES.COMMAND]=true}
|
|
|
|
for _,script_path in ipairs(dfhack.internal.getScriptPaths()) do
|
|
|
|
for _,script_path in ipairs(dfhack.internal.getScriptPaths()) do
|
|
|
|
local files = dfhack.filesystem.listdir_recursive(
|
|
|
|
local files = dfhack.filesystem.listdir_recursive(
|
|
|
@ -333,12 +354,11 @@ local function scan_scripts(old_db, db)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
local dot_index = f.path:find('%.[^.]*$')
|
|
|
|
local dot_index = f.path:find('%.[^.]*$')
|
|
|
|
local entry_name = f.path:sub(1, dot_index - 1)
|
|
|
|
local entry_name = f.path:sub(1, dot_index - 1)
|
|
|
|
local script_source = script_path .. '/' .. f.path
|
|
|
|
local source_path = script_path .. '/' .. f.path
|
|
|
|
update_db(old_db, db,
|
|
|
|
update_db(old_db, entry_name, entry_name,
|
|
|
|
has_rendered_help(entry_name) and
|
|
|
|
has_rendered_help(entry_name) and
|
|
|
|
HELP_SOURCES.RENDERED or HELP_SOURCES.SCRIPT,
|
|
|
|
HELP_SOURCES.RENDERED or HELP_SOURCES.SCRIPT,
|
|
|
|
entry_name,
|
|
|
|
{entry_types=entry_types, source_path=source_path})
|
|
|
|
{entry_types=entry_types, script_source=script_source})
|
|
|
|
|
|
|
|
::continue::
|
|
|
|
::continue::
|
|
|
|
end
|
|
|
|
end
|
|
|
|
::skip_path::
|
|
|
|
::skip_path::
|
|
|
@ -370,6 +390,17 @@ local function initialize_tags()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function index_tags()
|
|
|
|
|
|
|
|
for entry_name,entry in pairs(entrydb) do
|
|
|
|
|
|
|
|
for tag in pairs(textdb[entry.text_entry].tags) do
|
|
|
|
|
|
|
|
-- ignore unknown tags
|
|
|
|
|
|
|
|
if tag_index[tag] then
|
|
|
|
|
|
|
|
table.insert(tag_index[tag], entry_name)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-- ensures the db is up to date by scanning all help sources. does not do
|
|
|
|
-- ensures the db is up to date by scanning all help sources. does not do
|
|
|
|
-- anything if it has already been run within the last 60 seconds.
|
|
|
|
-- anything if it has already been run within the last 60 seconds.
|
|
|
|
last_refresh_ms = last_refresh_ms or 0
|
|
|
|
last_refresh_ms = last_refresh_ms or 0
|
|
|
@ -378,13 +409,14 @@ local function ensure_db()
|
|
|
|
if now_ms - last_refresh_ms < 60000 then return end
|
|
|
|
if now_ms - last_refresh_ms < 60000 then return end
|
|
|
|
last_refresh_ms = now_ms
|
|
|
|
last_refresh_ms = now_ms
|
|
|
|
|
|
|
|
|
|
|
|
local old_db = db
|
|
|
|
local old_db = textdb
|
|
|
|
db, tag_index = {}, {}
|
|
|
|
textdb, entrydb, tag_index = {}, {}, {}
|
|
|
|
|
|
|
|
|
|
|
|
initialize_tags()
|
|
|
|
initialize_tags()
|
|
|
|
scan_builtins(old_db, db)
|
|
|
|
scan_builtins(old_db)
|
|
|
|
scan_plugins(old_db, db)
|
|
|
|
scan_plugins(old_db)
|
|
|
|
scan_scripts(old_db, db)
|
|
|
|
scan_scripts(old_db)
|
|
|
|
|
|
|
|
index_tags()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
---------------------------------------------------------------------------
|
|
|
@ -415,15 +447,16 @@ end
|
|
|
|
|
|
|
|
|
|
|
|
-- returns whether the given string (or list of strings) is an entry in the db
|
|
|
|
-- returns whether the given string (or list of strings) is an entry in the db
|
|
|
|
function is_entry(str)
|
|
|
|
function is_entry(str)
|
|
|
|
return has_keys(str, db)
|
|
|
|
return has_keys(str, entrydb)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local function get_db_property(entry_name, property)
|
|
|
|
local function get_db_property(entry_name, property)
|
|
|
|
ensure_db()
|
|
|
|
ensure_db()
|
|
|
|
if not db[entry_name] then
|
|
|
|
if not entrydb[entry_name] then
|
|
|
|
error(('helpdb entry not found: "%s"'):format(entry_name))
|
|
|
|
error(('helpdb entry not found: "%s"'):format(entry_name))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return db[entry_name][property]
|
|
|
|
return entrydb[entry_name][property] or
|
|
|
|
|
|
|
|
textdb[entrydb[entry_name].text_entry][property]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-- returns the ~54 char summary blurb associated with the entry
|
|
|
|
-- returns the ~54 char summary blurb associated with the entry
|
|
|
@ -504,11 +537,11 @@ local function sort_by_basename(a, b)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
local function matches(entry_name, filter)
|
|
|
|
local function matches(entry_name, filter)
|
|
|
|
local db_entry = db[entry_name]
|
|
|
|
|
|
|
|
if filter.tag then
|
|
|
|
if filter.tag then
|
|
|
|
local matched = false
|
|
|
|
local matched = false
|
|
|
|
|
|
|
|
local tags = get_db_property(entry_name, 'tags')
|
|
|
|
for _,tag in ipairs(filter.tag) do
|
|
|
|
for _,tag in ipairs(filter.tag) do
|
|
|
|
if db_entry.tags[tag] then
|
|
|
|
if tags[tag] then
|
|
|
|
matched = true
|
|
|
|
matched = true
|
|
|
|
break
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
@ -519,8 +552,9 @@ local function matches(entry_name, filter)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if filter.types then
|
|
|
|
if filter.types then
|
|
|
|
local matched = false
|
|
|
|
local matched = false
|
|
|
|
|
|
|
|
local etypes = get_db_property(entry_name, 'entry_types')
|
|
|
|
for _,etype in ipairs(filter.types) do
|
|
|
|
for _,etype in ipairs(filter.types) do
|
|
|
|
if db_entry.entry_types[etype] then
|
|
|
|
if etypes[etype] then
|
|
|
|
matched = true
|
|
|
|
matched = true
|
|
|
|
break
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
@ -577,7 +611,7 @@ function search_entries(include, exclude)
|
|
|
|
include = normalize_filter(include)
|
|
|
|
include = normalize_filter(include)
|
|
|
|
exclude = normalize_filter(exclude)
|
|
|
|
exclude = normalize_filter(exclude)
|
|
|
|
local entries = {}
|
|
|
|
local entries = {}
|
|
|
|
for entry in pairs(db) do
|
|
|
|
for entry in pairs(entrydb) do
|
|
|
|
if (not include or matches(entry, include)) and
|
|
|
|
if (not include or matches(entry, include)) and
|
|
|
|
(not exclude or not matches(entry, exclude)) then
|
|
|
|
(not exclude or not matches(entry, exclude)) then
|
|
|
|
table.insert(entries, entry)
|
|
|
|
table.insert(entries, entry)
|
|
|
@ -595,7 +629,8 @@ end
|
|
|
|
|
|
|
|
|
|
|
|
function is_builtin(command)
|
|
|
|
function is_builtin(command)
|
|
|
|
ensure_db()
|
|
|
|
ensure_db()
|
|
|
|
return db[command] and db[command].entry_types[ENTRY_TYPES.BUILTIN]
|
|
|
|
return entrydb[command] and
|
|
|
|
|
|
|
|
get_db_property(entry_name, 'entry_types')[ENTRY_TYPES.BUILTIN]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
---------------------------------------------------------------------------
|
|
|
|
---------------------------------------------------------------------------
|
|
|
@ -605,7 +640,7 @@ end
|
|
|
|
-- implements the 'help' builtin command
|
|
|
|
-- implements the 'help' builtin command
|
|
|
|
function help(entry)
|
|
|
|
function help(entry)
|
|
|
|
ensure_db()
|
|
|
|
ensure_db()
|
|
|
|
if not db[entry] then
|
|
|
|
if not entrydb[entry] then
|
|
|
|
dfhack.printerr(('No help entry found for "%s"'):format(entry))
|
|
|
|
dfhack.printerr(('No help entry found for "%s"'):format(entry))
|
|
|
|
return
|
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
|
|
|