Skip to content

Generate snippets for community format#2744

Merged
phillco merged 12 commits into
mainfrom
generateSnippets2
Jan 23, 2025
Merged

Generate snippets for community format#2744
phillco merged 12 commits into
mainfrom
generateSnippets2

Conversation

@AndreasArvidsson

Copy link
Copy Markdown
Member

If the user has set the user.cursorless_use_community_snippets tag we create a snippet in the community snippet format instead of the Cursorless one.

The legacy Cursorless snippets will be removed in a final pull request.

Checklist

  • I have added tests
  • [/] I have updated the docs and cheatsheet
  • [/] I have not broken the cheatsheet

actions.user.private_cursorless_command_no_wait(
{
"name": "generateSnippet",
"target": target,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

By default don't send dirPath argument. This is for the legacy Cursorless snippet format. The vscode setting for snippet directory will be used.

{
"name": "generateSnippet",
"target": target,
"dirPath": get_dir_path(),

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

If the community snippet tag has been set send dirPath argument. A new community snippet will be added to this folder.

Comment on lines +193 to +196
const metaSnippetText = serializeSnippetFile(snippetDocuments)
// Escape dollar signs in the snippet text so that they don't get used as
// placeholders in the meta snippet
.replace(/\$/g, "\\$")

Check failure

Code scanning / CodeQL

Incomplete string escaping or encoding

This does not escape backslash characters in the input.

Copilot Autofix

AI over 1 year ago

To fix the problem, we need to ensure that backslashes are properly escaped in the metaSnippetText string. This can be done by adding a replace operation to escape backslashes before any other replacements are made. Specifically, we should replace each backslash (\) with a double backslash (\\). This ensures that any backslashes in the input are correctly handled and do not lead to injection vulnerabilities or malformed strings.

Suggested changeset 1
packages/cursorless-engine/src/actions/GenerateSnippet/GenerateSnippetCommunity.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/packages/cursorless-engine/src/actions/GenerateSnippet/GenerateSnippetCommunity.ts b/packages/cursorless-engine/src/actions/GenerateSnippet/GenerateSnippetCommunity.ts
--- a/packages/cursorless-engine/src/actions/GenerateSnippet/GenerateSnippetCommunity.ts
+++ b/packages/cursorless-engine/src/actions/GenerateSnippet/GenerateSnippetCommunity.ts
@@ -187,2 +187,4 @@
     const metaSnippetText = serializeSnippetFile(snippetDocuments)
+      // Escape backslashes in the snippet text
+      .replace(/\\/g, "\\\\")
       // Escape dollar signs in the snippet text so that they don't get used as
EOF
@@ -187,2 +187,4 @@
const metaSnippetText = serializeSnippetFile(snippetDocuments)
// Escape backslashes in the snippet text
.replace(/\\/g, "\\\\")
// Escape dollar signs in the snippet text so that they don't get used as
Copilot is powered by AI and may make mistakes. Always verify output.
@@ -0,0 +1,55 @@
languageId: typescript

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Double up on existing snippet make tests in the community format

spokenForm: snippet make funk
action:
name: generateSnippet
dirPath: ""

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Including the dirPath argument indicates that this is a community snippet.

user_dir = Path(actions.path.talon_user())
dir = user_dir / dir

return str(dir.resolve())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd make all of these return Path and only coalesce to a string when you need to stick it into the JSON dictionary

return get_community_snippets_dir()


def get_setting_dir() -> Path | None:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

TIL:

We can't currently use it in action definitions until v0.5 releases but we can use it in code like this

Comment on lines -233 to -234
// Insert the meta-snippet
await editableEditor.insertSnippet(snippetText);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

NB: this was technically a bug and relying on odd Visual Studio Code behavior because we aren't using the new editor that was created inside of this.snippets.openNewSnippetFile(snippetName);. It just so happens that insertSnippet always uses the current editor even if you call it on a different one. The new code fixes this by making the function return a promise with the actual new editor which we needed for appending.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

NB: Andreas fixed this because we now want to append the text to the file if it already exists, and reading the text from an editor that's not the current one does work, and that's when he found that the editor object was actually technically wrong

run(targets: Target[], snippetName?: string): Promise<ActionReturnValue>;
run(
targets: Target[],
dirPath?: string,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not thrilled about dirPath but it makes sense after discussion -- we sometimes have the directory name dirName so it's needed to disambiguate.

If we had a Path type of class it would be nicer so we didn't have to put the type information in the name itself, but we don't. We could make a wrapper ourselves or just do two type aliases. We might make a followup for this.

storageDirectory would be my choice for the name but not if it has to be storageDirectoryPath, I think that's worse than the status quo

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Settled on directory for now

@phillco phillco left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

.

Comment thread packages/cursorless-engine/src/disabledComponents/DisabledSnippets.ts Outdated
@phillco
phillco enabled auto-merge January 23, 2025 18:27
@phillco
phillco added this pull request to the merge queue Jan 23, 2025
Merged via the queue into main with commit 9611d3d Jan 23, 2025
@phillco
phillco deleted the generateSnippets2 branch January 23, 2025 18:45
cursorless-bot pushed a commit that referenced this pull request Jan 23, 2025
If the user has set the `user.cursorless_use_community_snippets` tag we
create a snippet in the community snippet format instead of the
Cursorless one.

The legacy Cursorless snippets will be removed in a final pull request.

## Checklist

- [x] I have added
[tests](https://www.cursorless.org/docs/contributing/test-case-recorder/)
- [/] I have updated the
[docs](https://github.com/cursorless-dev/cursorless/tree/main/docs) and
[cheatsheet](https://github.com/cursorless-dev/cursorless/tree/main/cursorless-talon/src/cheatsheet)
- [/] I have not broken the cheatsheet

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: Phil Cohen <phillip@phillip.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate "snip make" Cursorless action to output to community snippets dir

3 participants