<commit_before>const {CompositeDisposable, Point} = require("atom")
const {existsSync} = require("fs")
const path = require("path")

// Wrapper for Point or Marker.
//  For alive editor, use Marker to track up to date position.
//  For destroyed editor, use Point.
module.exports = class Entry {
  static deserialize({editor, point, URI}) {
    return new this({editor, point: Point.fromObject(point), URI})
  }

  serialize() {
    return {
      point: this.point.serialize(),
      URI: this.URI,
    }
  }

  constructor({editor, point, URI}) {
    this.point = point
    this.URI = URI
    this.destroyed = false

    if (!editor || !editor.isAlive()) return

    this.editor = editor
    this.subscriptions = new CompositeDisposable()
    this.marker = editor.markBufferPosition(point)
    this.subscriptions.add(
      this.marker.onDidChange(({newHeadBufferPosition}) => {
        this.point = newHeadBufferPosition
      })
    )
    this.subscriptions.add(
      editor.onDidDestroy(() => {
        if (editor.getURI()) {
          this.unSubscribe()
        } else {
          this.destroy()
        }
      })
    )
  }

  unSubscribe() {
    this.subscriptions.dispose()
    this.editor = this.subscriptions = null
  }

  destroy() {
    if (this.destroyed) return

    if (this.editor) this.unSubscribe()
    this.destroyed = true
    if (this.marker) this.marker.destroy()
    this.point = this.URI = this.marker = null
  }

  isDestroyed() {
    return this.destroyed
  }

  isEditorAlive() {
    return this.editor && this.editor.isAlive()
  }

  isValid() {
    if (this.isDestroyed()) return false

    const excludeClosedBuffer = atom.config.get("cursor-history.excludeClosedBuffer")
    return this.isEditorAlive() || (!excludeClosedBuffer && existsSync(this.URI))
  }

  isSameFile(other) {
    return (this.editor && this.editor === other.editor) || (this.URI && (this.URI && other.URI))
  }

  isAtSameRow(other) {
    return (
      this.isSameFile(other) &&
      this.isValid() &&
      other.isValid() &&
      other.point.row === this.point.row &&
      other.URI === this.URI
    )
  }

  toString() {
    return `${this.point}, ${this.URI}`
  }

  inspect() {
    if (this.isDestroyed()) {
      return "[Destroyed]"
    } else {
      const invalid = this.isValid() ? "" : " [Invalid]"
      return `${this.point}, ${path.basename(this.URI)}` + invalid
    }
  }<commit_msg>explicitly check URI requrement<commit_after>const {CompositeDisposable, Point} = require("atom")
const {existsSync} = require("fs")
const path = require("path")

// Wrapper for Point or Marker.
//  For alive editor, use Marker to track up to date position.
//  For destroyed editor, use Point.
module.exports = class Entry {
  static deserialize({editor, point, URI}) {
    return new this({editor, point: Point.fromObject(point), URI})
  }

  serialize() {
    return {
      point: this.point.serialize(),
      URI: this.URI,
    }
  }

  constructor({editor, point, URI}) {
    this.point = point
    this.URI = URI
    this.destroyed = false

    if (!editor || !editor.isAlive()) return

    this.editor = editor
    this.subscriptions = new CompositeDisposable()
    this.marker = editor.markBufferPosition(point)
    this.subscriptions.add(
      this.marker.onDidChange(({newHeadBufferPosition}) => {
        this.point = newHeadBufferPosition
      })
    )
    this.subscriptions.add(
      editor.onDidDestroy(() => {
        if (editor.getURI()) {
          this.unSubscribe()
        } else {
          this.destroy()
        }
      })
    )
  }

  unSubscribe() {
    this.subscriptions.dispose()
    this.editor = this.subscriptions = null
  }

  destroy() {
    if (this.destroyed) return

    if (this.editor) this.unSubscribe()
    this.destroyed = true
    if (this.marker) this.marker.destroy()
    this.point = this.URI = this.marker = null
  }

  isDestroyed() {
    return this.destroyed
  }

  isEditorAlive() {
    return this.editor && this.editor.isAlive()
  }

  isValid() {
    if (this.isDestroyed()) return false

    const excludeClosedBuffer = atom.config.get("cursor-history.excludeClosedBuffer")
    return this.isEditorAlive() || (!excludeClosedBuffer && this.URI && existsSync(this.URI))
  }

  isSameFile(other) {
    return (this.editor && this.editor === other.editor) || (this.URI && (this.URI && other.URI))
  }

  isAtSameRow(other) {
    return (
      this.isSameFile(other) &&
      this.isValid() &&
      other.isValid() &&
      other.point.row === this.point.row &&
      other.URI === this.URI
    )
  }

  toString() {
    return `${this.point}, ${this.URI}`
  }

  inspect() {
    if (this.isDestroyed()) {
      return "[Destroyed]"
    } else {
      const invalid = this.isValid() ? "" : " [Invalid]"
      return `${this.point}, ${path.basename(this.URI)}` + invalid
    }
  }
{'fraction_non_alphanumeric': 0.14849235852953324, 'fraction_numerical': 0.0, 'mean_word_length': 2.67172100075815, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1488131', 'n_tokens_mistral': 1564, 'n_tokens_neox': 1520, 'n_words': 316}