TextRange.js 4.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. export class TextRange{constructor(startLine,startColumn,endLine,endColumn){this.startLine=startLine;this.startColumn=startColumn;this.endLine=endLine;this.endColumn=endColumn;}
  2. static createFromLocation(line,column){return new TextRange(line,column,line,column);}
  3. static fromObject(serializedTextRange){return new TextRange(serializedTextRange.startLine,serializedTextRange.startColumn,serializedTextRange.endLine,serializedTextRange.endColumn);}
  4. static comparator(range1,range2){return range1.compareTo(range2);}
  5. static fromEdit(oldRange,newText){let endLine=oldRange.startLine;let endColumn=oldRange.startColumn+newText.length;const lineEndings=newText.computeLineEndings();if(lineEndings.length>1){endLine=oldRange.startLine+lineEndings.length-1;const len=lineEndings.length;endColumn=lineEndings[len-1]-lineEndings[len-2]-1;}
  6. return new TextRange(oldRange.startLine,oldRange.startColumn,endLine,endColumn);}
  7. isEmpty(){return this.startLine===this.endLine&&this.startColumn===this.endColumn;}
  8. immediatelyPrecedes(range){if(!range){return false;}
  9. return this.endLine===range.startLine&&this.endColumn===range.startColumn;}
  10. immediatelyFollows(range){if(!range){return false;}
  11. return range.immediatelyPrecedes(this);}
  12. follows(range){return(range.endLine===this.startLine&&range.endColumn<=this.startColumn)||range.endLine<this.startLine;}
  13. get linesCount(){return this.endLine-this.startLine;}
  14. collapseToEnd(){return new TextRange(this.endLine,this.endColumn,this.endLine,this.endColumn);}
  15. collapseToStart(){return new TextRange(this.startLine,this.startColumn,this.startLine,this.startColumn);}
  16. normalize(){if(this.startLine>this.endLine||(this.startLine===this.endLine&&this.startColumn>this.endColumn)){return new TextRange(this.endLine,this.endColumn,this.startLine,this.startColumn);}else{return this.clone();}}
  17. clone(){return new TextRange(this.startLine,this.startColumn,this.endLine,this.endColumn);}
  18. serializeToObject(){const serializedTextRange={};serializedTextRange.startLine=this.startLine;serializedTextRange.startColumn=this.startColumn;serializedTextRange.endLine=this.endLine;serializedTextRange.endColumn=this.endColumn;return serializedTextRange;}
  19. compareTo(other){if(this.startLine>other.startLine){return 1;}
  20. if(this.startLine<other.startLine){return-1;}
  21. if(this.startColumn>other.startColumn){return 1;}
  22. if(this.startColumn<other.startColumn){return-1;}
  23. return 0;}
  24. compareToPosition(lineNumber,columnNumber){if(lineNumber<this.startLine||(lineNumber===this.startLine&&columnNumber<this.startColumn)){return-1;}
  25. if(lineNumber>this.endLine||(lineNumber===this.endLine&&columnNumber>this.endColumn)){return 1;}
  26. return 0;}
  27. equal(other){return this.startLine===other.startLine&&this.endLine===other.endLine&&this.startColumn===other.startColumn&&this.endColumn===other.endColumn;}
  28. relativeTo(line,column){const relative=this.clone();if(this.startLine===line){relative.startColumn-=column;}
  29. if(this.endLine===line){relative.endColumn-=column;}
  30. relative.startLine-=line;relative.endLine-=line;return relative;}
  31. relativeFrom(line,column){const relative=this.clone();if(this.startLine===0){relative.startColumn+=column;}
  32. if(this.endLine===0){relative.endColumn+=column;}
  33. relative.startLine+=line;relative.endLine+=line;return relative;}
  34. rebaseAfterTextEdit(originalRange,editedRange){console.assert(originalRange.startLine===editedRange.startLine);console.assert(originalRange.startColumn===editedRange.startColumn);const rebase=this.clone();if(!this.follows(originalRange)){return rebase;}
  35. const lineDelta=editedRange.endLine-originalRange.endLine;const columnDelta=editedRange.endColumn-originalRange.endColumn;rebase.startLine+=lineDelta;rebase.endLine+=lineDelta;if(rebase.startLine===editedRange.endLine){rebase.startColumn+=columnDelta;}
  36. if(rebase.endLine===editedRange.endLine){rebase.endColumn+=columnDelta;}
  37. return rebase;}
  38. toString(){return JSON.stringify(this);}
  39. containsLocation(lineNumber,columnNumber){if(this.startLine===this.endLine){return this.startLine===lineNumber&&this.startColumn<=columnNumber&&columnNumber<=this.endColumn;}
  40. if(this.startLine===lineNumber){return this.startColumn<=columnNumber;}
  41. if(this.endLine===lineNumber){return columnNumber<=this.endColumn;}
  42. return this.startLine<lineNumber&&lineNumber<this.endLine;}}
  43. export class SourceRange{constructor(offset,length){this.offset=offset;this.length=length;}}
  44. export class SourceEdit{constructor(sourceURL,oldRange,newText){this.sourceURL=sourceURL;this.oldRange=oldRange;this.newText=newText;}
  45. static comparator(edit1,edit2){return TextRange.comparator(edit1.oldRange,edit2.oldRange);}
  46. newRange(){return TextRange.fromEdit(this.oldRange,this.newText);}}
  47. self.TextUtils=self.TextUtils||{};TextUtils=TextUtils||{};TextUtils.TextRange=TextRange;TextUtils.SourceRange=SourceRange;TextUtils.SourceEdit=SourceEdit;