Skip to content

Commit 80af744

Browse files
committed
Merge pull request #9 from lumaxis/feature/markdown-blocks
New: Add support for copying snippets as Markdown code blocks
2 parents 5290123 + dfd68f1 commit 80af744

File tree

7 files changed

+100
-21
lines changed

7 files changed

+100
-21
lines changed

CHANGELOG.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
### Features
66

7-
- Add support for copying snippets from multiple selections
7+
- Add additional command to copy snippet with surrounding Markdown code block syntax
8+
- Add configuration option to add language identifier to Markdown code blocks
9+
- Add support for copying snippets from multiple selections
810

911
### Chores
1012

README.md

+16-4
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,30 @@
11
# Snippet Copy
22

33
Ever wanted to copy part of a source file as a snippet and paste it somewhere else, like in Slack or in a GitHub comment?
4-
Previously, you either got a bunch of unnecessary indentation that made the snippet ugly to read or you had to manually un-tab the snippet, copy, and then reset the indentation.
54

5+
Previously, you either got a bunch of unnecessary indentation that made the snippet ugly to read or you had to manually un-tab the snippet, copy, and then reset the indentation.
66
With **Snippet Copy** you can automatically get a snippet added to your clipboard with all the unnecessary indentation already removed!
77

88
## Features
99

10-
You can use the extension via a bunch of different ways:
10+
All features can be used via different ways in VS Code
1111

12-
- Via the Command Palette and the pre-configured keyboard shortcut
12+
- ⌨️ The **Command Palette** and the pre-configured **Keyboard Shortcuts**
1313

1414
![Command in Command Palette](images/command-palette.png)
1515

16-
- Via the Context Menu on selected text in the editor
16+
- 📝 The **Context Menu** on selected text in the editor
1717

