gigaTerminal text editor | 
          
| git clone git://git.dimitrijedobrota.com/giga.git | 
| Log | Files | Refs | README | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING | 
| commit | 6d35b46728c76b2e9ca7d1ee62ba214d3f35a903 | 
| parent | db345023355929e573412087179e5516f228d04f | 
| author | Dimitrije Dobrota < mail@dimitrijedobrota.com > | 
| date | Thu, 6 Mar 2025 23:18:58 +0100 | 
Restructure, refactor and make usable, for now...
| M | CMakeLists.txt | | | + - | 
| M | CMakePresets.json | | | + - | 
| M | source/layout_dynamic.cpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ --------------- | 
| M | source/layout_dynamic.hpp | | | +++++++++++++++++++++++ ----------------------------------------------------------- | 
| M | source/main.cpp | | | +++++++++++++++++++++++++ ------------------- | 
5 files changed, 348 insertions(+), 381 deletions(-)
diff --git a/ CMakeLists.txt b/ CMakeLists.txt
          @@ -4,7 +4,7 @@ 
          include(cmake/prelude.cmake)
        
        
          project(
              giga
              VERSION 0.1.11
              VERSION 0.1.12
              DESCRIPTION "Terminal text editor"
              HOMEPAGE_URL "https://git.dimitrijedobrota.com/giga.git"
              LANGUAGES CXX
        
        diff --git a/ CMakePresets.json b/ CMakePresets.json
@@ -40,7 +40,7 @@
      "name": "clang-tidy",
                "hidden": true,
                "cacheVariables": {
                  "CMAKE_CXX_CLANG_TIDY": "clang-tidy;--header-filter=^${sourceDir}/"
                  "CMAKE_CXX_CLANG_TIDY": "clang-tidy;--header-filter=^${sourceDir}/;--checks=exhaustive"
                }
              },
              {
        
        diff --git a/ source/layout_dynamic.cpp b/ source/layout_dynamic.cpp
@@ -1,68 +1,227 @@
#include <stack>
          #include <stdexcept>
          #include "layout_dynamic.hpp"
          namespace display
          {
          int WindowTest::counter = 0;
          void Panel::resize(plc_t aplc)
          {
            std::stack<std::pair<plc_t, Panel*>> stk;
            stk.emplace(aplc, this);
            while (!stk.empty()) {
              auto [plc, crnt] = stk.top();
              stk.pop();
              std::visit(
                  [&]<typename M>(M& var)
                  {
                    var.resize(plc);
                    if constexpr (!std::is_same_v<M, layout_t>) {
                      auto& panels = var.panels();
                      for (std::size_t i = 0; i < panels.size(); i++) {
                        stk.emplace(var.place(i, panels.size()), panels[i].get());
                      }
                    }
                  },
                  crnt->m_payload);
            }
          }
          void LayoutDynamic::input(event& evnt)
          void Panel::render() const
          {
            if (evnt.type() == event::Type::KEY) {
              if (evnt.key() == 'e') {
                m_sel = m_sel->split<Type::Horizontal>();
                m_sel->layout().emplace_child();
                render();
                evnt.type() = event::Type::NONE;
                return;
              }
            std::stack<const Panel*> stk;
            stk.emplace(this);
            while (!stk.empty()) {
              const auto* crnt = stk.top();
              stk.pop();
              std::visit(
                  [&]<typename M>(const M& var)
                  {
                    if constexpr (std::is_same_v<M, layout_t>) {
                      var.render();
                    }
                    if constexpr (!std::is_same_v<M, layout_t>) {
                      for (const auto& panel : var.panels()) {
                        stk.emplace(panel.get());
                      }
                    }
                  },
                  crnt->m_payload);
            }
          }
              if (evnt.key() == 'r') {
                m_sel = m_sel->split<Type::Vertical>();
                m_sel->layout().emplace_child();
                render();
                evnt.type() = event::Type::NONE;
                return;
          Panel* Panel::close()
          {
            const auto visit_parent = [&]<typename M>(M& pcont) -> Panel*
            {
              if constexpr (std::is_same_v<M, layout_t>) {
                throw std::runtime_error("Invalid node handle [close() layout_t]");
              }
              if (evnt.key() == 'x') {
                m_sel = m_sel->close();
                if (m_sel != nullptr) {
                  render();
              if constexpr (!std::is_same_v<M, layout_t>) {
                // need this here because 'this' is going to deleted
                auto* parent = m_parent;
                const auto pos = get_elem().apos();
                pcont.panels().erase(pcont.find_child(this));
                // 'this' is not to be used anymore
                if (pcont.panels().size() > 1) {
                  parent->resize(pcont.aplc());
                  return parent->select(pos);
                }
                evnt.type() = event::Type::NONE;
                return;
                // one child left, no need for Panel anymore
                // need this here because this is going to overridden
                auto payload = std::move(pcont.panels()[0]->m_payload);
                const auto aplc = pcont.aplc();
                parent->m_payload = std::move(payload);
                // pcnot is not to be used anymore
                // re-parent if needed
                std::visit(
                    [&]<typename L>(L& val)
                    {
                      if constexpr (!std::is_same_v<L, layout_t>) {
                        for (const auto& panel : val.panels()) {
                          panel->m_parent = parent;
                        }
                      }
                    },
                    parent->m_payload);
                parent->resize(aplc);
                return parent->select(aplc.pos);
              }
            };
            if (m_parent == nullptr) {
              // I am the last one
              return nullptr;
            }
              if (evnt.key() == 'w') {
                m_sel = m_container.select(m_sel, Direction::Up);
                render();
                evnt.type() = event::Type::NONE;
                return;
            return std::visit(visit_parent, m_parent->m_payload);
          }
          Panel* Panel::select(Panel* sel, Direction dir)
          {
            const auto& sele = sel->get_elem();
            pos_t tpos = {0, 0};
            switch (dir) {
              case Direction::Up:
                tpos = sele.apos() + pos_t(0, -1);
                break;
              case Direction::Left:
                tpos = sele.apos() + pos_t(-1, 0);
                break;
              case Direction::Down:
                tpos = sele.apos() + pos_t(0UL, sele.ahgt().value());
                break;
              case Direction::Right:
                tpos = sele.apos() + pos_t(sele.awth().value(), 0UL);
                break;
            }
            const auto& roote = get_elem();
            if (!(roote.apos() <= tpos && tpos < roote.apos() + roote.adim())) {
              return sel;
            }
            return select(tpos);
          }
          Panel* Panel::select(pos_t tpos)
          {
            Panel* crnt = this;
            while (true) {
              auto* next = std::visit(
                  [&]<typename M>(const M& val) -> Panel*
                  {
                    if constexpr (std::is_same_v<M, layout_t>) {
                      return nullptr;
                    }
                    if constexpr (!std::is_same_v<M, layout_t>) {
                      for (const auto& panel : val.panels()) {
                        const auto plc = panel->get_elem().aplc();
                        if (plc.pos <= tpos && tpos < plc.pos + plc.dim) {
                          return panel.get();
                        }
                      }
                      throw std::runtime_error("Something's wrong, I can feel it!");
                    }
                  },
                  crnt->m_payload);
              if (next == nullptr) {
                return crnt;
              }
              if (evnt.key() == 'a') {
                m_sel = m_container.select(m_sel, Direction::Left);
                render();
                evnt.type() = event::Type::NONE;
                return;
              crnt = next;
            }
          }
          template<Panel::Split T>
          Panel* Panel::split()
          {
            const auto visit_parent = [&]<typename M>(M& pcont) -> Panel*
            {
              if constexpr (std::is_same_v<M, layout_t>) {
                throw std::runtime_error("Invalid node handle [split() layout_t]");
              }
              if (evnt.key() == 's') {
                m_sel = m_container.select(m_sel, Direction::Down);
                render();
                evnt.type() = event::Type::NONE;
                return;
              if constexpr (!std::is_same_v<M, layout_t>) {
                if constexpr (M::type() != T) {
                  return nullptr;
                }
                auto itr = pcont.panels().emplace(
                    pcont.find_child(this) + 1,
                    std::make_unique<Panel>(m_parent, plc_t({0, 0}, {0, 0})));
                m_parent->resize(pcont.aplc());
                return itr->get();
              }
            };
              if (evnt.key() == 'd') {
                m_sel = m_container.select(m_sel, Direction::Right);
                render();
                evnt.type() = event::Type::NONE;
                return;
            // can it by handled by the parent?
            if (m_parent != nullptr) {
              auto* ret = std::visit(visit_parent, m_parent->m_payload);
              if (ret != nullptr) {
                return ret;
              }
            }
            m_sel->layout().input(evnt);
            // Nope I'll do it myself
            const auto aplc = std::get<layout_t>(m_payload).aplc();
            auto child = std::get<layout_t>(m_payload).release_child();
            auto& container = m_payload.emplace<Container<T>>(aplc);
            // var is not to be used anymore
            container.panels().emplace_back(
                std::make_unique<Panel>(this, container.place(0, 2), std::move(child)));
            container.panels().emplace_back(
                std::make_unique<Panel>(this, container.place(1, 2)));
            return container.panels().back().get();
          }
          template Panel* Panel::split<Panel::Split::Horizontal>();
          template Panel* Panel::split<Panel::Split::Vertical>();
          }  // namespace display
        
        diff --git a/ source/layout_dynamic.hpp b/ source/layout_dynamic.hpp
@@ -1,364 +1,134 @@
#pragma once
          #include <memory>
          #include <stack>
          #include <stdexcept>
          #include <variant>
          #include <vector>
          #include "display/element.hpp"
          #include "display/layout.hpp"
          #include "display/window.hpp"
          namespace display
          {
          class WindowTest : public Window
          class Panel
          {
          public:
            explicit WindowTest(plc_t aplc)
                : Window(aplc, {1, 1})
            {
            }
            using layout_t = Layout<Element>;
            void render() const override
            enum class Split : std::uint8_t
            {
              line_reset();
              line_right(std::to_string(m_num));
              Window::render_border();
            }
            static int counter;
            int m_num = ++counter;
          };
          enum class Type : std::uint8_t
          {
            Horizontal,
            Vertical,
          };
          enum class Direction : std::uint8_t
          {
            Up,
            Left,
            Down,
            Right
          };
              Horizontal,
              Vertical,
            };
          class Container;
          template<Type T>
          class PanelContainer : public Element
          {
          public:
            explicit PanelContainer(plc_t aplc)
                : Element(aplc)
            enum class Direction : std::uint8_t
            {
            }
            static constexpr Type type() { return T; }
            const auto& panels() const { return m_panels; }
            auto& panels() { return m_panels; }
              Up,
              Left,
              Down,
              Right
            };
            plc_t place(std::size_t idx, std::size_t size) const;
            auto find_child(Container* child)
            {
              return std::find_if(m_panels.begin(),
                                  m_panels.end(),
                                  [&](const auto& ptr) { return ptr.get() == child; });
            }
          private:
            std::vector<std::unique_ptr<Container>> m_panels;
          };
          using PanelHorizontal = PanelContainer<Type::Horizontal>;  // NOLINT
          using PanelVertical = PanelContainer<Type::Vertical>;  // NOLINT
          template<>
          inline plc_t PanelHorizontal::place(std::size_t idx, std::size_t size) const
          {
            if (idx + 1 == size) {
              const auto unit = (awth() / size) * (size - 1);
              const auto wth = awth() - unit;
              const auto xpos = axpos() + unit;
              return {{xpos, aypos()}, {wth, ahgt()}};
            }
            const auto wth = awth() / size;
            const auto xpos = axpos() + wth * idx;
            return {{xpos, aypos()}, {wth, ahgt()}};
          }
          template<>
          inline plc_t PanelVertical::place(std::size_t idx, std::size_t size) const
          {
            if (idx + 1 == size) {
              const auto unit = (ahgt() / size) * (size - 1);
              const auto ypos = aypos() + unit;
              const auto hgt = ahgt() - unit;
              return {{axpos(), ypos}, {awth(), hgt}};
            }
            const auto hgt = ahgt() / size;
            const auto ypos = aypos() + hgt * idx;
            return {{axpos(), ypos}, {awth(), hgt}};
          }
          class Container
          {
          public:
            using layout_t = Layout<WindowTest>;
            Container(Container* parent, plc_t aplc, layout_t::ptr_t&& child)
            Panel(Panel* parent, plc_t aplc, layout_t::ptr_t&& child)
                : m_parent(parent)
                , m_payload(layout_t(aplc, std::move(child)))
            {
            }
            explicit Container(Container* parent, plc_t aplc)
            explicit Panel(Panel* parent, plc_t aplc)
                : m_parent(parent)
                , m_payload(layout_t(aplc))
            {
            }
            auto& layout() { return std::get<layout_t>(m_payload); }
            layout_t& layout() { return std::get<layout_t>(m_payload); }
            void resize(plc_t aplc)
            {
              std::stack<std::pair<plc_t, Container*>> stk;
              stk.emplace(aplc, this);
              while (!stk.empty()) {
                auto [plc, crnt] = stk.top();
                stk.pop();
                std::visit(
                    [&]<typename M>(M& var)
                    {
                      var.resize(plc);
                      if constexpr (!std::is_same_v<M, layout_t>) {
                        auto& panels = var.panels();
                        for (std::size_t i = 0; i < panels.size(); i++) {
                          stk.emplace(var.place(i, panels.size()), panels[i].get());
                        }
                      }
                    },
                    crnt->m_payload);
              }
            }
            void resize(plc_t aplc);
            void render() const;
            void render() const
            {
              std::stack<const Container*> stk;
              stk.emplace(this);
              while (!stk.empty()) {
                const auto* crnt = stk.top();
                stk.pop();
                std::visit(
                    [&]<typename M>(const M& var)
                    {
                      if constexpr (std::is_same_v<M, layout_t>) {
                        var.render();
                      }
                      if constexpr (!std::is_same_v<M, layout_t>) {
                        for (const auto& panel : var.panels()) {
                          stk.emplace(panel.get());
                        }
                      }
                    },
                    crnt->m_payload);
              }
            }
            template<Split T>
            Panel* split();
            template<Type T>
            Container* split()
            {
              const auto visit_parent = [&]<typename M>(M& pcont) -> Container*
              {
                if constexpr (std::is_same_v<M, layout_t>) {
                  throw std::runtime_error("Invalid node handle [split() layout_t]");
                }
            Panel* close();
            Panel* select(Panel* sel, Direction dir);
                if constexpr (!std::is_same_v<M, layout_t>) {
                  if constexpr (M::type() != T) {
                    return nullptr;
                  }
                  auto itr = pcont.panels().emplace(
                      pcont.find_child(this) + 1,
                      std::make_unique<Container>(m_parent, plc_t({0, 0}, {0, 0})));
          private:
            const Element& get_elem() const
            {
              return std::visit([](const auto& val) -> const Element& { return val; },
                                m_payload);
            }
                  m_parent->resize(pcont.aplc());
            Panel* select(pos_t tpos);
                  return itr->get();
                }
              };
            template<Split M>
            class Container : public Element
            {
            public:
              using ptr_t = std::unique_ptr<Panel>;
              using container_t = std::vector<ptr_t>;
              // can it by handled by the parent?
              if (m_parent != nullptr) {
                auto* ret = std::visit(visit_parent, m_parent->m_payload);
                if (ret != nullptr) {
                  return ret;
                }
              explicit Container(plc_t aplc)
                  : Element(aplc)
              {
              }
              // Nope I'll do it myself
              const auto aplc = std::get<layout_t>(m_payload).aplc();
              auto child = std::get<layout_t>(m_payload).release_child();
              auto& con = m_payload.emplace<PanelContainer<T>>(aplc);
              // var is not to be used anymore
              con.panels().emplace_back(
                  std::make_unique<Container>(this, con.place(0, 2), std::move(child)));
              static constexpr Split type() { return M; }
              con.panels().emplace_back(
                  std::make_unique<Container>(this, con.place(1, 2)));
              const container_t& panels() const { return m_panels; }
              container_t& panels() { return m_panels; }
              return con.panels().back().get();
            }
            Container* close()
            {
              const auto visit_parent = [&]<typename M>(M& pcont) -> Container*
              plc_t place(std::size_t idx, std::size_t size) const
              {
                if constexpr (std::is_same_v<M, layout_t>) {
                  throw std::runtime_error("Invalid node handle [close() layout_t]");
                }
                if constexpr (M == Split::Horizontal) {
                  if (idx + 1 == size) {
                    const auto unit = (awth() / size) * (size - 1);
                    const auto wth = awth() - unit;
                    const auto xpos = axpos() + unit;
                if constexpr (!std::is_same_v<M, layout_t>) {
                  // need this here because 'this' is going to deleted
                  auto* parent = m_parent;
                  const auto pos = get_elem().apos();
                  pcont.panels().erase(pcont.find_child(this));
                  // 'this' is not to be used anymore
                  if (pcont.panels().size() > 1) {
                    parent->resize(pcont.aplc());
                    return parent->select(pos);
                    return {{xpos, aypos()}, {wth, ahgt()}};
                  }
                  // one child left, no need for Panel anymore
                  // need this here because this is going to overridden
                  auto payload = std::move(pcont.panels()[0]->m_payload);
                  const auto aplc = pcont.aplc();
                  parent->m_payload = std::move(payload);
                  // pcnot is not to be used anymore
                  // re-parent if needed
                  std::visit(
                      [&]<typename L>(L& val)
                      {
                        if constexpr (!std::is_same_v<L, layout_t>) {
                          for (auto& panel : val.panels()) {
                            panel->m_parent = parent;
                          }
                        }
                      },
                      parent->m_payload);
                  parent->resize(aplc);
                  return parent->select(aplc.pos);
                }
              };
              if (m_parent == nullptr) {
                // I am the last one
                return nullptr;
              }
              return std::visit(visit_parent, m_parent->m_payload);
            }
            Container* select(Container* sel, Direction dir)
            {
              const auto& sele = sel->get_elem();
              pos_t tpos = {0, 0};
              switch (dir) {
                case Direction::Up:
                  tpos = sele.apos() + pos_t(0, -1);
                  break;
                case Direction::Left:
                  tpos = sele.apos() + pos_t(-1, 0);
                  break;
                case Direction::Down:
                  tpos = sele.apos() + pos_t(0UL, sele.ahgt().value());
                  break;
                case Direction::Right:
                  tpos = sele.apos() + pos_t(sele.awth().value(), 0UL);
                  break;
              }
                  const auto wth = awth() / size;
                  const auto xpos = axpos() + wth * idx;
              const auto& roote = get_elem();
              if (!(roote.apos() <= tpos && tpos < roote.apos() + roote.adim())) {
                return sel;
              }
                  return {{xpos, aypos()}, {wth, ahgt()}};
                } else {
                  if (idx + 1 == size) {
                    const auto unit = (ahgt() / size) * (size - 1);
                    const auto ypos = aypos() + unit;
                    const auto hgt = ahgt() - unit;
              return select(tpos);
            }
                    return {{axpos(), ypos}, {awth(), hgt}};
                  }
          private:
            const Element& get_elem() const
            {
              return std::visit([](const auto& val) -> const Element& { return val; },
                                m_payload);
            }
                  const auto hgt = ahgt() / size;
                  const auto ypos = aypos() + hgt * idx;
            Container* select(pos_t tpos)
            {
              Container* crnt = this;
              while (true) {
                auto* next = std::visit(
                    [&]<typename M>(const M& val) -> Container*
                    {
                      if constexpr (std::is_same_v<M, layout_t>) {
                        return nullptr;
                      }
                      if constexpr (!std::is_same_v<M, layout_t>) {
                        for (const auto& panel : val.panels()) {
                          const auto plc = panel->get_elem().aplc();
                          if (plc.pos <= tpos && tpos < plc.pos + plc.dim) {
                            return panel.get();
                          }
                        }
                        throw std::runtime_error("Something's wrong, I can feel it!");
                      }
                    },
                    crnt->m_payload);
                if (next == nullptr) {
                  return crnt;
                  return {{axpos(), ypos}, {awth(), hgt}};
                }
              }
                crnt = next;
              container_t::iterator find_child(Panel* child)
              {
                return std::find_if(m_panels.begin(),
                                    m_panels.end(),
                                    [&](const auto& ptr) { return ptr.get() == child; });
              }
            }
            using payload_t = std::variant<layout_t, PanelHorizontal, PanelVertical>;
            private:
              container_t m_panels;
            };
            using payload_t = std::variant<layout_t,
                                           Container<Split::Horizontal>,
                                           Container<Split::Vertical>>;
            Container* m_parent;
            Panel* m_parent;
            payload_t m_payload;
          };
          template<typename T>
          class LayoutDynamic : public Element
          {
          public:
        
        
          @@ -366,21 +136,18 @@ 
          public:
        
        
                : Element(aplc)
                , m_container(nullptr, aplc)
            {
              m_sel->layout().emplace_child();
            }
            bool is_finished() const { return m_sel == nullptr; }
            void render() const override
            template<typename M = T, class... Args>
              requires(std::is_base_of_v<T, M>)
            M& emplace_child(Args&&... args)
            {
              Element::clear();
              m_container.render();
              std::cout << alec::foreground_v<alec::Color::RED>;
              m_sel->layout().get_child().render_border();
              std::cout << alec::foreground_v<alec::Color::DEFAULT>;
              std::cout << std::flush;
              return m_sel->layout().emplace_child<M>(std::forward<Args>(args)...);
            }
            bool is_finished() const { return m_sel == nullptr; }
            void render() const override { m_container.render(); }
            void resize(plc_t aplc) override
            {
              Element::resize(aplc);
        
        
          @@ -390,8 +157,43 @@ 
          public:
        
        
            void input(event& evnt) override;
          private:
            Container m_container;
            Container* m_sel = &m_container;
            Panel m_container;
            Panel* m_sel = &m_container;
          };
          template<typename T>
          void LayoutDynamic<T>::input(event& evnt)
          {
            if (evnt.type() == event::Type::KEY) {
              const auto* old = m_sel;
              if (evnt.key() == 'e') {
                const auto& child = m_sel->layout().get_child<T>();
                m_sel = m_sel->split<Panel::Split::Horizontal>();
                m_sel->layout().emplace_child<T>(child);
              } else if (evnt.key() == 'r') {
                const auto& child = m_sel->layout().get_child<T>();
                m_sel = m_sel->split<Panel::Split::Vertical>();
                m_sel->layout().emplace_child<T>(child);
              } else if (evnt.key() == 'x') {
                m_sel = m_sel->close();
              } else if (evnt.key() == 'w') {
                m_sel = m_container.select(m_sel, Panel::Direction::Up);
              } else if (evnt.key() == 'a') {
                m_sel = m_container.select(m_sel, Panel::Direction::Left);
              } else if (evnt.key() == 's') {
                m_sel = m_container.select(m_sel, Panel::Direction::Down);
              } else if (evnt.key() == 'd') {
                m_sel = m_container.select(m_sel, Panel::Direction::Right);
              } else {
                m_sel->layout().input(evnt);
              }
              if (m_sel != nullptr && m_sel != old) {
                render();
              }
              evnt.type() = event::Type::NONE;
              return;
            }
          }
          }  // namespace display
        
        diff --git a/ source/main.cpp b/ source/main.cpp
@@ -1,5 +1,6 @@
#include <filesystem>
          #include <fstream>
          #include <memory>
          #include <span>
          #include <string>
          #include <vector>
        
        @@ -13,36 +14,34 @@
class File
          {
          public:
            using container_t = std::vector<std::string>;
            explicit File(const std::filesystem::path& path)
                : m_lines(std::make_shared<container_t>())
            {
              std::ifstream ifs(path);
              std::string line;
              while (std::getline(ifs, line)) {
                m_lines.emplace_back(line);
                m_lines->emplace_back(line);
              }
            }
            File(const File&) = delete;
            File& operator=(const File&) = delete;
            File(File&&) = default;
            File& operator=(File&&) = default;
            ~File() = default;
            const auto& operator[](std::size_t idx) const { return m_lines[idx]; }
            auto& operator[](std::size_t idx) { return m_lines[idx]; }
            const auto& operator[](std::size_t idx) const
            {
              return m_lines->operator[](idx);
            }
            auto& operator[](std::size_t idx) { return m_lines->operator[](idx); }
            auto substr(std::size_t idx, std::size_t pos, std::size_t len) const
            {
              return pos < m_lines[idx].size() ? m_lines[idx].substr(pos, len) : "";
              return pos < operator[](idx).size() ? operator[](idx).substr(pos, len) : "";
            }
            auto size() const { return m_lines.size(); }
            auto size() const { return m_lines->size(); }
          private:
            std::vector<std::string> m_lines;
            std::shared_ptr<container_t> m_lines;
          };
          class PanelWindow : public display::Window
        
        
          @@ -257,6 +256,11 @@ 
          public:
        
        
            {
            }
            Panel(display::plc_t aplc, const Panel& panel)
                : Panel(aplc, panel.m_state.file)
            {
            }
            void resize(display::plc_t aplc) override
            {
              Element::resize(aplc);
        
        
          @@ -292,19 +296,19 @@ 
          public:
        
        
          private:
            display::plc_t place_num() const
            {
              return {display::pos_t(0, 0),
              return {apos() + display::pos_t(0, 0),
                      display::dim_t(get_linenuwidth(), (ahgt() - 1).value())};
            }
            display::plc_t place_info() const
            {
              return {display::pos_t(0U, (ahgt() - 1).value()),
              return {apos() + display::pos_t(0U, (ahgt() - 1).value()),
                      display::dim_t(awth(), display::hgt_t(1))};
            }
            display::plc_t place_editor() const
            {
              return {display::pos_t(get_linenuwidth(), 0U),
              return {apos() + display::pos_t(get_linenuwidth(), 0U),
                      display::dim_t(awth() - get_linenuwidth(), ahgt() - 1)};
            }
          
          @@ -336,9 +340,11 @@ 
          int main(const int argc, const char* argv[])
        
        
              return -1;
            }
            using editor_t = display::LayoutDynamic<Panel>;
            auto& inst = display::Display::display();
            // inst.layout().set_child<Panel>(File(args[1]));
            const auto& layout = inst.layout().emplace_child<display::LayoutDynamic>();
            auto& layout = inst.layout().emplace_child<editor_t>();
            layout.emplace_child(File(args[1]));
            inst.render();
            while (true) {