Skip to content

Commit 10680c4

Browse files
committed
Added table commands
Moved icons and gifs into common folder Restructured code
1 parent d5980c2 commit 10680c4

27 files changed

+223
-102
lines changed

README.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@
22
Handy shortcuts for editing Markdown (`.md`, `.markdown`) files. Now with title and context menu integration!
33

44
**Quickly toggle bullet points**
5-
![](https://raw.githubusercontent.com/mdickin/vscode-markdown-shortcuts/master/gifs/bullets.gif)
5+
![](https://raw.githubusercontent.com/mdickin/vscode-markdown-shortcuts/master/media/demo/bullets.gif)
66

77
**Easily generate URLs**
8-
![](https://raw.githubusercontent.com/mdickin/vscode-markdown-shortcuts/master/gifs/urls.gif)
8+
![](https://raw.githubusercontent.com/mdickin/vscode-markdown-shortcuts/master/media/demo/urls.gif)
9+
10+
**Convert tabular data to tables**
11+
![](https://raw.githubusercontent.com/mdickin/vscode-markdown-shortcuts/master/media/demo/table_with_header.gif)
12+
13+
14+
**Context and title menu integration**
15+
![](https://raw.githubusercontent.com/mdickin/vscode-markdown-shortcuts/master/media/demo/shortcut_menu.png)
916

1017
**Note**: extension will override a few default VS Code key bindings (ctrl+B, ctrl+I, ctrl+L), but only when editing Markdown files.
1118

@@ -28,12 +35,14 @@ Handy shortcuts for editing Markdown (`.md`, `.markdown`) files. Now with title
2835
| md-shortcut.toggleTitleH4 | Toggle #### H4 title | |
2936
| md-shortcut.toggleTitleH5 | Toggle ##### H5 title | |
3037
| md-shortcut.toggleTitleH6 | Toggle ###### H6 title | |
38+
| md-shortcut.addTable | Add Tabular values | |
39+
| md-shortcut.addTableWithHeader | Add Tabular values with header | |
3140

3241
## Changelog
3342

3443
**v0.4.0**
35-
* Added title and context menu shortcuts. Menu icons taken from material.io/icons
36-
* Added checkbox command. Thanks to [@wenbaofu](https://github.com/wenbaofu) for the recommendation!
44+
* Added title and context menu shortcuts. Menu icons taken from http://material.io/icons
45+
* Added checkbox and table commands. Thanks to [@wenbaofu](https://github.com/wenbaofu) for the recommendations!
3746

3847
**v0.3.0**
3948
* Added header shortcuts. Thanks to [@alebaffa](https://github.com/alebaffa) for the contribution!

extension.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
var commands = require('./commands');
1+
var commands = require('./lib/commands');
22

33
function activate(context) {
44

commands.js renamed to lib/commands.js

Lines changed: 34 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
var vscode = require("vscode")
2+
var editorHelpers = require("./editorHelpers");
3+
var tables = require("./tables");
4+
25
module.exports = {
36
register: register
47
}
@@ -18,7 +21,9 @@ var _commands = [
1821
new Command('toggleTitleH4', toggleTitleH4, 'Toggle title H4', '#### Title', true),
1922
new Command('toggleTitleH5', toggleTitleH5, 'Toggle title H5', '##### Title', true),
2023
new Command('toggleTitleH6', toggleTitleH6, 'Toggle title H6', '###### Title', true),
21-
new Command('toggleCheckboxes', toggleCheckboxes, 'Toggle checkboxes', '- [x] Checkbox item', true)
24+
new Command('toggleCheckboxes', toggleCheckboxes, 'Toggle checkboxes', '- [x] Checkbox item', true),
25+
new Command('addTable', tables.addTable, 'Add table', 'Tabular | values', true),
26+
new Command('addTableWithHeader', tables.addTableWithHeader, 'Add table (with header)', 'Tabular | values', true)
2227
]
2328

2429
function register(context) {
@@ -40,77 +45,77 @@ function showCommandPalette() {
4045
}
4146

4247
function toggleBold() {
43-
surroundSelection('**')
48+
editorHelpers.surroundSelection('**')
4449
}
4550

4651
function toggleItalic() {
47-
surroundSelection('_')
52+
editorHelpers.surroundSelection('_')
4853
}
4954

5055
function toggleCodeBlock() {
51-
surroundSelection('```\n', '\n```')
56+
editorHelpers.surroundSelection('```\n', '\n```')
5257
}
5358

5459
function toggleInlineCode() {
55-
surroundSelection('`')
60+
editorHelpers.surroundSelection('`')
5661
}
5762

5863
function toggleTitleH1() {
59-
surroundSelection('# ','')
64+
editorHelpers.surroundSelection('# ','')
6065
}
6166

6267
function toggleTitleH2() {
63-
surroundSelection('## ','')
68+
editorHelpers.surroundSelection('## ','')
6469
}
6570

6671
function toggleTitleH3() {
67-
surroundSelection('### ','')
72+
editorHelpers.surroundSelection('### ','')
6873
}
6974

7075
function toggleTitleH4() {
71-
surroundSelection('#### ','')
76+
editorHelpers.surroundSelection('#### ','')
7277
}
7378

7479
function toggleTitleH5() {
75-
surroundSelection('##### ','')
80+
editorHelpers.surroundSelection('##### ','')
7681
}
7782

7883
function toggleTitleH6() {
79-
surroundSelection('###### ','')
84+
editorHelpers.surroundSelection('###### ','')
8085
}
8186

8287
var HasBullets = /^(\s*)\* (.*)$/gm
8388
var AddBullets = /^(\s*)(.+)$/gm
8489
function toggleBullets() {
8590

86-
if (!isAnythingSelected()) {
87-
surroundSelection("* ", "")
91+
if (!editorHelpers.isAnythingSelected()) {
92+
editorHelpers.surroundSelection("* ", "")
8893
return;
8994
}
9095

91-
if (isMatch(HasBullets)) {
92-
replaceSelection((text) => text.replace(HasBullets, "$1$2"))
96+
if (editorHelpers.isMatch(HasBullets)) {
97+
editorHelpers.replaceSelection((text) => text.replace(HasBullets, "$1$2"))
9398
}
9499
else {
95-
replaceSelection((text) => text.replace(AddBullets, "$1* $2"))
100+
editorHelpers.replaceSelection((text) => text.replace(AddBullets, "$1* $2"))
96101
}
97102
}
98103

99104
var HasNumbers = /^(\s*)[0-9]\.+ (.*)$/gm
100105
var AddNumbers = /^(\s*)(.+)$/gm
101106
function toggleNumberList() {
102107

103-
if (!isAnythingSelected()) {
104-
surroundSelection("1. ", "")
108+
if (!editorHelpers.isAnythingSelected()) {
109+
editorHelpers.surroundSelection("1. ", "")
105110
return;
106111
}
107112

108-
if (isMatch(HasNumbers)) {
109-
replaceSelection((text) => text.replace(HasNumbers, "$1$2"))
113+
if (editorHelpers.isMatch(HasNumbers)) {
114+
editorHelpers.replaceSelection((text) => text.replace(HasNumbers, "$1$2"))
110115
}
111116
else {
112117
var lineNums = {};
113-
replaceSelection((text) => text.replace(AddNumbers, (match, whitespace, line) => {
118+
editorHelpers.replaceSelection((text) => text.replace(AddNumbers, (match, whitespace, line) => {
114119
if (!lineNums[whitespace]) {
115120
lineNums[whitespace] = 1
116121
}
@@ -123,23 +128,23 @@ var HasCheckboxes = /^(\s*)- \[[ x]{1}\] (.*)$/gm
123128
var AddCheckboxes = /^(\s*)(.+)$/gm
124129
function toggleCheckboxes() {
125130

126-
if (!isAnythingSelected()) {
127-
surroundSelection("- [ ]", "")
131+
if (!editorHelpers.isAnythingSelected()) {
132+
editorHelpers.surroundSelection("- [ ]", "")
128133
return;
129134
}
130135

131-
if (isMatch(HasCheckboxes)) {
132-
replaceSelection((text) => text.replace(HasCheckboxes, "$1$2"))
136+
if (editorHelpers.isMatch(HasCheckboxes)) {
137+
editorHelpers.replaceSelection((text) => text.replace(HasCheckboxes, "$1$2"))
133138
}
134139
else {
135-
replaceSelection((text) => text.replace(AddCheckboxes, "$1- [ ] $2"))
140+
editorHelpers.replaceSelection((text) => text.replace(AddCheckboxes, "$1- [ ] $2"))
136141
}
137142
}
138143

139144
function toggleLink() {
140145

141-
if (isMatch(/^\[.+\]\(.+\)$/i)) {
142-
replaceSelection((text) => text.match(/\[(.+)\]/)[1])
146+
if (editorHelpers.isMatch(/^\[.+\]\(.+\)$/i)) {
147+
editorHelpers.replaceSelection((text) => text.match(/\[(.+)\]/)[1])
143148
return;
144149
}
145150
else {
@@ -175,63 +180,10 @@ function toggleLink() {
175180
function addTags(options) {
176181
if (!options || !options.url) return;
177182

178-
surroundSelection("[" + options.text, "](" + options.url + ")")
179-
}
180-
}
181-
182-
function surroundSelection(startPattern, endPattern)
183-
{
184-
if (endPattern == undefined || endPattern == null) endPattern = startPattern;
185-
186-
var editor = vscode.window.activeTextEditor;
187-
var selection = editor.selection;
188-
189-
if (!isAnythingSelected()) {
190-
var position = selection.active;
191-
var newPosition = position.with(position.line, position.character + startPattern.length)
192-
editor.edit((edit) => {
193-
edit.insert(selection.start, startPattern + endPattern);
194-
}).then(() => {
195-
editor.selection = new vscode.Selection(newPosition, newPosition)
196-
})
197-
}
198-
else {
199-
if (isMatch(startPattern, endPattern)) {
200-
replaceSelection((text) => text.substr(startPattern.length, text.length - startPattern.length - endPattern.length))
201-
}
202-
else {
203-
replaceSelection((text) => startPattern + text + endPattern)
204-
}
183+
editorHelpers.surroundSelection("[" + options.text, "](" + options.url + ")")
205184
}
206185
}
207186

208-
function isAnythingSelected() {
209-
return !vscode.window.activeTextEditor.selection.isEmpty;
210-
}
211-
212-
function isMatch(startPattern, endPattern) {
213-
214-
var editor = vscode.window.activeTextEditor;
215-
var selection = editor.selection;
216-
217-
var text = editor.document.getText(selection)
218-
if (startPattern.constructor === RegExp) {
219-
return startPattern.test(text);
220-
}
221-
222-
return text.startsWith(startPattern) && text.endsWith(endPattern)
223-
}
224-
225-
function replaceSelection(replaceFunc) {
226-
var editor = vscode.window.activeTextEditor;
227-
var selection = editor.selection;
228-
229-
var newText = replaceFunc(editor.document.getText(selection));
230-
editor.edit((edit) => {
231-
edit.replace(selection, newText)
232-
})
233-
}
234-
235187
function Command(command, callback, label, description, showInCommandPalette) {
236188
this.command = command;
237189
this.callback = callback;

lib/editorHelpers.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
var vscode = require("vscode");
2+
3+
module.exports = {
4+
isAnythingSelected: isAnythingSelected,
5+
replaceSelection: replaceSelection,
6+
surroundSelection: surroundSelection,
7+
isMatch: isMatch
8+
}
9+
10+
function replaceSelection(replaceFunc) {
11+
var editor = vscode.window.activeTextEditor;
12+
var selection = editor.selection;
13+
14+
var newText = replaceFunc(editor.document.getText(selection));
15+
return editor.edit((edit) => {
16+
edit.replace(selection, newText)
17+
})
18+
}
19+
20+
function isAnythingSelected() {
21+
return !vscode.window.activeTextEditor.selection.isEmpty;
22+
}
23+
24+
function surroundSelection(startPattern, endPattern)
25+
{
26+
if (endPattern == undefined || endPattern == null) endPattern = startPattern;
27+
28+
var editor = vscode.window.activeTextEditor;
29+
var selection = editor.selection;
30+
31+
if (!isAnythingSelected()) {
32+
var position = selection.active;
33+
var newPosition = position.with(position.line, position.character + startPattern.length)
34+
editor.edit((edit) => {
35+
edit.insert(selection.start, startPattern + endPattern);
36+
}).then(() => {
37+
editor.selection = new vscode.Selection(newPosition, newPosition)
38+
})
39+
}
40+
else {
41+
if (isMatch(startPattern, endPattern)) {
42+
replaceSelection((text) => text.substr(startPattern.length, text.length - startPattern.length - endPattern.length))
43+
}
44+
else {
45+
replaceSelection((text) => startPattern + text + endPattern)
46+
}
47+
}
48+
}
49+
50+
function isMatch(startPattern, endPattern) {
51+
52+
var editor = vscode.window.activeTextEditor;
53+
var selection = editor.selection;
54+
55+
var text = editor.document.getText(selection)
56+
if (startPattern.constructor === RegExp) {
57+
return startPattern.test(text);
58+
}
59+
60+
return text.startsWith(startPattern) && text.endsWith(endPattern)
61+
}

lib/tables.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
var vscode = require("vscode");
2+
var editorHelpers = require("./editorHelpers");
3+
4+
module.exports = {
5+
addTable: () => addTable(false),
6+
addTableWithHeader: () => addTable(true)
7+
};
8+
9+
var sampleTable = [
10+
"",
11+
"Column A | Column B | Column C",
12+
"---------|----------|---------",
13+
" A1 | B1 | C1",
14+
" A2 | B2 | C2",
15+
" A3 | B3 | C3"
16+
].join("\r\n");
17+
18+
function addTable(addHeader) {
19+
//var editor = vscode.window.activeTextEditor;
20+
21+
var editFunc;
22+
if (!editorHelpers.isAnythingSelected()) {
23+
editFunc = () => sampleTable;
24+
}
25+
else if (addHeader) {
26+
editFunc = convertToTableWithHeader;
27+
}
28+
else {
29+
editFunc = convertToTableWithoutHeader;
30+
}
31+
editorHelpers.replaceSelection(editFunc);
32+
}
33+
34+
var tableColumnSeparator = /([ ]{2,}|[\t])/gi;
35+
function convertToTableWithoutHeader(text) {
36+
var firstRow = text.match(/.+/);
37+
38+
var columnSeparators = firstRow == null ? null : firstRow[0].match(tableColumnSeparator);
39+
var columnCount = columnSeparators == null ? 0 : columnSeparators.length;
40+
var line1 = [];
41+
for (var i = 0; i < columnCount + 1; i++) {
42+
line1.push("column" + i);
43+
}
44+
var tableHeader = line1.join(" | ") + "\r\n";
45+
tableHeader = tableHeader + tableHeader.replace(/[a-z0-9]/gi, "-");
46+
47+
return tableHeader + text.replace(tableColumnSeparator, " | ");
48+
}
49+
50+
function convertToTableWithHeader(text) {
51+
var textAsTable = text.replace(tableColumnSeparator, " | ");
52+
53+
var firstRow = textAsTable.match(/.+/)[0];
54+
55+
var headerLine = firstRow.replace(/[^\|]/gi, "-");
56+
57+
return firstRow + "\r\n" + headerLine + textAsTable.substring(firstRow.length);
58+
}

media/demo/bullets.gif

120 KB
Loading

media/demo/shortcut_menu.png

24.4 KB
Loading

media/demo/table_with_header.gif

132 KB
Loading

media/demo/urls.gif

227 KB
Loading
File renamed without changes.

0 commit comments

Comments
 (0)