@@ -7,90 +7,104 @@ import * as vscode from 'vscode';
77import { getNode , getDeepestNode , findNextWord , findPrevWord } from './util' ;
88import Node from '@emmetio/node' ;
99
10- export function nextItemHTML ( selection : vscode . Selection , editor : vscode . TextEditor , rootNode : Node ) : vscode . Selection {
11- let offset = editor . document . offsetAt ( selection . active ) ;
12- let currentNode = getNode ( rootNode , offset ) ;
10+ export function nextItemHTML ( selectionStart : number , selectionEnd : number , editor : vscode . TextEditor , rootNode : Node ) : vscode . Selection {
11+ let currentNode = getNode ( rootNode , selectionEnd ) ;
12+ let nextNode : Node ;
13+
14+ if ( currentNode . type !== 'comment' ) {
15+ // If cursor is in the tag name, select tag
16+ if ( selectionEnd < currentNode . open . start + currentNode . name . length ) {
17+ return getSelectionFromNode ( currentNode , editor . document ) ;
18+ }
1319
14- // Cursor is in the open tag, look for attributes
15- if ( offset < currentNode . open . end ) {
16- let attrSelection = getNextAttribute ( selection , editor . document , currentNode ) ;
17- if ( attrSelection ) {
18- return attrSelection ;
20+ // If cursor is in the open tag, look for attributes
21+ if ( selectionEnd < currentNode . open . end ) {
22+ let attrSelection = getNextAttribute ( selectionStart , selectionEnd , editor . document , currentNode ) ;
23+ if ( attrSelection ) {
24+ return attrSelection ;
25+ }
1926 }
20- }
2127
22- // Get the first child of current node which is right after the cursor
23- let nextNode = currentNode . firstChild ;
24- while ( nextNode && nextNode . start < offset ) {
25- nextNode = nextNode . nextSibling ;
28+ // Get the first child of current node which is right after the cursor and is not a comment
29+ nextNode = currentNode . firstChild ;
30+ while ( nextNode && ( nextNode . start < selectionEnd || nextNode . type === 'comment' ) ) {
31+ nextNode = nextNode . nextSibling ;
32+ }
2633 }
2734
28- // Get next sibling of current node or the parent
35+
36+ // Get next sibling of current node which is not a comment. If none is found try the same on the parent
2937 while ( ! nextNode && currentNode ) {
30- nextNode = currentNode . nextSibling ;
31- currentNode = currentNode . parent ;
38+ if ( currentNode . nextSibling ) {
39+ if ( currentNode . nextSibling . type !== 'comment' ) {
40+ nextNode = currentNode . nextSibling ;
41+ } else {
42+ currentNode = currentNode . nextSibling ;
43+ }
44+ } else {
45+ currentNode = currentNode . parent ;
46+ }
3247 }
3348
3449 return getSelectionFromNode ( nextNode , editor . document ) ;
3550}
3651
37- export function prevItemHTML ( selection : vscode . Selection , editor : vscode . TextEditor , rootNode : Node ) : vscode . Selection {
38- let offset = editor . document . offsetAt ( selection . active ) ;
39- let currentNode = getNode ( rootNode , offset ) ;
52+ export function prevItemHTML ( selectionStart : number , selectionEnd : number , editor : vscode . TextEditor , rootNode : Node ) : vscode . Selection {
53+ let currentNode = getNode ( rootNode , selectionStart ) ;
4054 let prevNode : Node ;
4155
42- // Cursor is in the open tag after the tag name
43- if ( offset > currentNode . open . start + currentNode . name . length + 1 && offset <= currentNode . open . end ) {
44- prevNode = currentNode ;
45- }
56+ if ( currentNode . type !== 'comment' && selectionStart > currentNode . open . start + 1 ) {
4657
47- // Cursor is inside the tag
48- if ( ! prevNode && offset > currentNode . open . end ) {
49- if ( ! currentNode . firstChild ) {
50- // No children, so current node should be selected
58+ if ( selectionStart < currentNode . open . end || ! currentNode . firstChild ) {
5159 prevNode = currentNode ;
5260 } else {
53- // Select the child that appears just before the cursor
61+ // Select the child that appears just before the cursor and is not a comment
5462 prevNode = currentNode . firstChild ;
55- while ( prevNode . nextSibling && prevNode . nextSibling . end < offset ) {
63+ let oldOption : Node ;
64+ while ( prevNode . nextSibling && prevNode . nextSibling . end < selectionStart ) {
65+ if ( prevNode && prevNode . type !== 'comment' ) {
66+ oldOption = prevNode ;
67+ }
5668 prevNode = prevNode . nextSibling ;
5769 }
58- if ( prevNode ) {
59- prevNode = getDeepestNode ( prevNode ) ;
60- }
70+
71+ prevNode = getDeepestNode ( ( prevNode && prevNode . type !== 'comment' ) ? prevNode : oldOption ) ;
6172 }
6273 }
6374
64- if ( ! prevNode && currentNode . previousSibling ) {
65- prevNode = getDeepestNode ( currentNode . previousSibling ) ;
66- }
75+ // Select previous sibling which is not a comment. If none found, then select parent
76+ while ( ! prevNode && currentNode ) {
77+ if ( currentNode . previousSibling ) {
78+ if ( currentNode . previousSibling . type !== 'comment' ) {
79+ prevNode = getDeepestNode ( currentNode . previousSibling ) ;
80+ } else {
81+ currentNode = currentNode . previousSibling ;
82+ }
83+ } else {
84+ prevNode = currentNode . parent ;
85+ }
6786
68- if ( ! prevNode && currentNode . parent ) {
69- prevNode = currentNode . parent ;
7087 }
7188
72- let attrSelection = getPrevAttribute ( selection , editor . document , prevNode ) ;
89+ let attrSelection = getPrevAttribute ( selectionStart , selectionEnd , editor . document , prevNode ) ;
7390 return attrSelection ? attrSelection : getSelectionFromNode ( prevNode , editor . document ) ;
7491}
7592
7693function getSelectionFromNode ( node : Node , document : vscode . TextDocument ) : vscode . Selection {
7794 if ( node && node . open ) {
7895 let selectionStart = document . positionAt ( node . open . start + 1 ) ;
79- let selectionEnd = node . type === 'comment' ? document . positionAt ( node . open . end - 1 ) : selectionStart . translate ( 0 , node . name . length ) ;
96+ let selectionEnd = selectionStart . translate ( 0 , node . name . length ) ;
8097
8198 return new vscode . Selection ( selectionStart , selectionEnd ) ;
8299 }
83100}
84101
85- function getNextAttribute ( selection : vscode . Selection , document : vscode . TextDocument , node : Node ) : vscode . Selection {
102+ function getNextAttribute ( selectionStart : number , selectionEnd : number , document : vscode . TextDocument , node : Node ) : vscode . Selection {
86103
87104 if ( ! node . attributes || node . attributes . length === 0 || node . type === 'comment' ) {
88105 return ;
89106 }
90107
91- let selectionStart = document . offsetAt ( selection . anchor ) ;
92- let selectionEnd = document . offsetAt ( selection . active ) ;
93-
94108 for ( let i = 0 ; i < node . attributes . length ; i ++ ) {
95109 let attr = node . attributes [ i ] ;
96110
@@ -136,15 +150,12 @@ function getNextAttribute(selection: vscode.Selection, document: vscode.TextDocu
136150 }
137151}
138152
139- function getPrevAttribute ( selection : vscode . Selection , document : vscode . TextDocument , node : Node ) : vscode . Selection {
153+ function getPrevAttribute ( selectionStart : number , selectionEnd : number , document : vscode . TextDocument , node : Node ) : vscode . Selection {
140154
141155 if ( ! node . attributes || node . attributes . length === 0 || node . type === 'comment' ) {
142156 return ;
143157 }
144158
145- let selectionStart = document . offsetAt ( selection . anchor ) ;
146- let selectionEnd = document . offsetAt ( selection . active ) ;
147-
148159 for ( let i = node . attributes . length - 1 ; i >= 0 ; i -- ) {
149160 let attr = node . attributes [ i ] ;
150161
0 commit comments