about summary refs log tree commit diff stats
path: root/src/buffer/select.nim
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-09-14 01:08:10 +0200
committerbptato <nincsnevem662@gmail.com>2023-09-14 01:08:10 +0200
commitdb0798acccbedcef4b16737f6be0cf7388cc0528 (patch)
tree208616de68fe9729e09e4084557f27f5b7204387 /src/buffer/select.nim
parentc2004e4aba182473e79100759a2d58e1bd7d184c (diff)
downloadchawan-db0798acccbedcef4b16737f6be0cf7388cc0528.tar.gz
move some modules to local/
makes a bit more sense than the previous arrangement
Diffstat (limited to 'src/buffer/select.nim')
-rw-r--r--src/buffer/select.nim306
1 files changed, 0 insertions, 306 deletions
diff --git a/src/buffer/select.nim b/src/buffer/select.nim
deleted file mode 100644
index f7afa4d9..00000000
--- a/src/buffer/select.nim
+++ /dev/null
@@ -1,306 +0,0 @@
-import unicode
-
-import buffer/buffer
-import buffer/cell
-import js/regex
-import utils/twtstr
-
-type
-  SubmitSelect* = proc(selected: seq[int])
-  CloseSelect* = proc()
-
-  Select* = object
-    open*: bool
-    options: seq[string]
-    multiple: bool
-    # old selection
-    oselected*: seq[int]
-    # new selection
-    selected*: seq[int]
-    # cursor distance from y
-    cursor: int
-    # widest option
-    maxw: int
-    # maximum height on screen (yes the naming is dumb)
-    maxh: int
-    # first index to display
-    si: int
-    # location on screen
-    x: int
-    y: int
-    redraw*: bool
-    submitFun: SubmitSelect
-    bpos: seq[int]
-
-proc windowChange*(select: var Select, height: int) =
-  select.maxh = height - 2
-  if select.y + select.options.len >= select.maxh:
-    select.y = height - select.options.len
-    if select.y < 0:
-      select.si = -select.y
-      select.y = 0
-  if select.selected.len > 0:
-    let i = select.selected[0]
-    if select.si > i:
-      select.si = i
-    elif select.si + select.maxh < i:
-      select.si = max(i - select.maxh, 0)
-  select.redraw = true
-
-proc initSelect*(select: var Select, selectResult: SelectResult,
-    x, y, height: int, submitFun: SubmitSelect) =
-  select.open = true
-  select.multiple = selectResult.multiple
-  select.options = selectResult.options
-  select.oselected = selectResult.selected
-  select.selected = selectResult.selected
-  select.submitFun = submitFun
-  for opt in select.options.mitems:
-    opt.mnormalize()
-    select.maxw = max(select.maxw, opt.width())
-  select.x = x
-  select.y = y
-  select.windowChange(height)
-
-# index of option currently under cursor
-func hover(select: Select): int =
-  return select.cursor + select.si
-
-func dispheight(select: Select): int =
-  return select.maxh - select.y
-
-proc `hover=`(select: var Select, i: int) =
-  let i = clamp(i, 0, select.options.high)
-  if i >= select.si + select.dispheight:
-    select.si = i - select.dispheight + 1
-    select.cursor = select.dispheight - 1
-  elif i < select.si:
-    select.si = i
-    select.cursor = 0
-  else:
-    select.cursor = i - select.si
-
-proc cursorDown*(select: var Select) =
-  if select.hover < select.options.high and
-      select.cursor + select.y < select.maxh - 1:
-    inc select.cursor
-    select.redraw = true
-  elif select.si < select.options.len - select.maxh:
-    inc select.si
-    select.redraw = true
-
-proc cursorUp*(select: var Select) =
-  if select.cursor > 0:
-    dec select.cursor
-    select.redraw = true
-  elif select.si > 0:
-    dec select.si
-    select.redraw = true
-  elif select.multiple and select.cursor > -1:
-    select.cursor = -1
-
-proc close(select: var Select) =
-  select = Select()
-
-proc cancel*(select: var Select) =
-  select.submitFun(select.oselected)
-  select.close()
-
-proc submit(select: var Select) =
-  select.submitFun(select.selected)
-  select.close()
-
-proc click*(select: var Select) =
-  if not select.multiple:
-    select.selected = @[select.hover]
-    select.submit()
-  elif select.cursor == -1:
-    select.submit()
-  else:
-    var k = select.selected.len
-    let i = select.hover
-    for j in 0 ..< select.selected.len:
-      if select.selected[j] >= i:
-        k = j
-        break
-    if k < select.selected.len and select.selected[k] == i:
-      select.selected.delete(k)
-    else:
-      select.selected.insert(i, k)
-    select.redraw = true
-
-proc cursorLeft*(select: var Select) =
-  select.submit()
-
-proc cursorRight*(select: var Select) =
-  select.click()
-
-proc getCursorX*(select: var Select): int =
-  if select.cursor == -1:
-    return select.x
-  return select.x + 1
-
-proc getCursorY*(select: var Select): int =
-  return select.y + 1 + select.cursor
-
-proc cursorFirstLine*(select: var Select) =
-  if select.cursor != 0 or select.si != 0:
-    select.cursor = 0
-    select.si = 0
-    select.redraw = true
-
-proc cursorLastLine*(select: var Select) =
-  if select.hover < select.options.len:
-    select.cursor = select.dispheight - 1
-    select.si = max(select.options.len - select.maxh, 0)
-    select.redraw = true
-
-proc cursorNextMatch*(select: var Select, regex: Regex, wrap: bool) =
-  var j = -1
-  for i in select.hover + 1 ..< select.options.len:
-    if regex.exec(select.options[i]).success:
-      j = i
-      break
-  if j != -1:
-    select.hover = j
-    select.redraw = true
-  elif wrap:
-    for i in 0 ..< select.hover:
-      if regex.exec(select.options[i]).success:
-        j = i
-        break
-    if j != -1:
-      select.hover = j
-      select.redraw = true
-
-proc cursorPrevMatch*(select: var Select, regex: Regex, wrap: bool) =
-  var j = -1
-  for i in countdown(select.hover - 1, 0):
-    if regex.exec(select.options[i]).success:
-      j = i
-      break
-  if j != -1:
-    select.hover = j
-    select.redraw = true
-  elif wrap:
-    for i in countdown(select.options.high, select.hover):
-      if regex.exec(select.options[i]).success:
-        j = i
-        break
-    if j != -1:
-      select.hover = j
-      select.redraw = true
-
-proc pushCursorPos*(select: var Select) =
-  select.bpos.add(select.hover)
-
-proc popCursorPos*(select: var Select, nojump = false) =
-  select.hover = select.bpos.pop()
-  if not nojump:
-    select.redraw = true
-
-const HorizontalBar = $Rune(0x2500)
-const VerticalBar = $Rune(0x2502)
-const CornerTopLeft = $Rune(0x250C)
-const CornerTopRight = $Rune(0x2510)
-const CornerBottomLeft = $Rune(0x2514)
-const CornerBottomRight = $Rune(0x2518)
-
-proc drawBorders(display: var FixedGrid, sx, ex, sy, ey: int,
-    upmore, downmore: bool) =
-  for y in sy .. ey:
-    var x = 0
-    while x < sx:
-      if display[y * display.width + x].str == "":
-        display[y * display.width + x].str = " "
-        inc x
-      else:
-        #x = display[y * display.width + x].str.twidth(x)
-        inc x
-  # Draw corners.
-  let tl = if upmore: VerticalBar else: CornerTopLeft
-  let tr = if upmore: VerticalBar else: CornerTopRight
-  let bl = if downmore: VerticalBar else: CornerBottomLeft
-  let br = if downmore: VerticalBar else: CornerBottomRight
-  const fmt = newFormat()
-  display[sy * display.width + sx].str = tl
-  display[sy * display.width + ex].str = tr
-  display[ey * display.width + sx].str = bl
-  display[ey * display.width + ex].str = br
-  display[sy * display.width + sx].format = fmt
-  display[sy * display.width + ex].format = fmt
-  display[ey * display.width + sx].format = fmt
-  display[ey * display.width + ex].format = fmt
-  # Draw top, bottom borders.
-  let ups = if upmore: " " else: HorizontalBar
-  let downs = if downmore: " " else: HorizontalBar
-  for x in sx + 1 .. ex - 1:
-    display[sy * display.width + x].str = ups
-    display[ey * display.width + x].str = downs
-    display[sy * display.width + x].format = fmt
-    display[ey * display.width + x].format = fmt
-  if upmore:
-    display[sy * display.width + sx + (ex - sx) div 2].str = ":"
-  if downmore:
-    display[ey * display.width + sx + (ex - sx) div 2].str = ":"
-  # Draw left, right borders.
-  for y in sy + 1 .. ey - 1:
-    display[y * display.width + sx].str = VerticalBar
-    display[y * display.width + ex].str = VerticalBar
-    display[y * display.width + sx].format = fmt
-    display[y * display.width + ex].format = fmt
-
-proc drawSelect*(select: Select, display: var FixedGrid) =
-  if display.width < 2 or display.height < 2:
-    return # border does not fit...
-  # Max width, height with one row/column on the sides.
-  let mw = display.width - 2
-  let mh = display.height - 2
-  var sy = select.y
-  let si = select.si
-  var ey = min(sy + select.options.len, mh) + 1
-  var sx = select.x
-  if sx + select.maxw >= mw:
-    sx = display.width - select.maxw
-    if sx < 0:
-      # This means the widest option is wider than the available screen.
-      # w3m simply cuts off the part that doesn't fit, and we do that too,
-      # but I feel like this may not be the best solution.
-      sx = 0
-  var ex = min(sx + select.maxw, mw) + 1
-  let upmore = select.si > 0
-  let downmore = select.si + mh < select.options.len
-  drawBorders(display, sx, ex, sy, ey, upmore, downmore)
-  if select.multiple and not upmore:
-    display[sy * display.width + sx].str = "X"
-  # move inside border
-  inc sy
-  inc sx
-  var r: Rune
-  var k = 0
-  var format = newFormat()
-  while k < select.selected.len and select.selected[k] < si:
-    inc k
-  for y in sy ..< ey:
-    let i = y - sy + si
-    var j = 0
-    var x = sx
-    let dls = y * display.width
-    if k < select.selected.len and select.selected[k] == i:
-      format.reverse = true
-      inc k
-    else:
-      format.reverse = false
-    while j < select.options[i].len:
-      fastRuneAt(select.options[i], j, r)
-      let rw = r.twidth(x)
-      let ox = x
-      x += rw
-      if x > ex:
-        break
-      display[dls + ox].str = $r
-      display[dls + ox].format = format
-    while x < ex:
-      display[dls + x].str = " "
-      display[dls + x].format = format
-      inc x