Skip to content

Commit ec8f8a2

Browse files
authored
Merge pull request #42 from yoavbls/fix-formatting-bugs-and-add-tests
Fix formatting bugs and add tests
2 parents 7e7f623 + 42308a6 commit ec8f8a2

12 files changed

Lines changed: 259 additions & 89 deletions

File tree

.vscode/launch.json

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,32 @@
33
// Hover to view descriptions of existing attributes.
44
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
55
{
6-
"version": "0.2.0",
7-
"configurations": [
8-
{
9-
"name": "Run Extension",
10-
"type": "extensionHost",
11-
"request": "launch",
12-
"args": [
13-
"--extensionDevelopmentPath=${workspaceFolder}"
14-
],
15-
"outFiles": [
16-
"${workspaceFolder}/dist/**/*.js"
17-
],
18-
"preLaunchTask": "${defaultBuildTask}"
19-
},
20-
{
21-
"name": "Extension Tests",
22-
"type": "extensionHost",
23-
"request": "launch",
24-
"args": [
25-
"--extensionDevelopmentPath=${workspaceFolder}",
26-
"--extensionTestsPath=${workspaceFolder}/out/test/suite/index"
27-
],
28-
"outFiles": [
29-
"${workspaceFolder}/out/**/*.js",
30-
"${workspaceFolder}/dist/**/*.js"
31-
],
32-
"preLaunchTask": "tasks: watch-tests"
33-
}
34-
]
6+
"version": "0.2.0",
7+
"configurations": [
8+
{
9+
"name": "Run Extension",
10+
"type": "extensionHost",
11+
"request": "launch",
12+
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
13+
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
14+
"preLaunchTask": "${defaultBuildTask}",
15+
"env": {
16+
"VSCODE_DEBUG_MODE": "true"
17+
}
18+
},
19+
{
20+
"name": "Extension Tests",
21+
"type": "extensionHost",
22+
"request": "launch",
23+
"args": [
24+
"--extensionDevelopmentPath=${workspaceFolder}",
25+
"--extensionTestsPath=${workspaceFolder}/out/test/suite/index"
26+
],
27+
"outFiles": [
28+
"${workspaceFolder}/out/**/*.js",
29+
"${workspaceFolder}/dist/**/*.js"
30+
],
31+
"preLaunchTask": "tasks: watch-tests"
32+
}
33+
]
3534
}

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@
1313
[![Visual Studio Code](https://img.shields.io/badge/--007ACC?logo=visual%20studio%20code&logoColor=ffffff)](https://marketplace.visualstudio.com/items?itemName=yoavbls.pretty-ts-errors) [![GitHub license](https://badgen.net/github/license/yoavbls/pretty-ts-errors)](https://github.com/yoavbls/pretty-ts-errors/blob/main/LICENSE) ![visitor badge](https://visitor-badge.glitch.me/badge?page_id=pretty-ts-errors)
1414
[![GitHub stars](https://img.shields.io/github/stars/yoavbls/pretty-ts-errors.svg?style=social&label=Star)](https://GitHub.com/yoavbls/pretty-ts-errors/stargazers/)
1515

16-
<a href="https://github.com/yoavbls/pretty-ts-errors/issues/38"><img src="https://raw.githubusercontent.com/yoavbls/pretty-ts-errors/assets/assets/mentions/vote.png" height="32" /></a>
16+
<a href="https://github.com/yoavbls/pretty-ts-errors/issues/38"><img src="https://raw.githubusercontent.com/yoavbls/pretty-ts-errors/assets/assets/mentions/vote.png" width="490px" /></a>
1717

1818
TypeScript errors become messier as the complexity of types increases. At some point, TypeScript will throw on you a shitty heap of parentheses and `"..."`.
1919
This extension will help you understand what's going on. For example, in this relatively simple error:
2020

21-
<img src="./assets/this.png" style="max-height: 350px" height="350px" />&nbsp; &nbsp; <img src="./assets/instead-of-that.png" height="350px" width="350px" style="max-height: 350px" />
21+
<img src="./assets/this.png" width="340.438px" />&nbsp; &nbsp; <img src="./assets/instead-of-that.png" width="350px" />
2222

2323

2424
## Watch this
2525
<a href="https://www.youtube.com/watch?v=9RM2aErJs-s" target="_blank">
26-
<img src="https://raw.githubusercontent.com/yoavbls/pretty-ts-errors/assets/assets/mentions/theo-video.png" alt="Watch theo's video" style="max-height: 150px" width="550" />
26+
<img src="https://raw.githubusercontent.com/yoavbls/pretty-ts-errors/assets/assets/mentions/theo-video.png" alt="Watch theo's video" width="550" />
2727
</a>
2828

2929
## Features
@@ -56,20 +56,20 @@ Yes, these types include things like `... more ...`, `{ ... }`, etc in an incons
5656
## Hype section
5757
<a href="https://twitter.com/t3dotgg/status/1647759462709747713">
5858
<picture>
59-
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/yoavbls/pretty-ts-errors/assets/assets/mentions/theo-dark.png">
60-
<img width="400" src="https://raw.githubusercontent.com/yoavbls/pretty-ts-errors/assets/assets/mentions/theo-light.png">
59+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/yoavbls/pretty-ts-errors/assets/assets/mentions/theo-light.pn#gh-light-mode-only">
60+
<img width="400" src="https://raw.githubusercontent.com/yoavbls/pretty-ts-errors/assets/assets/mentions/theo-dark.png#gh-dark-mode-only">
6161
</picture>
6262
</a>
6363
<a href="https://twitter.com/johnsoncodehk/status/1646214711204286465">
6464
<picture>
65-
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/yoavbls/pretty-ts-errors/assets/assets/mentions/johnson-dark.png">
66-
<img width="400" src="https://raw.githubusercontent.com/yoavbls/pretty-ts-errors/assets/assets/mentions/johnson-light.png">
65+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/yoavbls/pretty-ts-errors/assets/assets/mentions/johnson-light.png#gh-light-mode-only">
66+
<img width="400" src="https://raw.githubusercontent.com/yoavbls/pretty-ts-errors/assets/assets/mentions/johnson-dark.png#gh-dark-mode-only">
6767
</picture>
6868
</a>
6969
<a href="https://twitter.com/tannerlinsley/status/1647982562026090496">
7070
<picture>
71-
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/yoavbls/pretty-ts-errors/assets/assets/mentions/tanner-dark.png">
72-
<img width="400" src="https://raw.githubusercontent.com/yoavbls/pretty-ts-errors/assets/assets/mentions/tanner-light.png">
71+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/yoavbls/pretty-ts-errors/assets/assets/mentions/tanner-light.png#gh-light-mode-only">
72+
<img width="400" src="https://raw.githubusercontent.com/yoavbls/pretty-ts-errors/assets/assets/mentions/tanner-dark.png#gh-dark-mode-only">
7373
</picture>
7474
</a>
7575

package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
},
1212
"homepage": "https://github.com/yoavbls/pretty-ts-errors",
1313
"engines": {
14-
"vscode": "^1.70.0"
14+
"vscode": "^1.77.0"
1515
},
1616
"categories": [
1717
"Programming Languages",
@@ -54,7 +54,7 @@
5454
"scripts": {
5555
"vscode:prepublish": "npm run package",
5656
"compile": "node scripts/build",
57-
"watch": "npm run compile --watch",
57+
"watch": "npm run compile -- --watch",
5858
"build": "vsce package",
5959
"package": "node scripts/build -- --production",
6060
"compile-tests": "tsc -p . --outDir out",
@@ -77,7 +77,6 @@
7777
"eslint": "^8.20.0",
7878
"glob": "^8.0.3",
7979
"mocha": "^10.0.0",
80-
"ts-loader": "^9.3.1",
8180
"typescript": "^5.0.4"
8281
},
8382
"dependencies": {

src/components/title.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export const title = (diagnostic: Diagnostic) => d/*html*/ `
1414
`
1515
: ""
1616
}
17+
<br>
1718
<span>
1819
1920
`;

src/extension.ts

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,20 @@ import {
55
Range,
66
window,
77
} from "vscode";
8+
import { createConverter } from "vscode-languageclient/lib/common/codeConverter";
89
import { formatDiagnostic } from "./format/formatDiagnostic";
10+
import { prettify } from "./format/prettify";
911
import { hoverProvider } from "./provider/hoverProvider";
12+
import { registerSelectedTextHoverProvider } from "./provider/selectedTextHoverProvider";
1013
import { uriStore } from "./provider/uriStore";
1114
import { has } from "./utils";
12-
import { createConverter } from "vscode-languageclient/lib/common/codeConverter";
13-
import { format } from "prettier";
1415

1516
export function activate(context: ExtensionContext) {
1617
const registeredLanguages = new Set<string>();
1718
const converter = createConverter();
1819

20+
registerSelectedTextHoverProvider(context);
21+
1922
context.subscriptions.push(
2023
languages.onDidChangeDiagnostics(async (e) => {
2124
e.uris.forEach((uri) => {
@@ -35,10 +38,11 @@ export function activate(context: ExtensionContext) {
3538
: false
3639
)
3740
.forEach(async (diagnostic) => {
38-
3941
// formatDiagnostic converts message based on LSP Diagnostic type, not VSCode Diagnostic type, so it can be used in other IDEs.
4042
// Here we convert VSCode Diagnostic to LSP Diagnostic to make formatDiagnostic recognize it.
41-
const markdownString = new MarkdownString(formatDiagnostic(converter.asDiagnostic(diagnostic), prettify));
43+
const markdownString = new MarkdownString(
44+
formatDiagnostic(converter.asDiagnostic(diagnostic), prettify)
45+
);
4246

4347
markdownString.isTrusted = true;
4448
markdownString.supportHtml = true;
@@ -51,7 +55,7 @@ export function activate(context: ExtensionContext) {
5155
});
5256
uriStore[uri.path] = items;
5357

54-
if (hasTsDiagnostic && uri.scheme === "file") {
58+
if (hasTsDiagnostic) {
5559
const editor = window.visibleTextEditors.find(
5660
(editor) => editor.document.uri.toString() === uri.toString()
5761
);
@@ -60,7 +64,6 @@ export function activate(context: ExtensionContext) {
6064
context.subscriptions.push(
6165
languages.registerHoverProvider(
6266
{
63-
scheme: "file",
6467
language: editor.document.languageId,
6568
},
6669
hoverProvider
@@ -72,12 +75,3 @@ export function activate(context: ExtensionContext) {
7275
})
7376
);
7477
}
75-
76-
function prettify(text: string) {
77-
return format(text, {
78-
parser: "typescript",
79-
printWidth: 60,
80-
singleAttributePerLine: false,
81-
arrowParens: "avoid",
82-
});
83-
}

src/format/formatDiagnosticMessage.ts

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ const formatTypeScriptBlock = (_: string, code: string) =>
77
const formatSimpleTypeBlock = (_: string, code: string) =>
88
inlineCodeBlock(code, "type");
99

10-
const formatTypeOrModuleBlock = (_: string, prefix: string, code: string, format: (type: string) => string) =>
10+
const formatTypeOrModuleBlock = (
11+
_: string,
12+
prefix: string,
13+
code: string,
14+
format: (type: string) => string
15+
) =>
1116
formatTypeBlock(
1217
prefix,
1318
["module", "file", "file name"].includes(prefix.toLowerCase())
@@ -16,7 +21,10 @@ const formatTypeOrModuleBlock = (_: string, prefix: string, code: string, format
1621
format
1722
);
1823

19-
export const formatDiagnosticMessage = (message: string, format: (type: string) => string) =>
24+
export const formatDiagnosticMessage = (
25+
message: string,
26+
format: (type: string) => string
27+
) =>
2028
message
2129
// format declare module snippet
2230
.replaceAll(
@@ -26,9 +34,9 @@ export const formatDiagnosticMessage = (message: string, format: (type: string)
2634
)
2735
// format missing props error
2836
.replaceAll(
29-
/(is missing the following properties from type .*: )(.+?)(?=and|$)/g,
30-
(_, pre, post) =>
31-
`${pre}<ul>${post
37+
/(is missing the following properties from type )'(.*)': (.+?)(?=and|$)/g,
38+
(_, pre, type, post) =>
39+
`${pre}${formatTypeBlock("", type, format)}: <ul>${post
3240
.split(", ")
3341
.filter(Boolean)
3442
.map((prop: string) => `<li>${prop}</li>`)
@@ -38,13 +46,21 @@ export const formatDiagnosticMessage = (message: string, format: (type: string)
3846
.replaceAll(
3947
/(types) '(.*?)' and '(.*?)'[\.]?/gi,
4048
(_: string, p1: string, p2: string, p3: string) =>
41-
`${formatTypeBlock(p1, p2, format)} and ${formatTypeBlock("", p3, format)}`
49+
`${formatTypeBlock(p1, p2, format)} and ${formatTypeBlock(
50+
"",
51+
p3,
52+
format
53+
)}`
4254
)
4355
// Format type annotation options
4456
.replaceAll(
4557
/type annotation must be '(.*?)' or '(.*?)'[\.]?/gi,
4658
(_: string, p1: string, p2: string, p3: string) =>
47-
`${formatTypeBlock(p1, p2, format)} or ${formatTypeBlock("", p3, format)}`
59+
`${formatTypeBlock(p1, p2, format)} or ${formatTypeBlock(
60+
"",
61+
p3,
62+
format
63+
)}`
4864
)
4965
.replaceAll(
5066
/(Overload \d of \d), '(.*?)', /gi,
@@ -54,7 +70,7 @@ export const formatDiagnosticMessage = (message: string, format: (type: string)
5470
.replaceAll(/^'"[^"]*"'$/g, formatTypeScriptBlock)
5571
// Format types
5672
.replaceAll(
57-
/(type|type alias|interface|module|file|file name) '(.*?)'(?=[\s.])/gi,
73+
/(type|type alias|interface|module|file|file name|method's) '(.*?)'(?=[\s.])/gi,
5874
(_, p1: string, p2: string) => formatTypeOrModuleBlock(_, p1, p2, format)
5975
)
6076
// Format reversed types
@@ -80,6 +96,7 @@ export const formatDiagnosticMessage = (message: string, format: (type: string)
8096
(_, p1: string, p2: string) => `${p1} ${formatTypeScriptBlock("", p2)}`
8197
)
8298
// Format regular code blocks
83-
.replaceAll(/'((?:(?!:\s*}).)*?)'(?!\s*:)/g, (_: string, p1: string) => unstyledCodeBlock(p1));
84-
85-
99+
.replaceAll(
100+
/'((?:(?!:\s*}).)*?)' (?!\s*:)/g,
101+
(_: string, p1: string) => `${unstyledCodeBlock(p1)} `
102+
);

src/format/formatTypeBlock.ts

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import {
55
} from "../components";
66
import { addMissingParentheses } from "./addMissingParentheses";
77

8-
export function formatTypeBlock(prefix: string, type: string, format: (type: string) => string) {
8+
export function formatTypeBlock(
9+
prefix: string,
10+
type: string,
11+
format: (type: string) => string
12+
) {
913
// Return a simple code block if it's just a parenthesis
1014
if (type.match(/^(\[\]|\{\})$/)) {
1115
return `${prefix} ${unstyledCodeBlock(type)}`;
@@ -20,7 +24,7 @@ export function formatTypeBlock(prefix: string, type: string, format: (type: str
2024
return `${prefix} ${inlineCodeBlock(type, "type")}`;
2125
}
2226

23-
const prettyType = convertToOriginalType(prettifyType(convertToValidType(type), format));
27+
const prettyType = prettifyType(type, format);
2428

2529
if (prettyType.includes("\n")) {
2630
return `${prefix}: ${multiLineCodeBlock(prettyType, "type")}`;
@@ -31,13 +35,18 @@ export function formatTypeBlock(prefix: string, type: string, format: (type: str
3135
/**
3236
* Try to make type prettier with prettier
3337
*/
34-
function prettifyType(type: string, format: (type: string) => string) {
38+
export function prettifyType(
39+
type: string,
40+
format: (type: string) => string,
41+
options?: { throwOnError?: boolean }
42+
) {
3543
try {
3644
// Wrap type with valid statement, format it and extract the type back
37-
return convertToOriginalType(
38-
format(convertToValidType(type))
39-
);
45+
return convertToOriginalType(format(convertToValidType(type)));
4046
} catch (e) {
47+
if (options?.throwOnError) {
48+
throw e;
49+
}
4150
return type;
4251
}
4352
}
@@ -47,7 +56,7 @@ const convertToValidType = (type: string) =>
4756
// Add missing parentheses when the type ends with "...""
4857
.replace(/(.*)\.\.\.$/, (_, p1) => addMissingParentheses(p1))
4958
// Replace single parameter function destructuring because it's not a valid type
50-
.replaceAll(/\((\{.*\})\:/g, (_, p1) => `(param: /* ${p1} */`)
59+
// .replaceAll(/\((\{.*\})\:/g, (_, p1) => `(param: /* ${p1} */`)
5160
// Change `(...): return` which is invalid to `(...) => return`
5261
.replace(/^(\(.*\)): /, (_, p1) => `${p1} =>`)
5362
.replaceAll(/... (\d{0,}) more .../g, (_, p1) => `___${p1}MORE___`)
@@ -62,6 +71,6 @@ const convertToOriginalType = (type: string) =>
6271
.replaceAll(/___MORE___: (\d{0,});/g, (_, p1) => `... ${p1} more ...;`)
6372
.replaceAll(/___(\d{0,})MORE___/g, (_, p1) => `... ${p1} more ...`)
6473
.replaceAll(/... (\d{0,}) more .../g, (_, p1) => `/* ${p1} more */`) // ... x more ... not shown sell
65-
.replaceAll(/\(param\: \/\* (\{ .* \}) \*\//g, (_, p1) => `(${p1}: `)
74+
// .replaceAll(/\(param\: \/\* (\{ .* \}) \*\//g, (_, p1) => `(${p1}: `)
6675
.replace(/type x =[ ]?((.|\n)*);.*/g, "$1")
6776
.trim();

src/format/prettify.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { format } from "prettier";
2+
3+
export function prettify(text: string) {
4+
return format(text, {
5+
parser: "typescript",
6+
printWidth: 60,
7+
singleAttributePerLine: false,
8+
arrowParens: "avoid",
9+
});
10+
}

0 commit comments

Comments
 (0)