import { GoAction } from "../action/GoAction" ; import * as Utils from "../Utils" ; import { Position } from "../VimStyle" ; import { AbstractMotion } from "./AbstractMotion" ; /**
 * b B e E
 * cb cB ce cE
 * this class will be replaced
 */ export class WordMotion extends AbstractMotion { public Direction : Direction ; public IsSkipBlankLine : boolean ; public IsStopLineEnd : boolean ; public IsWordEnd : boolean ; public Command : string ; public IsWORD : boolean ; public IsForRange : boolean ; constructor ( direction ) { super ( ) ; this . Direction = direction ; this . IsSkipBlankLine = false ; this . IsStopLineEnd = false ; this . IsWordEnd = false ; this . IsWORD = false ; this . IsForRange = false ; } ; public CalculateEnd ( editor , vim , start ) { let count = this . Count ; let previousCharClass = null ; let charClass = null ; let nextCharClass = null ; let previousPosition = null ; let position = null ; let nextPosition = editor . GetCurrentPosition ( ) . Copy ( ) ; let beforeCountLoop ; let line = editor . ReadLine ( nextPosition . Line ) ; let lineLength = line . length ; let documentLength = editor . GetLastLineNum ( ) + 1 ; if ( this . Direction === Direction . Right ) { if ( nextPosition . Char === 0 ) { charClass = CharGroup . Spaces ; nextCharClass = CharGroup . Spaces ; nextPosition . Char = - 1 ; if ( this . Command !== "dw" && line . length > 0 ) { let charCode = line . charCodeAt ( nextPosition . Char ) ; charClass = Utils . GetCharClass ( charCode ) ; if ( charClass !== CharGroup . Spaces ) { count += 1 ; } } beforeCountLoop = - 1 ; } else if ( nextPosition . Char === 1 ) { nextCharClass = CharGroup . Spaces ; beforeCountLoop = - 2 ; } else { nextPosition . Char -- ; beforeCountLoop = - 3 ; } } else { if ( lineLength - 2 === nextPosition . Char ) { charClass = CharGroup . Spaces ; nextCharClass = CharGroup . Spaces ; beforeCountLoop = - 1 ; } else if ( lineLength - 1 === nextPosition . Char ) { nextCharClass = CharGroup . Spaces ; beforeCountLoop = - 2 ; } else { nextPosition . Char ++ ; beforeCountLoop = - 3 ; } } if ( this . IsForRange && nextCharClass !== CharGroup . Spaces ) { count -- ; } let isReachLast = false ; let charCode ; let lineEnd ; let skipCountDown ; while ( count > - 1 ) { skipCountDown = false ; lineEnd = false ; previousPosition = position ; previousCharClass = charClass ; position = nextPosition ; charClass = nextCharClass ; nextPosition = new Position ( position . Line , position . Char ) ; if ( this . Direction === Direction . Left ) { nextPosition . Char -- ; if ( nextPosition . Char === - 1 ) { nextCharClass = CharGroup . Spaces ; } else if ( nextPosition . Char < - 1 ) { nextPosition . Line -- ; if ( nextPosition . Line < 0 ) { isReachLast = true ; break ; } else { line = editor . ReadLine ( nextPosition . Line ) ; lineLength = line . length ; nextPosition . Char = lineLength - 1 ; nextCharClass = CharGroup . Spaces ; } } else { let nextCharCode = line . charCodeAt ( nextPosition . Char ) ; nextCharClass = Utils . GetCharClass ( nextCharCode ) ; } } else { nextPosition . Char ++ ; if ( lineLength <= nextPosition . Char ) { lineEnd = true ; nextPosition . Line ++ ; if ( nextPosition . Line === documentLength ) { isReachLast = true ; break ; } else { line = editor . ReadLine ( nextPosition . Line ) ; lineLength = line . length ; nextPosition . Char = - 1 ; nextCharClass = CharGroup . Spaces ; } } else { let nextCharCode = line . charCodeAt ( nextPosition . Char ) ; nextCharClass = Utils . GetCharClass ( nextCharCode ) ; } } beforeCountLoop ++ ; if ( beforeCountLoop < 0 ) { continue ; } else if ( beforeCountLoop === 0 && this . IsWordEnd && this . Command !== "cw" ) { if ( charClass !== CharGroup . Spaces && nextCharClass !== CharGroup . Spaces ) { if ( this . IsWORD || charClass === nextCharClass ) { count -- ; skipCountDown = true ; } } } let newWord = false ; if ( ! skipCountDown ) { if ( charClass !== CharGroup . Spaces ) { if ( this . IsWORD ) { if ( previousCharClass === CharGroup . Spaces ) { newWord = true ; count -- ; } } else { if ( previousCharClass !== charClass ) { newWord = true ; count -- ; } } } else if ( ! newWord && ! this . IsSkipBlankLine ) { if ( this . Direction === Direction . Right ) { if ( previousPosition !== null && previousPosition . Char === - 1 ) { count -- ; } } else { if ( position . Char === - 1 && previousPosition . Char === - 1 ) { count -- ; } } } } if ( count === 0 ) { if ( this . IsWordEnd ) { if ( this . IsWORD ) { if ( nextCharClass === CharGroup . Spaces ) { break ; } if ( lineEnd ) { break ; } } else { if ( charClass !== nextCharClass ) { break ; } } } else if ( this . IsForRange ) { if ( this . Direction === Direction . Right ) { if ( position . Char === - 1 ) { break ; } } } else { break ; } } } if ( isReachLast ) { if ( this . Direction === Direction . Left ) { return new Position ( 0 , 0 ) ; } else { if ( this . IsForRange ) { position . Char += 1 ; } return position ; } } if ( this . IsForRange && position . Char === - 1 ) { line = editor . ReadLine ( position . Line - 1 ) ; return new Position ( position . Line - 1 , line . length ) ; } if ( this . Command === "cw" ) { if ( line . length - 1 > position . Char ) { position . Char ++ ; } } return position ; } } export function GotoWordBackword ( num ) { let a = new GoAction ( ) ; let m ; m = new WordMotion ( Direction . Left ) ; m . IsWordEnd = true ; m . IsWORD = false ; m . IsSkipBlankLine = false ; m . Count = num > 0 ? num : 1 ; a . Motion = m ; return a ; } export function AddWordBackwardMotion ( num , action ) { let m ; m = new WordMotion ( Direction . Left ) ; m . IsWordEnd = true ; m . IsWORD = false ; m . IsSkipBlankLine = false ; m . Count = num > 0 ? num : 1 ; let a = < IRequireMotionAction > action ; a . Motion = m ; } export function GotoBlankSeparatedBackwordWord ( num ) { let a = new GoAction ( ) ; let m ; m = new WordMotion ( Direction . Left ) ; m . IsWordEnd = true ; m . IsWORD = true ; m . IsSkipBlankLine = false ; m . Count = num > 0 ? num : 1 ; a . Motion = m ; return a ; } export function AddBlankSeparatedBackwordMotion ( num , action ) { let m ; m = new WordMotion ( Direction . Left ) ; m . IsWordEnd = true ; m . IsWORD = true ; m . IsSkipBlankLine = false ; m . Count = num > 0 ? num : 1 ; let a = < IRequireMotionAction > action ; a . Motion = m ; }