-
${label || getDocLabel(doc)}
+
${getDocLabel(doc)}
+ ${doc.synonyms_text ? `
Synonyms: ${doc.synonyms_text}
` : ''}
${doc.description ? `
${doc.description}
` : ''}
${buildParamsList(doc.params)}
${buildExamples(doc.examples)}
@@ -74,19 +75,36 @@ const isValidDoc = (doc) => {
const hasExcludedTags = (doc) =>
['superdirtOnly', 'noAutocomplete'].some((tag) => doc.tags?.find((t) => t.originalTitle === tag));
+export const getSynonymDoc = (doc, synonym) => {
+ const synonyms = doc.synonyms || [];
+ const docLabel = getDocLabel(doc);
+ // Swap `doc.name` in for `s` in the list of synonyms
+ const synonymsWithDoc = [docLabel, ...synonyms].filter((x) => x && x !== synonym);
+ return {
+ ...doc,
+ name: synonym,
+ longname: synonym,
+ synonyms: synonymsWithDoc,
+ synonyms_text: synonymsWithDoc.join(', '),
+ };
+};
+
const jsdocCompletions = (() => {
const seen = new Set(); // avoid repetition
const completions = [];
for (const doc of jsdoc.docs) {
if (!isValidDoc(doc) || hasExcludedTags(doc)) continue;
- let labels = [getDocLabel(doc), ...(doc.synonyms || [])];
+ const docLabel = getDocLabel(doc);
+ // Remove duplicates
+ const synonyms = doc.synonyms || [];
+ let labels = [docLabel, ...synonyms];
for (const label of labels) {
// https://codemirror.net/docs/ref/#autocomplete.Completion
if (label && !seen.has(label)) {
seen.add(label);
completions.push({
label,
- info: () => Autocomplete({ doc, label }),
+ info: () => Autocomplete(getSynonymDoc(doc, label)),
type: 'function', // https://codemirror.net/docs/ref/#autocomplete.Completion.type
});
}
diff --git a/packages/codemirror/tooltip.mjs b/packages/codemirror/tooltip.mjs
index f67e6d14a..d1d0479b2 100644
--- a/packages/codemirror/tooltip.mjs
+++ b/packages/codemirror/tooltip.mjs
@@ -1,6 +1,6 @@
import { hoverTooltip } from '@codemirror/view';
import jsdoc from '../../doc.json';
-import { Autocomplete } from './autocomplete.mjs';
+import { Autocomplete, getSynonymDoc } from './autocomplete.mjs';
const getDocLabel = (doc) => doc.name || doc.longname;
@@ -52,10 +52,11 @@ export const strudelTooltip = hoverTooltip(
let entry = jsdoc.docs.filter((doc) => getDocLabel(doc) === word)[0];
if (!entry) {
// Try for synonyms
- entry = jsdoc.docs.filter((doc) => doc.synonyms && doc.synonyms.includes(word))[0];
- if (!entry) {
+ const doc = jsdoc.docs.filter((doc) => doc.synonyms && doc.synonyms.includes(word))[0];
+ if (!doc) {
return null;
}
+ entry = getSynonymDoc(doc, word);
}
return {
@@ -66,7 +67,7 @@ export const strudelTooltip = hoverTooltip(
create(view) {
let dom = document.createElement('div');
dom.className = 'strudel-tooltip';
- const ac = Autocomplete({ doc: entry, label: word });
+ const ac = Autocomplete(entry);
dom.appendChild(ac);
return { dom };
},
diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs
index addc301d5..39790f8a0 100644
--- a/packages/core/pattern.mjs
+++ b/packages/core/pattern.mjs
@@ -1246,7 +1246,8 @@ export const silence = gap(1);
/* Like silence, but with a 'steps' (relative duration) of 0 */
export const nothing = gap(0);
-/** A discrete value that repeats once per cycle.
+/**
+ * A discrete value that repeats once per cycle.
*
* @returns {Pattern}
* @example
@@ -1299,7 +1300,8 @@ export function sequenceP(pats) {
return result;
}
-/** The given items are played at the same time at the same length.
+/**
+ * The given items are played at the same time at the same length.
*
* @return {Pattern}
* @synonyms polyrhythm, pr
@@ -1382,11 +1384,11 @@ export function stackBy(by, ...pats) {
.setSteps(steps);
}
-/** Concatenation: combines a list of patterns, switching between them successively, one per cycle:
- *
- * synonyms: `cat`
+/**
+ * Concatenation: combines a list of patterns, switching between them successively, one per cycle.
*
* @return {Pattern}
+ * @synonyms cat
* @example
* slowcat("e5", "b4", ["d5", "c5"])
*
diff --git a/website/src/repl/Repl.css b/website/src/repl/Repl.css
index 498679090..9cf51ff85 100644
--- a/website/src/repl/Repl.css
+++ b/website/src/repl/Repl.css
@@ -112,6 +112,13 @@
margin: 0 0 8px 0;
}
+.autocomplete-info-function-synonyms {
+ margin: 0 0 12px 0;
+ color: var(--foreground);
+ line-height: 1.5;
+ opacity: 0.8;
+}
+
.autocomplete-info-function-description {
margin: 0 0 12px 0;
color: var(--foreground);
diff --git a/website/src/repl/components/panel/Reference.jsx b/website/src/repl/components/panel/Reference.jsx
index 81826aca2..6007667fa 100644
--- a/website/src/repl/components/panel/Reference.jsx
+++ b/website/src/repl/components/panel/Reference.jsx
@@ -16,8 +16,7 @@ const availableFunctions = (() => {
if (!s || seen.has(s)) continue;
seen.add(s);
// Swap `doc.name` in for `s` in the list of synonyms
- const notS = synonyms.filter((x) => x && x !== s);
- const synonymsWithDoc = Array.from(new Set([doc.name, ...notS]));
+ const synonymsWithDoc = [doc.name, ...synonyms].filter((x) => x && x !== s);
functions.push({
...doc,
name: s, // update names for the synonym