@@ -117,20 +117,29 @@ export function prevWordStart(text: string, offset: number, big: boolean) {
117117 return pos
118118}
119119
120+ function wordClass ( char : string , big : boolean ) : "blank" | "word" | "punct" {
121+ if ( ! isBigWord ( char ) ) return "blank"
122+ if ( big || isWord ( char ) ) return "word"
123+ return "punct"
124+ }
125+
120126export function wordEnd ( text : string , offset : number , big : boolean ) {
121127 if ( text . length === 0 ) return 0
122- const match = big ? isBigWord : isWord
123128 let pos = offset
124129 if ( pos >= text . length ) pos = text . length - 1
125130
126- if ( match ( text [ pos ] ) && ( pos + 1 >= text . length || ! match ( text [ pos + 1 ] ) ) ) {
131+ const startClass = wordClass ( text [ pos ] , big )
132+ const atRunEnd =
133+ startClass === "blank" || pos + 1 >= text . length || wordClass ( text [ pos + 1 ] , big ) !== startClass
134+
135+ if ( atRunEnd ) {
127136 pos ++
137+ while ( pos < text . length && wordClass ( text [ pos ] , big ) === "blank" ) pos ++
138+ if ( pos >= text . length ) return text . length - 1
128139 }
129140
130- while ( pos < text . length && ! match ( text [ pos ] ) ) pos ++
131- if ( pos >= text . length ) return text . length - 1
132-
133- while ( pos + 1 < text . length && match ( text [ pos + 1 ] ) ) pos ++
141+ const target = wordClass ( text [ pos ] , big )
142+ while ( pos + 1 < text . length && wordClass ( text [ pos + 1 ] , big ) === target ) pos ++
134143 return pos
135144}
136145
@@ -312,6 +321,17 @@ export function deleteWordBackward(textarea: TextareaRenderable): VimRegister {
312321 return { text : yanked , linewise : false }
313322}
314323
324+ export function deleteWordEnd ( textarea : TextareaRenderable , big = false ) : VimRegister {
325+ const text = textarea . plainText
326+ const startOffset = textarea . cursorOffset
327+ if ( startOffset >= text . length ) return null
328+ const endOffset = wordEnd ( text , startOffset , big ) + 1
329+ if ( endOffset <= startOffset ) return null
330+ const yanked = text . slice ( startOffset , endOffset )
331+ deleteOffsets ( textarea , startOffset , endOffset )
332+ return { text : yanked , linewise : false }
333+ }
334+
315335export function deleteLine ( textarea : TextareaRenderable ) : VimRegister {
316336 const text = textarea . plainText
317337 if ( ! text . length ) return null
@@ -445,6 +465,21 @@ export function yankWordSpan(textarea: TextareaRenderable): VimSpan | null {
445465 return { start, end }
446466}
447467
468+ export function yankWordEnd ( textarea : TextareaRenderable , big = false ) : VimRegister {
469+ const span = yankWordEndSpan ( textarea , big )
470+ if ( ! span ) return null
471+ return { text : textarea . plainText . slice ( span . start , span . end ) , linewise : false }
472+ }
473+
474+ export function yankWordEndSpan ( textarea : TextareaRenderable , big = false ) : VimSpan | null {
475+ const text = textarea . plainText
476+ const start = textarea . cursorOffset
477+ if ( start >= text . length ) return null
478+ const end = wordEnd ( text , start , big ) + 1
479+ if ( end <= start ) return null
480+ return { start, end }
481+ }
482+
448483export function pasteAfter ( textarea : TextareaRenderable , reg : VimRegister ) {
449484 if ( ! reg ) return
450485 if ( reg . linewise ) {
0 commit comments