e477b4dd8b3b30b17f1558cfa9bad5ffeedc2046cff2221ace459a972e440bd6619ee507fc551d27d9a70f6d58f83cec8aed17506f052c6241a7f18e43eeb3 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. import { getLine } from "./utils_line.js"
  2. // A Pos instance represents a position within the text.
  3. export function Pos(line, ch, sticky = null) {
  4. if (!(this instanceof Pos)) return new Pos(line, ch, sticky)
  5. this.line = line
  6. this.ch = ch
  7. this.sticky = sticky
  8. }
  9. // Compare two positions, return 0 if they are the same, a negative
  10. // number when a is less, and a positive number otherwise.
  11. export function cmp(a, b) { return a.line - b.line || a.ch - b.ch }
  12. export function equalCursorPos(a, b) { return a.sticky == b.sticky && cmp(a, b) == 0 }
  13. export function copyPos(x) {return Pos(x.line, x.ch)}
  14. export function maxPos(a, b) { return cmp(a, b) < 0 ? b : a }
  15. export function minPos(a, b) { return cmp(a, b) < 0 ? a : b }
  16. // Most of the external API clips given positions to make sure they
  17. // actually exist within the document.
  18. export function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1))}
  19. export function clipPos(doc, pos) {
  20. if (pos.line < doc.first) return Pos(doc.first, 0)
  21. let last = doc.first + doc.size - 1
  22. if (pos.line > last) return Pos(last, getLine(doc, last).text.length)
  23. return clipToLen(pos, getLine(doc, pos.line).text.length)
  24. }
  25. function clipToLen(pos, linelen) {
  26. let ch = pos.ch
  27. if (ch == null || ch > linelen) return Pos(pos.line, linelen)
  28. else if (ch < 0) return Pos(pos.line, 0)
  29. else return pos
  30. }
  31. export function clipPosArray(doc, array) {
  32. let out = []
  33. for (let i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i])
  34. return out
  35. }