Skip to content

Commit

Permalink
v0.9.2 Add options to disable highlighting from name and attributes (#81
Browse files Browse the repository at this point in the history
)
  • Loading branch information
vincaslt committed May 29, 2019
1 parent e1f9e92 commit bb38046
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 46 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
@@ -1,6 +1,10 @@
# Change Log
All notable changes to the "higlight-matching-tag" extension will be documented in this file.

### 0.9.2

* New configuration options: `highlightFromName` and `hightlightFromAttributes`

### 0.9.1

* Allow customization of empty elements via configuration options.
Expand Down
22 changes: 12 additions & 10 deletions README.md
Expand Up @@ -27,16 +27,18 @@ Other flavors (vue, php, angular) should work, but there are no guarantees. Feel

You can override any default [settings](https://code.visualstudio.com/docs/getstarted/settings) with your own values. The plugin supports [workspace settings](https://code.visualstudio.com/docs/editor/multi-root-workspaces) as well as global user settings.

| Variable | Default | Description |
| ----------------------------------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------- |
| `highlight-matching-tag.enabled` | `true` | Enables/disables the highlighting and status bar |
| `highlight-matching-tag.showPath` | `true` | Enables/disables showing path to tag in status bar (e.g. `div > p > a`) |
| `highlight-matching-tag.showRuler` | `true` | Enables/disables showing highlighted tag pair in ruler section |
| `highlight-matching-tag.highlightSelfClosing` | `false` | Should self-closing tags be highlighted too (can be useful for multiline self-closing tags) |
| `highlight-matching-tag.highlightFromContent` | `false` | Whether to highlight from the tag content the closest matching tag pair |
| `highlight-matching-tag.noDefaultEmptyElements` | `false` | Don't use default HTML empty elements |
| `highlight-matching-tag.customEmptyElements` | `null` | Custom [empty elements](#empty-elements) in addition to the default HTML empty elements |
| `highlight-matching-tag.styles` | `{ opening: { name: { underline: 'yellow' } } }` | Custom styling configuration, see [Styling Options](#styling-options) |
| Variable | Default | Description |
| ------------------------------------------------ | ------------------------------------------------ | ------------------------------------------------------------------------------------------- |
| `highlight-matching-tag.enabled` | `true` | Enables/disables the highlighting and status bar |
| `highlight-matching-tag.showPath` | `true` | Enables/disables showing path to tag in status bar (e.g. `div > p > a`) |
| `highlight-matching-tag.showRuler` | `true` | Enables/disables showing highlighted tag pair in ruler section |
| `highlight-matching-tag.highlightSelfClosing` | `false` | Should self-closing tags be highlighted too (can be useful for multiline self-closing tags) |
| `highlight-matching-tag.highlightFromContent` | `false` | Whether to highlight matching tag from inside the tag content |
| `highlight-matching-tag.highlightFromName` | `true` | Whether to highlight matching tag from the tag name |
| `highlight-matching-tag.highlightFromAttributes` | `true` | Whether to highlight matching tag from the tag attributes |
| `highlight-matching-tag.noDefaultEmptyElements` | `false` | Don't use default HTML empty elements |
| `highlight-matching-tag.customEmptyElements` | `null` | Custom [empty elements](#empty-elements) in addition to the default HTML empty elements |
| `highlight-matching-tag.styles` | `{ opening: { name: { underline: 'yellow' } } }` | Custom styling configuration, see [Styling Options](#styling-options) |

## Styling Options

Expand Down
16 changes: 14 additions & 2 deletions package.json
Expand Up @@ -2,7 +2,7 @@
"name": "highlight-matching-tag",
"displayName": "Highlight Matching Tag",
"description": "Highlights matching closing or opening tag",
"version": "0.9.1",
"version": "0.9.2",
"publisher": "vincaslt",
"icon": "icon.png",
"repository": {
Expand Down Expand Up @@ -57,7 +57,19 @@
"highlight-matching-tag.highlightFromContent": {
"type": "boolean",
"default": false,
"description": "Whether to highlight from the tag content the closest matching tag pair",
"description": "Whether to highlight matching tag from inside the tag content",
"scope": "resource"
},
"highlight-matching-tag.highlightFromName": {
"type": "boolean",
"default": true,
"description": "Whether to highlight matching tag from the tag name",
"scope": "resource"
},
"highlight-matching-tag.highlightFromAttributes": {
"type": "boolean",
"default": true,
"description": "Whether to highlight matching tag from the tag attributes",
"scope": "resource"
},
"highlight-matching-tag.noDefaultEmptyElements": {
Expand Down
8 changes: 7 additions & 1 deletion src/commands.ts
@@ -1,4 +1,5 @@
import * as vscode from 'vscode'
import config from './configuration'
import { findMatchingTag, getTagForPosition } from './tagMatcher'
import { parseTags } from './tagParser'

Expand All @@ -13,7 +14,12 @@ export async function jumpToMatchingTag() {
const position = editor.selection.active
const positionOffset = editor.document.offsetAt(position)

const match = findMatchingTag(tagsList, positionOffset)
const match = findMatchingTag(
tagsList,
positionOffset,
config.highlightFromName,
config.highlightFromAttributes
)

if (match) {
const openingTagStartPos = editor.document.positionAt(match.opening.start)
Expand Down
8 changes: 8 additions & 0 deletions src/configuration.ts
Expand Up @@ -43,6 +43,14 @@ class Configuration {
return !!this.config.get('highlightFromContent')
}

get highlightFromName() {
return !!this.config.get('highlightFromName')
}

get highlightFromAttributes() {
return !!this.config.get('highlightFromAttributes')
}

get showPath() {
return !!this.config.get('showPath')
}
Expand Down
9 changes: 8 additions & 1 deletion src/extension.ts
Expand Up @@ -111,7 +111,14 @@ export function activate(context: vscode.ExtensionContext) {
.filter(match => match !== undefined)
} else {
matches = editor.selections
.map(sel => findMatchingTag(tagsList, editor.document.offsetAt(sel.active)))
.map(sel =>
findMatchingTag(
tagsList,
editor.document.offsetAt(sel.active),
config.highlightFromName,
config.highlightFromAttributes
)
)
.filter(
match => match && (match.opening !== match.closing || config.highlightSelfClosing)
)
Expand Down
30 changes: 24 additions & 6 deletions src/tagMatcher.ts
Expand Up @@ -10,14 +10,32 @@ function isTagPairValid(pair: hmt.PartialMatch): boolean {

export function findMatchingTag(
tagsList: hmt.PartialMatch[],
position: number
position: number,
matchFromName: boolean,
matchFromAttributes: boolean
): hmt.Match | undefined {
for (let i = tagsList.length - 1; i >= 0; i--) {
if (
isTagPairValid(tagsList[i]) &&
((position > tagsList[i].opening!.start! && position < tagsList[i].opening!.end!) ||
(position > tagsList[i].closing!.start! && position < tagsList[i].closing!.end!))
) {
if (!isTagPairValid(tagsList[i])) {
continue
}

const openingStart = tagsList[i].opening!.start!
const openingEnd = tagsList[i].opening!.end!
const closingStart = tagsList[i].closing!.start!
const closingEnd = tagsList[i].closing!.end!

const positionInName =
(position > openingStart &&
position <= openingStart + tagsList[i].opening!.name!.length + 1) ||
(position > closingStart + 1 &&
position <= closingStart + tagsList[i].closing!.name!.length + 2)

const positionInAttributes =
!positionInName &&
((position > openingStart && position < openingEnd) ||
(position > closingStart && position < closingEnd))

if ((positionInName && matchFromName) || (positionInAttributes && matchFromAttributes)) {
return {
attributeNestingLevel: tagsList[i].attributeNestingLevel,
opening: tagsList[i].opening as hmt.Tag,
Expand Down
52 changes: 26 additions & 26 deletions test/tagMatcher.test.ts
Expand Up @@ -11,15 +11,15 @@ suite('TagMatcher Tests', () => {
opening: { name: 'a', start: 0, end: 3 },
closing: { name: 'a', start: 4, end: 8 }
}
assert.deepEqual(findMatchingTag(data, 0), undefined)
assert.deepEqual(findMatchingTag(data, 1), expected)
assert.deepEqual(findMatchingTag(data, 2), expected)
assert.deepEqual(findMatchingTag(data, 3), undefined)
assert.deepEqual(findMatchingTag(data, 4), undefined)
assert.deepEqual(findMatchingTag(data, 5), expected)
assert.deepEqual(findMatchingTag(data, 6), expected)
assert.deepEqual(findMatchingTag(data, 7), expected)
assert.deepEqual(findMatchingTag(data, 8), undefined)
assert.deepEqual(findMatchingTag(data, 0, true, true), undefined)
assert.deepEqual(findMatchingTag(data, 1, true, true), expected)
assert.deepEqual(findMatchingTag(data, 2, true, true), expected)
assert.deepEqual(findMatchingTag(data, 3, true, true), undefined)
assert.deepEqual(findMatchingTag(data, 4, true, true), undefined)
assert.deepEqual(findMatchingTag(data, 5, true, true), expected)
assert.deepEqual(findMatchingTag(data, 6, true, true), expected)
assert.deepEqual(findMatchingTag(data, 7, true, true), expected)
assert.deepEqual(findMatchingTag(data, 8, true, true), undefined)
})

test('can match nested with invalid tags', () => {
Expand All @@ -29,31 +29,31 @@ suite('TagMatcher Tests', () => {
opening: { name: 'b', start: 3, end: 6 },
closing: { name: 'b', start: 10, end: 14 }
}
assert.deepEqual(findMatchingTag(data, 0), undefined)
assert.deepEqual(findMatchingTag(data, 4), expected)
assert.deepEqual(findMatchingTag(data, 12), expected)
assert.deepEqual(findMatchingTag(data, 1), undefined)
assert.deepEqual(findMatchingTag(data, 8), undefined)
assert.deepEqual(findMatchingTag(data, 0, true, true), undefined)
assert.deepEqual(findMatchingTag(data, 4, true, true), expected)
assert.deepEqual(findMatchingTag(data, 12, true, true), expected)
assert.deepEqual(findMatchingTag(data, 1, true, true), undefined)
assert.deepEqual(findMatchingTag(data, 8, true, true), undefined)
})

test('does not match unclosed tags', () => {
const data = parseTags('<a>a')
assert.deepEqual(findMatchingTag(data, 0), undefined)
assert.deepEqual(findMatchingTag(data, 1), undefined)
assert.deepEqual(findMatchingTag(data, 2), undefined)
assert.deepEqual(findMatchingTag(data, 3), undefined)
assert.deepEqual(findMatchingTag(data, 4), undefined)
assert.deepEqual(findMatchingTag(data, 0, true, true), undefined)
assert.deepEqual(findMatchingTag(data, 1, true, true), undefined)
assert.deepEqual(findMatchingTag(data, 2, true, true), undefined)
assert.deepEqual(findMatchingTag(data, 3, true, true), undefined)
assert.deepEqual(findMatchingTag(data, 4, true, true), undefined)
})

test('does not match unfinished opening tags', () => {
const data = parseTags('<a</a>')
assert.deepEqual(findMatchingTag(data, 0), undefined)
assert.deepEqual(findMatchingTag(data, 1), undefined)
assert.deepEqual(findMatchingTag(data, 2), undefined)
assert.deepEqual(findMatchingTag(data, 3), undefined)
assert.deepEqual(findMatchingTag(data, 4), undefined)
assert.deepEqual(findMatchingTag(data, 5), undefined)
assert.deepEqual(findMatchingTag(data, 6), undefined)
assert.deepEqual(findMatchingTag(data, 0, true, true), undefined)
assert.deepEqual(findMatchingTag(data, 1, true, true), undefined)
assert.deepEqual(findMatchingTag(data, 2, true, true), undefined)
assert.deepEqual(findMatchingTag(data, 3, true, true), undefined)
assert.deepEqual(findMatchingTag(data, 4, true, true), undefined)
assert.deepEqual(findMatchingTag(data, 5, true, true), undefined)
assert.deepEqual(findMatchingTag(data, 6, true, true), undefined)
})
})

Expand Down

0 comments on commit bb38046

Please sign in to comment.