@neuroplastio/xterm-addon-hotty 0.1.0-next.5 → 0.1.0-next.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -898,6 +898,7 @@ var ACTIONS = /* @__PURE__ */ new Set([
898
898
  "page-down",
899
899
  "input-start",
900
900
  "input-end",
901
+ "select-all",
901
902
  "newline",
902
903
  "submit",
903
904
  "program",
@@ -913,7 +914,21 @@ var ACTIONS = /* @__PURE__ */ new Set([
913
914
  "scroll-end"
914
915
  ]);
915
916
  var SCROLL_ACTIONS = new Set([...ACTIONS].filter((a) => a.startsWith("scroll-")));
916
- var MULTILINE_ACTIONS = /* @__PURE__ */ new Set(["line-previous", "line-next", "page-up", "page-down", "input-start", "input-end", "newline"]);
917
+ var MULTILINE_ACTIONS = /* @__PURE__ */ new Set(["line-previous", "line-next", "page-up", "page-down", "newline"]);
918
+ var MOVES = /* @__PURE__ */ new Set([
919
+ "char-backward",
920
+ "char-forward",
921
+ "word-backward",
922
+ "word-forward",
923
+ "line-start",
924
+ "line-end",
925
+ "line-previous",
926
+ "line-next",
927
+ "page-up",
928
+ "page-down",
929
+ "input-start",
930
+ "input-end"
931
+ ]);
917
932
  var ROW_ACTIONS = /* @__PURE__ */ new Set(["line-previous", "line-next", "page-up", "page-down"]);
918
933
  var BACKWARD = /* @__PURE__ */ new Set(["char-backward", "word-backward", "line-start", "line-previous", "page-up", "input-start"]);
919
934
  var INSERT = "insert";
@@ -921,7 +936,7 @@ var TERMINAL_KEYS = [
921
936
  "ArrowLeft=char-backward Control+b=char-backward ArrowRight=char-forward Control+f=char-forward",
922
937
  "Alt+ArrowLeft=word-backward Control+ArrowLeft=word-backward Alt+b=word-backward",
923
938
  "Alt+ArrowRight=word-forward Control+ArrowRight=word-forward Alt+f=word-forward",
924
- "Home=line-start Control+a=line-start End=line-end Control+e=line-end",
939
+ "Home=line-start End=line-end Control+e=line-end",
925
940
  "Backspace=delete-char-backward Control+h=delete-char-backward",
926
941
  "Delete=delete-char-forward Control+d=delete-char-forward",
927
942
  "Alt+Backspace=delete-word-backward Control+w=delete-word-backward Control+Backspace=delete-word-backward",
@@ -930,6 +945,7 @@ var TERMINAL_KEYS = [
930
945
  "ArrowUp=line-previous Control+p=line-previous ArrowDown=line-next Control+n=line-next",
931
946
  "PageUp=page-up PageDown=page-down",
932
947
  "Alt+<=input-start Control+Home=input-start Alt+>=input-end Control+End=input-end",
948
+ "Control+a=select-all",
933
949
  "Control+m=newline"
934
950
  ].join(" ");
935
951
  var segmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
@@ -1181,6 +1197,15 @@ var Keymap = class {
1181
1197
  if (isChar(value) && !mods.some((m) => m !== "Shift")) return INSERT;
1182
1198
  return null;
1183
1199
  }
1200
+ /** Whether the field selects with a key (SPEC §10.2, *Shift selects*):
1201
+ * it looks up a move, and the key's name has Shift. The field then moves
1202
+ * its caret and keeps the selection's anchor. */
1203
+ selects(name) {
1204
+ const k = parseKey(name);
1205
+ if (k === null) return false;
1206
+ const a = this.lookup(k);
1207
+ return a !== null && MOVES.has(a) && splitKey(k)[0].includes("Shift");
1208
+ }
1184
1209
  };
1185
1210
  function* bindingsOf(value) {
1186
1211
  for (const b of value.split(/[ \t\n\f\r]+/)) {
@@ -1207,14 +1232,25 @@ function resolve(multiline, ...values) {
1207
1232
  for (const [k, a] of [
1208
1233
  ["ArrowLeft", "char-backward"],
1209
1234
  ["ArrowRight", "char-forward"],
1235
+ ["Control+ArrowLeft", "word-backward"],
1236
+ ["Control+ArrowRight", "word-forward"],
1237
+ ["Alt+ArrowLeft", "word-backward"],
1238
+ ["Alt+ArrowRight", "word-forward"],
1210
1239
  ["Home", "line-start"],
1211
1240
  ["End", "line-end"],
1241
+ ["Control+Home", "input-start"],
1242
+ ["Control+End", "input-end"],
1212
1243
  ["Backspace", "delete-char-backward"],
1213
1244
  ["Delete", "delete-char-forward"],
1245
+ ["Control+Backspace", "delete-word-backward"],
1246
+ ["Control+Delete", "delete-word-forward"],
1247
+ ["Alt+Backspace", "delete-word-backward"],
1248
+ ["Alt+Delete", "delete-word-forward"],
1214
1249
  ["ArrowUp", "line-previous"],
1215
1250
  ["ArrowDown", "line-next"],
1216
1251
  ["PageUp", "page-up"],
1217
1252
  ["PageDown", "page-down"],
1253
+ ["Control+a", "select-all"],
1218
1254
  ["Enter", multiline ? "newline" : "submit"]
1219
1255
  ])
1220
1256
  m.bind(k, a);
@@ -1241,10 +1277,16 @@ function wordForward(t, p) {
1241
1277
  while (p < t.chars.length && !isSpace(t.chars[p])) p++;
1242
1278
  return p;
1243
1279
  }
1244
- function plan(t, action, rows, goal = null) {
1280
+ function plan(t, action, rows, goal = null, extend = false) {
1245
1281
  if (MULTILINE_ACTIONS.has(action) && !t.multiline) return { kind: "none" };
1246
1282
  const n = t.chars.length;
1247
1283
  const selected = t.start < t.end;
1284
+ if (action === "select-all") return { kind: "move", anchor: 0, to: n };
1285
+ if (extend && MOVES.has(action)) {
1286
+ const anchor = t.caret === t.start ? t.end : t.start;
1287
+ const moved = plan({ ...t, start: t.caret, end: t.caret }, action, rows, goal);
1288
+ return moved.kind === "move" ? { ...moved, anchor } : moved;
1289
+ }
1248
1290
  if (action.startsWith("delete-")) {
1249
1291
  if (selected) return { kind: "replace", from: t.start, to: t.end, text: "" };
1250
1292
  const p2 = t.start;
@@ -2018,6 +2060,7 @@ var Surface = class {
2018
2060
  const keys = data === null ? [{ key: domKeyName(e), data: "" }] : inputKeys(data);
2019
2061
  const keymap = this.keymapOf(el, multiline);
2020
2062
  const uses = keys.map((k) => k.key === null ? null : keymap.lookup(k.key));
2063
+ const extend = keys.map((k) => k.key !== null && keymap.selects(k.key));
2021
2064
  if (uses.every((u) => u === null)) {
2022
2065
  const program = keys.some((k) => k.key !== null && keymap.program(k.key));
2023
2066
  if (!program && this.axes && this.scrollKey(e)) return;
@@ -2046,7 +2089,7 @@ var Surface = class {
2046
2089
  } else if (use === "submit") {
2047
2090
  this.goal = null;
2048
2091
  submitFrom(el);
2049
- } else this.edit(el, multiline, { kind: "action", action: use });
2092
+ } else this.edit(el, multiline, { kind: "action", action: use, extend: extend[i] });
2050
2093
  });
2051
2094
  }
2052
2095
  /** A field's keymap (SPEC §10.2): the default, then the `data-keys` of
@@ -2074,6 +2117,7 @@ var Surface = class {
2074
2117
  };
2075
2118
  const start = index(el.selectionStart ?? el.value.length);
2076
2119
  const end = index(el.selectionEnd ?? el.value.length);
2120
+ const caret = el.selectionDirection === "backward" ? start : end;
2077
2121
  if (what.kind === "type") {
2078
2122
  this.goal = null;
2079
2123
  this.replace(el, at[start], at[end], what.text);
@@ -2081,14 +2125,16 @@ var Surface = class {
2081
2125
  }
2082
2126
  const action = what.action;
2083
2127
  const password = el.localName === "input" && this.inputType(el) === "password";
2084
- const text2 = { chars: cl, start, end, multiline, password };
2128
+ const text2 = { chars: cl, start, end, caret, multiline, password };
2085
2129
  const g = this.goal;
2086
- const goal = ROW_ACTIONS.has(action) && g && g.el === el && start === end && g.caret === start ? g.x : null;
2130
+ const goal = ROW_ACTIONS.has(action) && g && g.el === el && g.caret === caret ? g.x : null;
2087
2131
  const rows = multiline && ROW_ACTIONS.has(action) ? this.textareaRows(el, cl) : null;
2088
- const p = plan(text2, action, rows, goal);
2132
+ const p = plan(text2, action, rows, goal, what.extend);
2089
2133
  this.goal = p.kind === "move" && p.goal !== void 0 ? { el, caret: p.to, x: p.goal } : null;
2090
- if (p.kind === "move") el.setSelectionRange(at[p.to], at[p.to]);
2091
- else if (p.kind === "replace") this.replace(el, at[p.from], at[p.to], p.text);
2134
+ if (p.kind === "move") {
2135
+ const a = p.anchor ?? p.to;
2136
+ el.setSelectionRange(at[Math.min(a, p.to)], at[Math.max(a, p.to)], a > p.to ? "backward" : "forward");
2137
+ } else if (p.kind === "replace") this.replace(el, at[p.from], at[p.to], p.text);
2092
2138
  }
2093
2139
  /** Replaces code units `from` to `to` of a field's value with `text`, the
2094
2140
  * caret after it, as typing does. */
@@ -2177,6 +2223,10 @@ var Surface = class {
2177
2223
  d.execCommand("insertLineBreak", false);
2178
2224
  return;
2179
2225
  }
2226
+ if (action === "select-all") {
2227
+ sel.selectAllChildren(host);
2228
+ return;
2229
+ }
2180
2230
  const within = () => sel.focusNode !== null && host.contains(sel.focusNode);
2181
2231
  const next = (dir) => {
2182
2232
  const [an, ao, fn, fo] = [sel.anchorNode, sel.anchorOffset, sel.focusNode, sel.focusOffset];
@@ -2186,26 +2236,26 @@ var Surface = class {
2186
2236
  sel.setBaseAndExtent(an, ao, fn, fo);
2187
2237
  return c;
2188
2238
  };
2189
- const walk = (alter, dir, go) => {
2239
+ const walk = (alter2, dir, go) => {
2190
2240
  for (let i = 0; i < 1e5; i++) {
2191
2241
  const c = next(dir);
2192
2242
  if (!c || !go(c)) return;
2193
- sel.modify(alter, dir, "character");
2243
+ sel.modify(alter2, dir, "character");
2194
2244
  }
2195
2245
  };
2196
- const back = (alter, unit) => {
2246
+ const back = (alter2, unit) => {
2197
2247
  if (unit === "word") {
2198
- walk(alter, "backward", isSpace);
2199
- walk(alter, "backward", (c) => !isSpace(c));
2200
- } else if (unit === "line") walk(alter, "backward", (c) => !isBreak(c));
2201
- else sel.modify(alter, "backward", "character");
2248
+ walk(alter2, "backward", isSpace);
2249
+ walk(alter2, "backward", (c) => !isSpace(c));
2250
+ } else if (unit === "line") walk(alter2, "backward", (c) => !isBreak(c));
2251
+ else sel.modify(alter2, "backward", "character");
2202
2252
  };
2203
- const forward = (alter, unit) => {
2253
+ const forward = (alter2, unit) => {
2204
2254
  if (unit === "word") {
2205
- walk(alter, "forward", isSpace);
2206
- walk(alter, "forward", (c) => !isSpace(c));
2207
- } else if (unit === "line") walk(alter, "forward", (c) => !isBreak(c));
2208
- else sel.modify(alter, "forward", "character");
2255
+ walk(alter2, "forward", isSpace);
2256
+ walk(alter2, "forward", (c) => !isSpace(c));
2257
+ } else if (unit === "line") walk(alter2, "forward", (c) => !isBreak(c));
2258
+ else sel.modify(alter2, "forward", "character");
2209
2259
  };
2210
2260
  if (action.startsWith("delete-")) {
2211
2261
  if (sel.isCollapsed) {
@@ -2217,28 +2267,29 @@ var Surface = class {
2217
2267
  return;
2218
2268
  }
2219
2269
  const backward = ["char-backward", "word-backward", "line-start", "line-previous", "page-up", "input-start"].includes(action);
2220
- if (!sel.isCollapsed) {
2270
+ const alter = what.extend ? "extend" : "move";
2271
+ if (!what.extend && !sel.isCollapsed) {
2221
2272
  if (backward) sel.collapseToStart();
2222
2273
  else sel.collapseToEnd();
2223
2274
  if (action === "char-backward" || action === "char-forward") return;
2224
2275
  }
2225
2276
  const by = { "char-backward": "char", "char-forward": "char", "word-backward": "word", "word-forward": "word", "line-start": "line", "line-end": "line" }[action];
2226
2277
  if (by) {
2227
- if (backward) back("move", by);
2228
- else forward("move", by);
2278
+ if (backward) back(alter, by);
2279
+ else forward(alter, by);
2229
2280
  return;
2230
2281
  }
2231
2282
  if (action === "input-start" || action === "input-end") {
2232
- sel.modify("move", backward ? "backward" : "forward", "documentboundary");
2283
+ sel.modify(alter, backward ? "backward" : "forward", "documentboundary");
2233
2284
  return;
2234
2285
  }
2235
2286
  if (ROW_ACTIONS.has(action)) {
2236
2287
  const rows = action.startsWith("page") ? Math.max(1, Math.round(host.clientHeight / (parseFloat(this.frame.contentWindow.getComputedStyle(host).lineHeight) || 16))) : 1;
2237
2288
  for (let i = 0; i < rows; i++) {
2238
2289
  const [fn, fo] = [sel.focusNode, sel.focusOffset];
2239
- sel.modify("move", backward ? "backward" : "forward", "line");
2290
+ sel.modify(alter, backward ? "backward" : "forward", "line");
2240
2291
  if (sel.focusNode === fn && sel.focusOffset === fo) {
2241
- sel.modify("move", backward ? "backward" : "forward", "documentboundary");
2292
+ sel.modify(alter, backward ? "backward" : "forward", "documentboundary");
2242
2293
  return;
2243
2294
  }
2244
2295
  }