8295800d611b301861e0b6e8597e856ae96abf78
chmalee
  Mon Nov 24 16:19:31 2025 -0800
successful HGVS searches get saved into the 'recent searches' dropdown on hgTracks. the position box tries to suggest hgvs when the search term is longer than 8 characters, otherwise we assume it's a gene, refs #35984

diff --git src/hg/hgSuggest/hgSuggest.c src/hg/hgSuggest/hgSuggest.c
index f6fe982b2ad..be184521e9b 100644
--- src/hg/hgSuggest/hgSuggest.c
+++ src/hg/hgSuggest/hgSuggest.c
@@ -8,30 +8,31 @@
 #include "hdb.h"
 #include "cheapcgi.h"
 #include "htmshell.h"
 #include "dystring.h"
 #include "jsonParse.h"
 #include "jsonWrite.h"
 #include "suggest.h"
 #include "genbank.h"
 #include "hgFind.h"
 #include "trix.h"
 
 // Optional CGI param type can specify what kind of thing to suggest (default: gene)
 #define ALT_OR_PATCH "altOrPatch"
 #define HELP_DOCS "helpDocs"
 #define TRACK "track"
+#define HGVS "hgvs"
 
 void suggestTrack(char *database,  char *prefix)
 {
 char query[4096];
 sqlSafef(query, sizeof query,
     "select tableName, shortLabel from trackDb where shortLabel like '%%%s%%'", prefix);
 struct sqlConnection *conn = hAllocConn(database);
 struct sqlResult *sr = sqlGetResult(conn, query);
 char **row;
 struct jsonWrite *jw = jsonWriteNew();
 jsonWriteListStart(jw, NULL);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     jsonWriteObjectStart(jw, NULL);
     jsonWriteString(jw, "label", row[1]);
@@ -262,43 +263,69 @@
 struct trix *helpTrix = openStaticTrix(helpDocsTrix);
 struct trixSearchResult *tsr, *tsrList = trixSearch(helpTrix, keyCount, keyWords, tsmExpand);
 int i;
 for (i = 0, tsr = tsrList; i < 25 && tsr != NULL; i++, tsr = tsr->next)
     {
     jsonWriteObjectStart(jw, NULL);
     jsonWriteString(jw, "value", tsr->itemId); // value is necessary
     jsonWriteString(jw, "category", "helpDocs"); // hardcode this for client
     jsonWriteObjectEnd(jw);
     }
 jsonWriteListEnd(jw);
 puts(jw->dy->string);
 jsonWriteFree(&jw);
 }
 
+void suggestHGVS(char *database, char *prefix)
+/* Print out a list of javascript objects that define positions matching the HGVS term prefix */
+{
+struct hgPositions *hgp = NULL;
+AllocVar(hgp);
+boolean match = matchesHgvs(NULL, database, prefix, hgp, FALSE);
+if (match)
+    {
+fprintf(stderr, "suggesting hgvs for db: '%s' and prefix '%s'\n", database, prefix);
+    fixSinglePos(hgp);
+    struct jsonWrite *jw = jsonWriteNew();
+    jsonWriteListStart(jw,NULL);
+    jsonWriteObjectStart(jw, NULL);
+    jsonWriteString(jw, "type", HGVS);
+    jsonWriteString(jw, "value", hgp->singlePos->description);
+    jsonWriteString(jw, "id", hgp->singlePos->description);
+    jsonWriteString(jw, "chrom", hgp->singlePos->chrom);
+    jsonWriteNumber(jw, "start", hgp->singlePos->chromStart);
+    jsonWriteNumber(jw, "end", hgp->singlePos->chromEnd);
+    jsonWriteObjectEnd(jw);
+    jsonWriteListEnd(jw);
+    puts(jw->dy->string);
+    jsonWriteFree(&jw);
+    }
+}
+
 char *checkParams(char *database, char *prefix, char *type)
 /* If we don't have valid CGI parameters, quit with a Bad Request HTTP response. */
 {
 pushWarnHandler(htmlVaBadRequestAbort);
 pushAbortHandler(htmlVaBadRequestAbort);
 if(prefix == NULL || database == NULL)
     errAbort("%s", "Missing prefix and/or db CGI parameter");
 if (! hDbIsActive(database))
     errAbort("'%s' is not a valid, active database", htmlEncode(database));
-if (isNotEmpty(type) && differentString(type, ALT_OR_PATCH) && differentString(type, HELP_DOCS) && differentString(type, TRACK))
+if (isNotEmpty(type) && differentString(type, ALT_OR_PATCH) && differentString(type, HELP_DOCS) && differentString(type, TRACK) && differentString(type, HGVS))
     errAbort("'%s' is not a valid type", type);
 char *table = NULL;
-if (! sameOk(type, ALT_OR_PATCH) && !sameOk(type, HELP_DOCS))
+if (! sameOk(type, ALT_OR_PATCH) && !sameOk(type, HELP_DOCS) && !sameOk(type, HGVS))
     {
     char *knownDatabase = hdbDefaultKnownDb(database);
     struct sqlConnection *conn = hAllocConn(knownDatabase);
     table = connGeneSuggestTable(conn);
     hFreeConn(&conn);
     if(table == NULL)
         errAbort("gene autosuggest is not supported for db '%s'", database);
     }
 popWarnHandler();
 popAbortHandler();
 return table;
 }
 
 int main(int argc, char *argv[])
 {
@@ -307,21 +334,23 @@
 cgiSpoof(&argc, argv);
 char *database = cgiOptionalString("db");
 char *prefix = cgiOptionalString("prefix");
 char *type = cgiOptionalString("type");
 char *table = checkParams(database, prefix, type);
 
 puts("Content-Type:text/plain");
 puts("\n");
 
 if (sameOk(type, ALT_OR_PATCH))
     suggestAltOrPatch(database, prefix);
 else if (sameOk(type, HELP_DOCS))
     suggestHelpPage(prefix);
 else if (sameOk(type, TRACK))
     suggestTrack(database, prefix);
+else if (sameOk(type, HGVS))
+    suggestHGVS(database, prefix);
 else
     suggestGene(database, table, prefix);
 
 cgiExitTime("hgSuggest", enteredMainTime);
 return 0;
 }