1818
![Command in Context Menu](images/context-menu.png)
19+
20+
### Copy Snippet Without Leading Indentation
21+
22+
Simply get a copy of your currently selected code or text snippet added to your clipboard – without any unnecessary indentation that you would otherwise need to remove manually.
23+
24+
### Copy Snippet Without Leading Indentation as Markdown Code Block
25+
26+
This command has an additional configuration option that let's you determine if the Markdown code block should contain the file's language identifier which enables [syntax highlighting](https://help.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks#syntax-highlighting) in some places:
27+
28+
```json
29+
"snippet-copy.addLanguageIdToMarkdownBlock": false // Default is false
30+
```

package.json

+32-5
Original file line numberDiff line numberDiff line change
@@ -19,31 +19,58 @@
1919
"vscode": "^1.44.0"
2020
},
2121
"activationEvents": [
22-
"onCommand:snippet-copy.copyWithoutLeadingIndentation"
22+
"onCommand:snippet-copy.copySnippet",
23+
"onCommand:snippet-copy.copySnippetAsMarkdownCodeBlock"
2324
],
2425
"main": "./out/extension.js",
2526
"contributes": {
2627
"commands": [
2728
{
28-
"command": "snippet-copy.copyWithoutLeadingIndentation",
29-
"title": "Copy Without Leading Indentation"
29+
"command": "snippet-copy.copySnippet",
30+
"title": "Copy Snippet Without Leading Indentation"
31+
},
32+
{
33+
"command": "snippet-copy.copySnippetAsMarkdownCodeBlock",
34+
"title": "Copy Snippet Without Leading Indentation as Markdown Code Block"
3035
}
3136
],
37+
"configuration": {
38+
"title": "Snippet Copy",
39+
"properties": {
40+
"snippet-copy.addLanguageIdentifierToMarkdownBlock": {
41+
"type": "boolean",
42+
"default": false,
43+
"description": "Add a programming language identifier to the beginning of the Markdown code block. This is incompatible with some apps, for example Slack."
44+
}
45+
}
46+
},
3247
"keybindings": [
3348
{
34-
"command": "snippet-copy.copyWithoutLeadingIndentation",
49+
"command": "snippet-copy.copySnippet",
3550
"mac": "Cmd+Ctrl+c",
3651
"linux": "Meta+Ctrl+c",
3752
"win": "Win+Ctrl+c",
3853
"when": "editorHasSelection"
54+
},
55+
{
56+
"command": "snippet-copy.copySnippetAsMarkdownCodeBlock",
57+
"mac": "Cmd+Ctrl+Shift+c",
58+
"linux": "Meta+Ctrl+Shift+c",
59+
"win": "Win+Ctrl+Shift+c",
60+
"when": "editorHasSelection"
3961
}
4062
],
4163
"menus": {
4264
"editor/context": [
4365
{
44-
"command": "snippet-copy.copyWithoutLeadingIndentation",
66+
"command": "snippet-copy.copySnippet",
4567
"when": "editorHasSelection",
4668
"group": "9_cutcopypaste@2"
69+
},
70+
{
71+
"command": "snippet-copy.copySnippetAsMarkdownCodeBlock",
72+
"when": "editorHasSelection",
73+
"group": "9_cutcopypaste@3"
4774
}
4875
]
4976
}

src/extension.ts

+13-7
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
1-
import * as vscode from 'vscode';
2-
import { ExtensionContext } from 'vscode';
1+
import { commands, env, ExtensionContext } from 'vscode';
32
import { generateSnippet } from './lib/textHelpers';
43

54
export function activate(context: ExtensionContext) {
6-
let disposable = vscode.commands.registerTextEditorCommand('snippet-copy.copyWithoutLeadingIndentation', async (editor) => {
7-
const snippet = generateSnippet(editor.document, editor.selections);
5+
context.subscriptions.push(
6+
commands.registerTextEditorCommand('snippet-copy.copySnippet', async (editor) => {
7+
const snippet = generateSnippet(editor.document, editor.selections, false);
88

9-
await vscode.env.clipboard.writeText(snippet);
10-
});
9+
await env.clipboard.writeText(snippet);
10+
})
11+
);
12+
context.subscriptions.push(
13+
commands.registerTextEditorCommand('snippet-copy.copySnippetAsMarkdownCodeBlock', async (editor) => {
14+
const snippet = generateSnippet(editor.document, editor.selections, true);
1115

12-
context.subscriptions.push(disposable);
16+
await env.clipboard.writeText(snippet);
17+
})
18+
);
1319
}
1420

1521
export function deactivate() { }

src/lib/documentHelpers.ts

+4
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,7 @@ export function adjustedRangeWithMinimumIndentation(range: Range, minimumIndenta
3838
export function endOfLineCharacter(document: TextDocument): string {
3939
return document.eol === EndOfLine.CRLF ? '\r\n' : '\n';
4040
}
41+
42+
export function languageId(document: TextDocument): string {
43+
return document.languageId;
44+
}

src/lib/textHelpers.ts

+19-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
1-
import { Selection, TextDocument } from "vscode";
2-
import { contentOfLinesWithAdjustedIndentation, endOfLineCharacter, minimumIndentationForLineIndexes } from "./documentHelpers";
1+
import { Selection, TextDocument, workspace } from "vscode";
2+
import { contentOfLinesWithAdjustedIndentation, endOfLineCharacter, languageId, minimumIndentationForLineIndexes } from "./documentHelpers";
33
import { lineIndexesForSelection } from "./selectionHelpers";
44

5-
export function generateSnippet(document: TextDocument, selections: Selection[]): string {
5+
export function generateSnippet(document: TextDocument, selections: Selection[], markdownCodeBlock = false): string {
66
let texts: string[] = [];
77
selections.forEach(selection => {
88
texts.push(generateCopyableText(document, selection));
99
});
1010

1111
const snippet = texts.join(endOfLineCharacter(document));
1212

13+
if (markdownCodeBlock) {
14+
const config = workspace.getConfiguration('snippet-copy');
15+
16+
return wrapTextInMarkdownCodeBlock(document, snippet, config.addLanguageIdentifierToMarkdownBlock);
17+
}
18+
1319
return snippet;
1420
}
1521

@@ -26,3 +32,13 @@ export function generateCopyableText(document: TextDocument, selection: Selectio
2632

2733
return text;
2834
}
35+
36+
export function wrapTextInMarkdownCodeBlock(document: TextDocument, text: string, addLanguageId = false): string {
37+
const codeBlockDelimiter = '```';
38+
const eolCharacter = endOfLineCharacter(document);
39+
const optionalLanguageIdentifier = addLanguageId ? languageId(document) : '';
40+
41+
return codeBlockDelimiter + optionalLanguageIdentifier + eolCharacter +
42+
text + eolCharacter +
43+
codeBlockDelimiter;
44+
}

src/test/suite/lib/textHelpers.test.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as assert from 'assert';
22
import * as path from 'path';
33
import * as vscode from 'vscode';
44
import { Position, Selection, TextDocument } from 'vscode';
5-
import { generateCopyableText, generateSnippet } from '../../../lib/textHelpers';
5+
import { generateCopyableText, generateSnippet, wrapTextInMarkdownCodeBlock } from '../../../lib/textHelpers';
66

77
const fixturesPath = '/../../../../src/test/fixtures/';
88
const uri = vscode.Uri.file(
@@ -60,5 +60,17 @@ describe('Text Helpers', () => {
6060
generateCopyableText(document, new Selection(testSelection1.selection.start, new Position(5, 0)))
6161
);
6262
});
63+
64+
context('wrapTextInMarkdownCodeBlock', () => {
65+
it('returns the text wrapped in a Markdown code block', () => {
66+
const codeSnippet = 'console.log("Yo");';
67+
assert.equal(wrapTextInMarkdownCodeBlock(document, codeSnippet), '```\n' + codeSnippet + '\n```');
68+
});
69+
70+
it('returns the wrapped text with a language identifier', () => {
71+
const codeSnippet = 'console.log("Yo");';
72+
assert.equal(wrapTextInMarkdownCodeBlock(document, codeSnippet, true), '```javascript\n' + codeSnippet + '\n```');
73+
});
74+
});
6375
});
6476
});

0 commit comments

Comments
 (0)