Skip to content

Show languages in the docs sidebar #2859

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Apr 11, 2025
6 changes: 6 additions & 0 deletions changelog/2025-02-addedLanguagesToDocs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
tags: [documentation]
pullRequest: 2859
---

- Added languages sidebar to documents page. Here you can see the supported scope facets for each language.
1 change: 1 addition & 0 deletions packages/common/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export * from "./types/TreeSitter";
export * from "./types/tutorial.types";
export * from "./util";
export * from "./util/camelCaseToAllDown";
export * from "./util/capitalize";
export * from "./util/clientSupportsFallback";
export * from "./util/CompositeKeyDefaultMap";
export * from "./util/CompositeKeyMap";
Expand Down
3 changes: 3 additions & 0 deletions packages/common/src/util/capitalize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function capitalize(str: string) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ludicrous that this is not part of the javascript standard.

return str.charAt(0).toUpperCase() + str.slice(1);
}
20 changes: 20 additions & 0 deletions packages/cursorless-org-docs/src/css/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,23 @@
.hidden {
display: none;
}

.card {
Copy link
Member Author

@AndreasArvidsson AndreasArvidsson Feb 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I could tell we don't have a css library for the docs page? I didn't want to add one for this simple use case.

border: 1px solid rgba(0, 0, 0, 0.175);
margin-bottom: 1rem;
}

.card-header {
background-color: #f8f9fa;
border-bottom: 1px solid rgba(0, 0, 0, 0.125);
padding: 0.5rem 1rem;
cursor: pointer;
}

.card-body {
padding: 1rem;
}

.facet-name {
font-weight: 600;
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Language from "./Language";
import { Language } from "./components/Language";

# C

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Language from "./Language";
import { Language } from "./components/Language";

# Clojure

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from "react";
import ScopeSupport from "./ScopeSupport";
import { ScopeSupport } from "./ScopeSupport";

interface Props {
languageId: string;
}

export default function Language({ languageId }: Props) {
export function Language({ languageId }: Props) {
return <ScopeSupport languageId={languageId} />;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import {
ScopeSupportFacetLevel,
languageScopeSupport,
scopeSupportFacets,
} from "@cursorless/common";
import React from "react";
import { ScopeSupportForLevel } from "./ScopeSupportForLevel";

interface Props {
languageId: string;
}

export function ScopeSupport({ languageId }: Props): JSX.Element {
const scopesSorted = [...scopeSupportFacets].sort();
const scopeSupport = languageScopeSupport[languageId] ?? {};

const supportedScopes = scopesSorted.filter(
(facet) => scopeSupport[facet] === ScopeSupportFacetLevel.supported,
);
const supportedLegacyScopes = scopesSorted.filter(
(facet) => scopeSupport[facet] === ScopeSupportFacetLevel.supportedLegacy,
);
const unsupportedScopes = scopesSorted.filter(
(facet) => scopeSupport[facet] === ScopeSupportFacetLevel.unsupported,
);
const unspecifiedScopes = scopesSorted.filter(
(facet) => scopeSupport[facet] == null,
);

return (
<>
<h2>Scopes</h2>

<ScopeSupportForLevel
facets={supportedScopes}
title="Supported facets"
subtitle="These facets are supported"
expanded
/>

<ScopeSupportForLevel
facets={supportedLegacyScopes}
title="Supported Legacy facets"
subtitle="These facets are supported with the legacy implementation and should be migrated to the new implementation"
/>

<ScopeSupportForLevel
facets={unsupportedScopes}
title="Unsupported facets"
subtitle="These facets are not supported yet and needs a developer to implement them"
description={
<>
We would happily accept{" "}
<a href="https://www.cursorless.org/docs/contributing/adding-a-new-scope">
contributions
</a>
</>
}
/>

<ScopeSupportForLevel
facets={unspecifiedScopes}
title="Unspecified facets"
subtitle="These facets are unspecified"
description={
<>
Note that in many instances we actually do support these scopes and
facets, but we have not yet updated 'languageScopeSupport' to
reflect this fact.
<br />
We would happily accept{" "}
<a href="https://www.cursorless.org/docs/contributing/adding-a-new-scope">
contributions
</a>
</>
}
/>
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import {
camelCaseToAllDown,
capitalize,
groupBy,
type ScopeSupportFacet,
type ScopeSupportFacetInfo,
scopeSupportFacetInfos,
type ScopeType,
type SimpleScopeTypeType,
} from "@cursorless/common";
import React, { useState } from "react";

interface Props {
facets: ScopeSupportFacet[];
title: string;
subtitle: string;
description?: React.ReactNode;
expanded?: boolean;
}

export function ScopeSupportForLevel({
facets,
title,
subtitle,
description,
expanded: expandedProp,
}: Props): JSX.Element | null {
const [expanded, setExpanded] = useState(expandedProp ?? false);

if (facets.length === 0) {
return null;
}

const renderBody = () => {
if (!expanded) {
return null;
}

const facetInfos = facets.map(
(facet): AugmentedFacetInfo => ({
facet,
...scopeSupportFacetInfos[facet],
}),
);
const scopeGroups: Map<string, AugmentedFacetInfo[]> = groupBy(
facetInfos,
(facetInfo) => serializeScopeType(facetInfo.scopeType),
);
const scopeTypes = Array.from(scopeGroups.keys()).sort();

return (
<div className="card-body">
{description && <p>{description}</p>}

{scopeTypes.map((scopeType) => {
const facetInfos = scopeGroups.get(scopeType) ?? [];
return (
<div key={scopeType}>
<h4>{prettifyScopeType(scopeType)}</h4>
<ul>
{facetInfos.map((facetInfo) => {
return (
<li key={facetInfo.facet}>
<span className="facet-name" title={facetInfo.facet}>
{prettifyFacet(facetInfo.facet)}
</span>
: {facetInfo.description}
</li>
);
})}
</ul>
</div>
);
})}
</div>
);
};

return (
<div className="card">
<div className="card-header" onClick={() => setExpanded(!expanded)}>
<h3>{title}</h3>
{subtitle}
</div>

{renderBody()}
</div>
);
}

interface AugmentedFacetInfo extends ScopeSupportFacetInfo {
facet: ScopeSupportFacet;
}

function prettifyScopeType(scopeType: string): string {
return capitalize(camelCaseToAllDown(scopeType));
}

function prettifyFacet(facet: ScopeSupportFacet): string {
const parts = facet.split(".").map(camelCaseToAllDown);
if (parts.length === 1) {
return capitalize(parts[0]);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some facets just have the same name as the scope. In that case I just keep it.

image
image

}
const isIteration = parts[parts.length - 1] === "iteration";
if (isIteration) {
parts.pop();
}
const name = capitalize(parts.slice(1).join(" "));
return isIteration ? `${name} (iteration)` : name;
}

function serializeScopeType(
scopeType: SimpleScopeTypeType | ScopeType,
): string {
if (typeof scopeType === "string") {
return scopeType;
}
return scopeType.type;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Language from "./Language";
import { Language } from "./components/Language";

# C++

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Language from "./Language";
import { Language } from "./components/Language";

# C#

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Language from "./Language";
import { Language } from "./components/Language";

# CSS

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Language from "./Language";
import { Language } from "./components/Language";

# dart
# Dart

<Language languageId="dart"></Language>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Language from "./Language";
import { Language } from "./components/Language";

# Go

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Language from "./Language";
import { Language } from "./components/Language";

# HTML

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Language from "./Language";
import { Language } from "./components/Language";

# Java

Expand Down
Loading
Loading