/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
https://github.com/joethei/obsidian-non-printing-chars
*/

var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __export = (target, all) => {
  __markAsModule(target);
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __reExport = (target, module2, desc) => {
  if (module2 && typeof module2 === "object" || typeof module2 === "function") {
    for (let key of __getOwnPropNames(module2))
      if (!__hasOwnProp.call(target, key) && key !== "default")
        __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
  }
  return target;
};
var __toModule = (module2) => {
  return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __async = (__this, __arguments, generator) => {
  return new Promise((resolve, reject) => {
    var fulfilled = (value) => {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    };
    var rejected = (value) => {
      try {
        step(generator.throw(value));
      } catch (e) {
        reject(e);
      }
    };
    var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
    step((generator = generator.apply(__this, __arguments)).next());
  });
};

// src/main.ts
__export(exports, {
  default: () => ControlCharacterPlugin
});
var import_obsidian4 = __toModule(require("obsidian"));
var import_state2 = __toModule(require("@codemirror/state"));

// src/SettingsTab.ts
var import_obsidian = __toModule(require("obsidian"));
var ControlCharactersSettingsTab = class extends import_obsidian.PluginSettingTab {
  constructor(plugin) {
    super(plugin.app, plugin);
    this.plugin = plugin;
  }
  display() {
    const { containerEl } = this;
    containerEl.empty();
    containerEl.createEl("h2", { text: "Control Characters" });
    new import_obsidian.Setting(containerEl).setName("Only show control characters in selection").addToggle((toggle) => {
      toggle.setValue(this.plugin.settings.selection).onChange((value) => __async(this, null, function* () {
        this.plugin.settings.selection = value;
        yield this.plugin.saveSettings();
      }));
    });
    containerEl.createEl("h3", { text: "Show" });
    new import_obsidian.Setting(containerEl).setName("Space").addToggle((toggle) => {
      toggle.setValue(this.plugin.settings.space).onChange((value) => __async(this, null, function* () {
        this.plugin.settings.space = value;
        yield this.plugin.saveSettings();
      }));
    });
    new import_obsidian.Setting(containerEl).setName("Tab").addToggle((toggle) => {
      toggle.setValue(this.plugin.settings.tab).onChange((value) => __async(this, null, function* () {
        this.plugin.settings.tab = value;
        yield this.plugin.saveSettings();
      }));
    });
    new import_obsidian.Setting(containerEl).setName("New line").addToggle((toggle) => {
      toggle.setValue(this.plugin.settings.newLine).onChange((value) => __async(this, null, function* () {
        this.plugin.settings.newLine = value;
        yield this.plugin.saveSettings();
      }));
    });
  }
};

// src/NormalDecoration.ts
var import_view3 = __toModule(require("@codemirror/view"));

// src/StatefulDecoration.ts
var import_state = __toModule(require("@codemirror/state"));
var import_view = __toModule(require("@codemirror/view"));
var statefulDecorations = defineStatefulDecoration();
function defineStatefulDecoration() {
  const update = import_state.StateEffect.define();
  const field = import_state.StateField.define({
    create() {
      return import_view.Decoration.none;
    },
    update(deco, tr) {
      return tr.effects.reduce((deco2, effect) => effect.is(update) ? effect.value : deco2, deco.map(tr.changes));
    },
    provide: (field2) => import_view.EditorView.decorations.from(field2)
  });
  return { update, field };
}

// src/StatefulDecorationSet.ts
var import_view2 = __toModule(require("@codemirror/view"));
var import_obsidian2 = __toModule(require("obsidian"));
var StatefulDecorationSet = class {
  constructor(editor) {
    this.decoCache = Object.create(null);
    this.debouncedUpdate = (0, import_obsidian2.debounce)(this.updateAsyncDecorations, 10, true);
    this.editor = editor;
  }
  computeAsyncDecorations(tokens) {
    return __async(this, null, function* () {
      const decorations = [];
      for (const token of tokens) {
        let deco = this.decoCache[token.value];
        if (!deco) {
          deco = this.decoCache[token.value] = import_view2.Decoration.mark({
            class: "control-character",
            attributes: { type: token.value }
          });
        }
        decorations.push(deco.range(token.from, token.to));
      }
      return import_view2.Decoration.set(decorations, true);
    });
  }
  updateAsyncDecorations(tokens) {
    return __async(this, null, function* () {
      const decorations = yield this.computeAsyncDecorations(tokens);
      if (decorations || this.editor.state.field(statefulDecorations.field).size) {
        this.editor.dispatch({ effects: statefulDecorations.update.of(decorations || import_view2.Decoration.none) });
      }
    });
  }
};

// src/FrontmatterParser.ts
var import_obsidian3 = __toModule(require("obsidian"));
function parseFrontmatter(view, settings) {
  const result = {
    enabled: settings.enabled,
    newLine: settings.newLine,
    selection: settings.selection,
    space: settings.space,
    tab: settings.tab
  };
  const matches = view.state.sliceDoc().match(/---([\s\S]*?)---/);
  if (matches && matches.length !== 0) {
    for (const match of matches) {
      const replaced = match.replace(/---/g, "");
      try {
        const frontmatter = (0, import_obsidian3.parseYaml)(replaced);
        if (frontmatter.hasOwnProperty("cc")) {
          result.enabled = frontmatter.cc;
        }
        if (frontmatter.hasOwnProperty("cc-tab")) {
          result.tab = frontmatter["cc-tab"];
        }
        if (frontmatter.hasOwnProperty("cc-newline")) {
          result.newLine = frontmatter["cc-newline"];
        }
        if (frontmatter.hasOwnProperty("cc-space")) {
          result.space = frontmatter["cc-space"];
        }
        if (frontmatter.hasOwnProperty("cc-selection")) {
          result.selection = frontmatter["cc-selection"];
        }
      } catch (e) {
      }
    }
  }
  return result;
}

// src/NormalDecoration.ts
function buildViewPlugin(plugin) {
  return import_view3.ViewPlugin.fromClass(class {
    constructor(view) {
      this.decoManager = new StatefulDecorationSet(view);
      this.buildAsyncDecorations(view, plugin.settings);
    }
    update(update) {
      if (update.docChanged || update.viewportChanged) {
        const frontmatter = parseFrontmatter(update.view, plugin.settings);
        if (!frontmatter.enabled || frontmatter.selection) {
          this.decoManager.debouncedUpdate([]);
          return;
        }
        this.buildAsyncDecorations(update.view, frontmatter);
      }
    }
    buildAsyncDecorations(view, settings) {
      const targetElements = [];
      for (const { from, to } of view.visibleRanges) {
        targetElements.push(...plugin.getTokens(view, from, to, settings));
      }
      this.decoManager.debouncedUpdate(targetElements);
    }
  });
}
function normalDecoration(plugin) {
  return [statefulDecorations.field, buildViewPlugin(plugin)];
}

// src/settings.ts
var DEFAULT_SETTINGS = {
  newLine: true,
  tab: true,
  space: true,
  enabled: true,
  selection: false
};

// src/SelectionHighlight.ts
var import_view4 = __toModule(require("@codemirror/view"));
function buildViewPlugin2(plugin) {
  return import_view4.ViewPlugin.fromClass(class {
    constructor(view) {
      this.decoManager = new StatefulDecorationSet(view);
      const frontmatter = parseFrontmatter(view, plugin.settings);
      if (!frontmatter.selection) {
        return;
      }
      this.buildAsyncDecorations(view, parseFrontmatter(view, plugin.settings));
    }
    update(update) {
      const frontmatter = parseFrontmatter(update.view, plugin.settings);
      if (!frontmatter.selection) {
        return;
      }
      if (update.selectionSet || update.docChanged || update.viewportChanged) {
        this.buildAsyncDecorations(update.view, frontmatter);
      }
    }
    buildAsyncDecorations(view, settings) {
      const targetElements = [];
      for (const range of view.state.selection.ranges) {
        targetElements.push(...plugin.getTokens(view, range.from, range.to, settings));
      }
      this.decoManager.debouncedUpdate(targetElements);
    }
  });
}
function selectionDecorations(plugin) {
  return [statefulDecorations.field, buildViewPlugin2(plugin)];
}

// src/types.ts
var ControlCharacter;
(function(ControlCharacter2) {
  ControlCharacter2["NEWLINE"] = "newline";
  ControlCharacter2["SPACE"] = "space";
  ControlCharacter2["TAB"] = "tab";
  ControlCharacter2["OTHER"] = "other";
})(ControlCharacter || (ControlCharacter = {}));

// src/main.ts
var ControlCharacterPlugin = class extends import_obsidian4.Plugin {
  onload() {
    return __async(this, null, function* () {
      if (!this.app.vault.getConfig("legacyEditor")) {
        yield this.loadSettings();
        this.registerEditorExtension(import_state2.Prec.lowest(normalDecoration(this)));
        this.registerEditorExtension(import_state2.Prec.lowest(selectionDecorations(this)));
        this.addSettingTab(new ControlCharactersSettingsTab(this));
        this.addCommand({
          id: "toggle",
          name: "Show/hide control characters",
          callback: () => __async(this, null, function* () {
            this.settings.enabled = !this.settings.enabled;
            console.log(this.settings.enabled);
            yield this.saveSettings();
            this.app.workspace.updateOptions();
          })
        });
        this.app.workspace.trigger("parse-style-settings");
      } else {
        new import_obsidian4.Notice("Control Characters: You are using the legacy editor, this plugin is not supported there");
      }
    });
  }
  onunload() {
  }
  loadSettings() {
    return __async(this, null, function* () {
      this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
    });
  }
  saveSettings() {
    return __async(this, null, function* () {
      yield this.saveData(this.settings);
    });
  }
  getTokens(view, from, to, settings) {
    const targetElements = [];
    const text = view.state.sliceDoc(from, to);
    for (const match of text.matchAll(/[\u00A0\u202F\u2007\u2060\s]/gu)) {
      const index = from + match.index;
      if (match.toString() === "\n" && settings.newLine) {
        targetElements.push({ from: index - 1, to: index, value: ControlCharacter.NEWLINE });
        continue;
      }
      let value;
      if (match.toString() === "	" && settings.tab) {
        value = ControlCharacter.TAB;
      } else if (match.toString() === " " && settings.space) {
        value = ControlCharacter.SPACE;
      } else {
        value = ControlCharacter.OTHER;
      }
      targetElements.push({ from: index, to: index + 1, value });
    }
    return targetElements;
  }
};
