website

Personal website
git clone https://github.com/michaelneuper/website.git
README | Files | Log | Refs

website/src/scripts/emacs/modeline.js (1989B)


// doom-modeline: evil state, buffer name, position, major mode and a clock.
// Other modules fill the misc and flags segments with setSegment().

import { $, isTyping, reducedMotion } from "../util.js";

const root = document.documentElement;
const modeline = $(".modeline");
const ml = {
  evil: $(".ml-evil"), buf: $(".ml-buf"), pos: $(".ml-pos"), pct: $(".ml-pct"),
  flags: $(".ml-flags"), misc: $(".ml-misc"), mode: $(".ml-mode"), time: $(".ml-time"),
};
const mini = $(".mini");

export function setSegment(name, text) {
  if (ml[name]) ml[name].textContent = text;
}

export function evilState() {
  const a = document.activeElement;
  let s = "N";
  if (!mini.hidden || (a && isTyping({ target: a }))) s = "I";
  else if (String(getSelection()).length) s = "V";
  modeline.dataset.evil = s;
  ml.evil.textContent = `<${s}>`;
}
document.addEventListener("focusin", evilState);
document.addEventListener("focusout", () => setTimeout(evilState));
document.addEventListener("selectionchange", evilState);

// back to top, once the reader is a screen down; gg does the same. The home
// page has no button.
const toTop = $(".to-top");
toTop?.addEventListener("click", () => {
  scrollTo({ top: 0, behavior: reducedMotion.matches ? "instant" : "smooth" });
  // the button hides at the top, so focus goes to the first link on the page
  $(".brand")?.focus({ preventScroll: true });
});

function onScroll() {
  const max = root.scrollHeight - innerHeight;
  const y = scrollY;
  ml.pct.textContent = y <= 2 ? "Top" : y >= max - 2 ? "Bot" : `${Math.round((y / max) * 100)}%`;
  ml.pos.textContent = `${Math.floor(y / 21) + 1}:0`;
  root.classList.toggle("is-scrolled", y > 24);
  if (toTop) toTop.hidden = y < innerHeight;
}
addEventListener("scroll", onScroll, { passive: true });
onScroll();

function clock() {
  const d = new Date();
  ml.time.textContent = `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
}
clock();
setInterval(clock, 15000);