diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100755
index 0000000..9612267
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,37 @@
+{
+ "version": "0.2.0",
+ // List of configurations. Add new configurations or edit existing ones.
+ "configurations": [
+ {
+ "type": "extensionHost",
+ "request": "launch",
+ "name": "Launch Client",
+ "runtimeExecutable": "${execPath}",
+ "args": ["--extensionDevelopmentPath=${workspaceRoot}"],
+ "stopOnEntry": false,
+ "sourceMaps": true,
+ "outFiles": ["${workspaceRoot}/dist/extension/**/*.js"],
+ // "preLaunchTask": "npm: dev"
+ },
+ {
+ "type": "node",
+ "request": "attach",
+ "name": "Attach to Server 6011",
+ "address": "localhost",
+ "protocol": "inspector",
+ "port": 6011,
+ "sourceMaps": true,
+ "outFiles": ["${workspaceRoot}/dist/server/**/*.js"]
+ },
+ {
+ "type": "node",
+ "request": "attach",
+ "name": "Attach to Server 6012",
+ "address": "localhost",
+ "protocol": "inspector",
+ "port": 6012,
+ "sourceMaps": true,
+ "outFiles": ["${workspaceRoot}/dist/server/**/*.js"]
+ }
+ ]
+}
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100755
index 0000000..4b2d95f
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,29 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "type": "npm",
+ "script": "build",
+ "group": "build",
+ "presentation": {
+ "panel": "dedicated",
+ "reveal": "never"
+ },
+ "problemMatcher": ["$tsc"]
+ },
+ {
+ "type": "npm",
+ "script": "dev",
+ "isBackground": true,
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ },
+ "presentation": {
+ "panel": "dedicated",
+ "reveal": "never"
+ },
+ "problemMatcher": ["$tsc-watch"]
+ }
+ ]
+}
diff --git a/.vscodeignore b/.vscodeignore
index 97c56c3..eef67fb 100755
--- a/.vscodeignore
+++ b/.vscodeignore
@@ -7,3 +7,4 @@
contributing.md
node_modules/**
src/**
+tests/**
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..f8bf3f3
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,75 @@
+# Changelog
+
+## 0.3.0
+
+### General
+
+- Added support for string values in Tailwind's `important` option (#96)
+- Removed all unnecessary logs (#91)
+- Added support for components in addition to utilities (#67)
+- Added description to custom variant completion items where possible
+- Config parsing errors are now displayed in the VS Code UI
+- Class names from `@tailwind base` are now included (by default `@tailwind base` does not include any class names but plugins may contribute them)
+- Color swatches can now be displayed for rules with multiple properties and/or colors with variable alpha (#113)
+- Added `tailwindCSS.includeLanguages` setting:
+ ```json
+ {
+ "tailwindCSS.includeLanguages": {
+ "plaintext": "html"
+ }
+ }
+ ```
+ This setting allows you to add additional language support. The key of each entry is the new language ID and the value is any one of the extensions built-in languages, depending on how you want the new language to be treated (e.g. `html`, `css`, or `javascript`)
+
+### HTML
+
+- Added built-in support for `liquid`, `aspnetcorerazor`, `mustache`, `HTML (EEx)`, `html-eex`, `gohtml`, `GoHTML`, and `hbs` languages
+- Added syntax definition to embedded stylesheets in HTML files
+
+### CSS
+
+- Added built-in support for `sugarss` language
+- Added `theme` (and `config`) helper hovers
+- Added `@apply` class name hovers
+- Added directive completion items with links to documentation
+- Added `@tailwind` completion items (`preflight`/`base`, `utilities`, `components`, `screens`) with links to documentation
+- Helper completion items that contain the `.` character will now insert square brackets when selected
+- `@apply` completion list now excludes class names that are not compatible
+- Added CSS syntax highlighting in `.vue` files (#15)
+
+### JS(X)
+
+- Completions now trigger when using backticks (#50, #93):
+ ```js
+ const App = () =>
+
+ **After:**
+
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..27cc6e8
--- /dev/null
+++ b/README.md
@@ -0,0 +1,81 @@
+# Tailwind CSS IntelliSense
+
+> [Tailwind CSS](https://tailwindcss.com/) class name completion for VS Code
+
+**[Get it from the VS Code Marketplace →](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss)**
+
+
+
+## Requirements
+
+This extension requires:
+- a `tailwind.config.js` file to be [present in your project folder](https://github.com/bradlc/vscode-tailwindcss/blob/master/package.json#L38). You can create it with `npx tailwind init`.
+- `tailwindcss` to be installed (present in project `node_modules/`)
+
+## Features
+
+Tailwind CSS IntelliSense uses your projects Tailwind installation and configuration to provide suggestions as you type.
+
+It also includes features that improve the overall Tailwind experience, including improved syntax highlighting, and CSS previews.
+
+### HTML (including Vue, JSX, PHP etc.)
+
+- [Class name suggestions, including support for Emmet syntax](#class-name-suggestions-including-support-for-emmet-syntax)
+ - Suggestions include color previews where applicable, for example for text and background colors
+ - They also include a preview of the actual CSS for that class name
+- [CSS preview when hovering over class names](#css-preview-when-hovering-over-class-names)
+
+### CSS
+
+- [Suggestions when using `@apply` and config helpers](#suggestions-when-using-apply-and-config)
+- Suggestions when using the `@screen` directive
+- Suggestions when using the `@variants` directive
+- [Improves syntax highlighting when using `@apply` and config helpers](#improves-syntax-highlighting-when-using-apply-and-config-helpers)
+
+## Examples
+
+#### Class name suggestions, including support for Emmet syntax
+
+
+
+#### CSS preview when hovering over class names
+
+
+
+#### Suggestions when using `@apply` and config helpers
+
+
+
+#### Improves syntax highlighting when using `@apply` and config helpers
+
+Before:
+
+
+
+After:
+
+
+
+## Settings
+
+### `tailwindCSS.includeLanguages`
+
+This setting allows you to add additional language support. The key of each entry is the new language ID and the value is any one of the extensions built-in languages, depending on how you want the new language to be treated (e.g. `html`, `css`, or `javascript`):
+
+```json
+{
+ "tailwindCSS.includeLanguages": {
+ "plaintext": "html"
+ }
+}
+```
+
+### `tailwindcss.emmetCompletions`
+
+Enable completions when using [Emmet](https://emmet.io/)-style syntax, for example `div.bg-red-500.uppercase`. **Default: `false`**
+
+```json
+{
+ "tailwindCSS.emmetCompletions": true
+}
+```
diff --git a/package-lock.json b/package-lock.json
index f844afb..9f6cc9e 100755
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "vscode-tailwindcss",
- "version": "0.3.0-alpha.2",
+ "version": "0.3.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -4845,9 +4845,9 @@
},
"dependencies": {
"entities": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz",
- "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz",
+ "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==",
"dev": true
}
}
@@ -6896,9 +6896,9 @@
}
},
"vsce": {
- "version": "1.75.0",
- "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.75.0.tgz",
- "integrity": "sha512-qyAQTmolxKWc9bV1z0yBTSH4WEIWhDueBJMKB0GUFD6lM4MiaU1zJ9BtzekUORZu094YeNSKz0RmVVuxfqPq0g==",
+ "version": "1.76.1",
+ "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.76.1.tgz",
+ "integrity": "sha512-WNx6JzRywxAOuhVpjmrsI0eHMK0mCA0YKD8u++7sprmhwCHsoQIBpSf0vp6kVMHBmafknr1Z6K7IC5jIjsNL9Q==",
"dev": true,
"requires": {
"azure-devops-node-api": "^7.2.0",
diff --git a/package.json b/package.json
index 0b515ca..456a3dc 100755
--- a/package.json
+++ b/package.json
@@ -5,10 +5,15 @@
"preview": true,
"author": "Brad Cornes ",
"license": "MIT",
- "version": "0.3.0-alpha.2",
+ "version": "0.3.0",
+ "homepage": "https://github.com/bradlc/vscode-tailwindcss",
+ "bugs": {
+ "url": "https://github.com/bradlc/vscode-tailwindcss/issues",
+ "email": "hello@bradley.dev"
+ },
"repository": {
"type": "git",
- "url": "https://github.com/bradlc/"
+ "url": "https://github.com/bradlc/vscode-tailwindcss.git"
},
"publisher": "bradlc",
"keywords": [
@@ -55,11 +60,12 @@
"tailwindCSS.emmetCompletions": {
"type": "boolean",
"default": false,
- "description": ""
+ "description": "Enable class name completions when using Emmet-style syntax, for example `div.bg-red-500.uppercase`."
},
"tailwindCSS.includeLanguages": {
"type": "object",
- "default": {}
+ "default": {},
+ "description": "Enable features in languages that are not supported by default. Add a mapping here between the new language and an already supported language.\n E.g.: `{\"plaintext\": \"html\"}`"
}
}
}
@@ -106,7 +112,7 @@
"tiny-invariant": "^1.1.0",
"tslint": "^5.16.0",
"typescript": "^3.8.3",
- "vsce": "^1.75.0",
+ "vsce": "^1.76.1",
"vscode-emmet-helper-bundled": "0.0.1",
"vscode-languageclient": "^5.2.1",
"vscode-languageserver": "^5.2.1",
diff --git a/src/class-names/runPlugin.js b/src/class-names/runPlugin.js
index dbdd2b5..118961e 100644
--- a/src/class-names/runPlugin.js
+++ b/src/class-names/runPlugin.js
@@ -17,6 +17,12 @@ export function runPlugin(plugin, params = {}) {
theme: (path, defaultValue) => dlv(config, `theme.${path}`, defaultValue),
variants: () => [],
config: (path, defaultValue) => dlv(config, path, defaultValue),
+ corePlugins: (path) => {
+ if (Array.isArray(config.corePlugins)) {
+ return config.corePlugins.includes(path)
+ }
+ return dlv(config, `corePlugins.${path}`, true)
+ },
target: (path) => {
if (typeof config.target === 'string') {
return config.target === 'browserslist'
diff --git a/src/lib/languages.ts b/src/lib/languages.ts
index 777f588..0b9c450 100644
--- a/src/lib/languages.ts
+++ b/src/lib/languages.ts
@@ -6,6 +6,8 @@ export const DEFAULT_LANGUAGES = [
'edge',
'ejs',
'erb',
+ 'gohtml',
+ 'GoHTML',
'haml',
'handlebars',
'hbs',
diff --git a/src/lsp/util/find.ts b/src/lsp/util/find.ts
index 800d0a3..6b1bfca 100644
--- a/src/lsp/util/find.ts
+++ b/src/lsp/util/find.ts
@@ -1,10 +1,10 @@
import { TextDocument, Range, Position } from 'vscode-languageserver'
import { DocumentClassName, DocumentClassList, State } from './state'
import lineColumn from 'line-column'
-import { isCssContext } from './css'
-import { isHtmlContext } from './html'
+import { isCssContext, isCssDoc } from './css'
+import { isHtmlContext, isHtmlDoc, isSvelteDoc, isVueDoc } from './html'
import { isWithinRange } from './isWithinRange'
-import { isJsContext } from './js'
+import { isJsContext, isJsDoc } from './js'
import { getClassAttributeLexer } from './lexers'
export function findAll(re: RegExp, str: string): RegExpMatchArray[] {
@@ -83,11 +83,13 @@ export function findClassListsInCssRange(
range: {
start: {
line: globalStart.line + start.line,
- character: globalStart.character + start.character,
+ character:
+ (end.line === 0 ? globalStart.character : 0) + start.character,
},
end: {
line: globalStart.line + end.line,
- character: globalStart.character + end.character,
+ character:
+ (end.line === 0 ? globalStart.character : 0) + end.character,
},
},
}
@@ -173,11 +175,14 @@ export function findClassListsInHtmlRange(
range: {
start: {
line: range.start.line + start.line,
- character: range.start.character + start.character,
+ character:
+ (end.line === 0 ? range.start.character : 0) +
+ start.character,
},
end: {
line: range.start.line + end.line,
- character: range.start.character + end.character,
+ character:
+ (end.line === 0 ? range.start.character : 0) + end.character,
},
},
}
@@ -200,6 +205,80 @@ export function findClassListsInRange(
return findClassListsInHtmlRange(doc, range)
}
+export function findClassListsInDocument(
+ state: State,
+ doc: TextDocument
+): DocumentClassList[] {
+ if (isCssDoc(state, doc)) {
+ return findClassListsInCssRange(doc)
+ }
+
+ if (isVueDoc(doc)) {
+ let text = doc.getText()
+ let blocks = findAll(
+ /<(?template|style|script)\b[^>]*>.*?(<\/\k>|$)/gis,
+ text
+ )
+ let htmlRanges: Range[] = []
+ let cssRanges: Range[] = []
+ for (let i = 0; i < blocks.length; i++) {
+ let range = {
+ start: indexToPosition(text, blocks[i].index),
+ end: indexToPosition(text, blocks[i].index + blocks[i][0].length),
+ }
+ if (blocks[i].groups.type === 'style') {
+ cssRanges.push(range)
+ } else {
+ htmlRanges.push(range)
+ }
+ }
+ return [].concat.apply(
+ [],
+ [
+ ...htmlRanges.map((range) => findClassListsInHtmlRange(doc, range)),
+ ...cssRanges.map((range) => findClassListsInCssRange(doc, range)),
+ ]
+ )
+ }
+
+ if (isHtmlDoc(state, doc) || isJsDoc(state, doc) || isSvelteDoc(doc)) {
+ let text = doc.getText()
+ let styleBlocks = findAll(/