summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/command.cc77
-rw-r--r--crawl-ref/source/database.cc33
-rw-r--r--crawl-ref/source/database.h7
-rw-r--r--crawl-ref/source/describe.cc2
-rw-r--r--crawl-ref/source/describe.h2
-rw-r--r--crawl-ref/source/libutil.h7
6 files changed, 123 insertions, 5 deletions
diff --git a/crawl-ref/source/command.cc b/crawl-ref/source/command.cc
index 8a234a49fc..26f55a4f0e 100644
--- a/crawl-ref/source/command.cc
+++ b/crawl-ref/source/command.cc
@@ -26,6 +26,8 @@
#include "abl-show.h"
#include "chardump.h"
#include "cio.h"
+#include "database.h"
+#include "describe.h"
#include "files.h"
#include "invent.h"
#include "itemname.h"
@@ -679,6 +681,65 @@ help_file help_files[] = {
{ NULL, 0, false }
};
+static void find_description()
+{
+ clrscr();
+ viewwindow(true, false);
+
+ mpr("Describe what? (can be a partial name or a regex) ");
+ char buf[80];
+ if (cancelable_get_line(buf, sizeof(buf)) || buf[0] == '\0')
+ {
+ canned_msg( MSG_OK);
+ return;
+ }
+
+ std::string regex = trimmed_string(buf);
+
+ if (regex == "")
+ {
+ mpr("Description must contain at least one non-space.");
+ return;
+ }
+
+ // Try to get an exact match first.
+ std::string key = regex;
+ std::string desc = getLongDescription(key);
+
+ if (desc == "")
+ {
+ std::vector<std::string> matches = getLongDescriptionByRegex(regex);
+
+ if (matches.size() == 0)
+ {
+ mprf("Nothing matches '%s'", buf);
+ return;
+ }
+ else if (matches.size() > 1)
+ {
+ std::string prefix = "No exact match for '" +
+ regex + "', possible matches are: ";
+
+ // Use mpr_comma_separated_list() because the list
+ // might be *LONG*.
+ mpr_comma_separated_list(prefix, matches, " and ", ", ",
+ MSGCH_PLAIN);
+ return;
+ }
+ else
+ {
+ // Only one match, use that.
+ key = matches[0];
+ desc = getLongDescription(key);
+ }
+ }
+ key = uppercase_first(key);
+ key += "$$";
+
+ clrscr();
+ print_description(key + desc);
+}
+
static int keyhelp_keyfilter(int ch)
{
switch (ch)
@@ -690,10 +751,19 @@ static int keyhelp_keyfilter(int ch)
display_notes();
return -1;
}
- // fall through
- default:
- return ch;
+ break;
+
+ case '/':
+ find_description();
+
+ if ( getch() == 0 )
+ getch();
+
+ viewwindow(true, false);
+
+ return -1;
}
+ return ch;
}
static void show_keyhelp_menu(const std::vector<formatted_string> &lines,
@@ -733,6 +803,7 @@ static void show_keyhelp_menu(const std::vector<formatted_string> &lines,
"<w>~</w>: Macros help\n"
"<w>!</w>: Options help\n"
"<w>%</w>: Table of aptitudes\n"
+ "<w>/</w>: Lookup description\n"
"<w>Home</w>: This screen\n",
true, true, cmdhelp_textfilter);
diff --git a/crawl-ref/source/database.cc b/crawl-ref/source/database.cc
index f8c97a354c..6de91c3a1e 100644
--- a/crawl-ref/source/database.cc
+++ b/crawl-ref/source/database.cc
@@ -152,6 +152,28 @@ datum database_fetch(DBM *database, const std::string &key)
return result;
}
+std::vector<std::string> database_find_keys(DBM *database,
+ const std::string &regex,
+ bool ignore_case)
+{
+ text_pattern tpat(regex, ignore_case);
+ std::vector<std::string> matches;
+
+ datum dbKey = dbm_firstkey(database);
+
+ while (dbKey.dptr != NULL)
+ {
+ std::string key((const char *)dbKey.dptr, dbKey.dsize);
+
+ if (tpat.matches(key))
+ matches.push_back(key);
+
+ dbKey = dbm_nextkey(database);
+ }
+
+ return (matches);
+}
+
///////////////////////////////////////////////////////////////////////////
// Internal DB utility functions
static void trim_right(std::string &s)
@@ -403,6 +425,17 @@ std::string getLongDescription(const std::string &key)
return std::string((const char *)result.dptr, result.dsize);
}
+std::vector<std::string> getLongDescriptionByRegex(const std::string &regex)
+{
+ if (!descriptionDB)
+ {
+ std::vector<std::string> empty;
+ return (empty);
+ }
+
+ return database_find_keys(descriptionDB, regex, true);
+}
+
static std::vector<std::string> description_txt_paths()
{
std::vector<std::string> txt_file_names;
diff --git a/crawl-ref/source/database.h b/crawl-ref/source/database.h
index e1cb3f230e..b30d8814e6 100644
--- a/crawl-ref/source/database.h
+++ b/crawl-ref/source/database.h
@@ -40,7 +40,12 @@ void databaseSystemShutdown();
DBM *openDB(const char *dbFilename);
datum database_fetch(DBM *database, const std::string &key);
-std::string getLongDescription(const std::string &key);
+std::vector<std::string> database_find_keys(DBM *database,
+ const std::string &regex,
+ bool ignore_case = false);
+
+std::string getLongDescription(const std::string &key);
+std::vector<std::string> getLongDescriptionByRegex(const std::string &regex);
std::string getShoutString(const std::string &monst,
const std::string &suffix = "");
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index 169a83af6f..8555459057 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -89,7 +89,7 @@ static void append_value( std::string & description, int valu, bool plussed )
// word and such. The character $ is interpreted as a CR.
//
//---------------------------------------------------------------
-static void print_description( const std::string &d )
+void print_description( const std::string &d )
{
std::string::size_type nextLine = std::string::npos;
unsigned int currentPos = 0;
diff --git a/crawl-ref/source/describe.h b/crawl-ref/source/describe.h
index af067e0415..875c86b8c0 100644
--- a/crawl-ref/source/describe.h
+++ b/crawl-ref/source/describe.h
@@ -72,6 +72,8 @@ void describe_spell(spell_type spelled);
* *********************************************************************** */
std::string ghost_description(const monsters &mons, bool concise = false);
+void print_description( const std::string &d );
+
const char *trap_name(trap_type trap);
int str_to_trap(const std::string &s);
diff --git a/crawl-ref/source/libutil.h b/crawl-ref/source/libutil.h
index 183f6fac2f..fc42023f70 100644
--- a/crawl-ref/source/libutil.h
+++ b/crawl-ref/source/libutil.h
@@ -102,6 +102,13 @@ inline std::string lowercase_first(std::string s)
return (s);
}
+inline std::string uppercase_first(std::string s)
+{
+ if (s.length())
+ s[0] = toupper(s[0]);
+ return (s);
+}
+
template <typename Z>
std::string comma_separated_line(Z start, Z end,
const std::string &andc = " and ",