Commit ce5f3ee1a5669d017e02074e0dfbbdf773171400

Thomas de Grivel 2022-02-25T07:42:21

space, backspace and tab

diff --git a/lib/exterm.ex b/lib/exterm.ex
index 402409b..bccf0a1 100644
--- a/lib/exterm.ex
+++ b/lib/exterm.ex
@@ -42,9 +42,10 @@ defmodule Exterm do
     context = :wxGLContext.new(canvas)
     :wxGLCanvas.setCurrent(canvas, context)
     setup_gl(canvas)
-    state = %{canvas: canvas,
+    state = %{bell: false,
+              canvas: canvas,
               font: font,
-              lines: ['$>_hello_world_!  ',
+              lines: ['$>_hello_world_!  ' |> Enum.reverse(),
                       'plop',
                       'hop',
                       'toto toto']}
@@ -96,17 +97,31 @@ defmodule Exterm do
 
   def handle_event({:wx, _, _, _, {:wxKey, :char, _, _, code, _, _, _, _, _, _, _}}, state) do
     IO.inspect([code])
-    lines = if [code] == '\r' do
-      [[] | state.lines]
-    else
-      first_line = hd(state.lines) ++ [code]
-      [first_line | tl(state.lines)]
-    end
-    state = %{state | lines: lines}
+    state = state
+    |> state_input_char([code])
     :wx.batch(fn -> render(state) end)
     {:noreply, state}
   end
 
+  defp state_input_char(state = %{lines: lines}, '\r') do
+    %{state | lines: [[] | reverse_first_line(lines)]}
+  end
+  defp state_input_char(state = %{lines: []}, '\b') do
+    %{state | bell: true}
+  end
+  defp state_input_char(state = %{lines: [[] | rest]}, '\b') do
+    %{state | lines: rest}
+  end
+  defp state_input_char(state = %{lines: [[_ | rest] | lines_rest]}, '\b') do
+    %{state | lines: [rest | lines_rest]}
+  end
+  defp state_input_char(state = %{lines: []}, char) do
+    %{state | lines: [char]}
+  end
+  defp state_input_char(state = %{lines: [first | rest]}, [char]) do
+    state = %{state | lines: [[char | first] | rest]}
+  end
+
   def handle_event(data, state) do
     IO.inspect({:handle_event, data, state})
     {:noreply, state}
@@ -142,7 +157,7 @@ defmodule Exterm do
   end
 
   defp draw(font, lines) do
-    wrapped = lines |> wrap(80, 25)
+    wrapped = lines |> reverse_first_line() |> wrap(80, 25)
     lists = wrapped
     |> Enum.map(fn line ->
       Enum.map(line, fn c ->
@@ -159,6 +174,9 @@ defmodule Exterm do
     end)
   end
 
+  def reverse_first_line([]), do: []
+  def reverse_first_line([first | rest]), do: [first |> Enum.reverse() | rest]
+
   def wrap(input, w, h) when is_list(input) do
     input
     |> Enum.slice(0..h)
@@ -177,6 +195,15 @@ defmodule Exterm do
     line = acc |> Enum.reverse()
     wrap(input, w, [line | lines], 0, [])
   end
+  def wrap([[9 | rest] | rest1], w, lines, x, acc) do
+    len = Enum.count(acc)
+    r = 8 - rem(len, 8)
+    r = if r == 0, do: 8, else: r
+    acc1 = 1..r
+    |> Enum.reduce(acc, fn _, acc -> [32 | acc] end)
+    IO.inspect([len: len, r: r, acc1: acc1])
+    wrap([rest | rest1], w, lines, x + r, acc1)
+  end
   def wrap([[c | rest] | rest1], w, lines, x, acc) do
     wrap([rest | rest1], w, lines, x + 1, [c | acc])
   end
diff --git a/lib/exterm/font.ex b/lib/exterm/font.ex
index 5bab960..c1772b5 100644
--- a/lib/exterm/font.ex
+++ b/lib/exterm/font.ex
@@ -33,7 +33,7 @@ defmodule Exterm.Font do
       :gl.clearColor(1.0, 1.0, 1.0, 0.0)
       :gl.color4f(0.0, 0.0, 0.0, 1.0)
       :gl.clear(:gl_const.gl_color_buffer_bit)
-      :ok = render_glyph(font, codepoint)
+      render_glyph(font, codepoint)
       w = 24
       h = 32
       size = w * h * 8
@@ -60,6 +60,8 @@ defmodule Exterm.Font do
     end
   end
 
+  def render_glyph(_, 32) do
+  end
   def render_glyph(font, codepoint) do
     ttf = ttf(font.family)
     if glyph = TTF.glyph(ttf, codepoint) do