2P by GN⁺ 8시간전 | ★ favorite | 댓글 1개
  • 90년대 Borland의 텍스트 UI 프레임워크를 크로스플랫폼+유니코드로 현대화한 오픈소스 포트
  • 터미널 앱 만들 때 터미널 호환성 처리 불필요 - Linux, Windows, DOS에서 동일 코드로 동작함
  • 리사이즈 가능한 오버래핑 윈도우, 풀다운 메뉴, 다이얼로그, 버튼, 스크롤바, 입력박스, 체크박스, 라디오버튼TUI 위젯이 이미 내장되어 있어서 직접 구현할 필요 없이 가져다 쓰면 됨
  • UTF-8 유니코드 전면 지원 — 기존 char 기반 API를 유지하면서도 CJK 전각 문자, 결합 문자, 이모지까지 처리 가능하고, moveStr() 한 줄이면 멀티바이트 스크롤링·잘림 처리가 자동
  • Microsoft RTL의 UTF-8 setlocale 지원을 활용해 std::ifstream f("コンピュータ.txt") 같은 코드가 Windows에서도 그대로 동작
  • 24비트 트루컬러 지원 — 기존 16색에서 RGB, xterm-256, 터미널 기본색까지 확장되었고, 터미널이 지원 안 하면 자동으로 가장 가까운 색상으로 양자화 처리
  • 마우스 휠, 중간 버튼, 트리플 클릭, 32767행/열까지의 화면 크기, 창 리사이즈 이벤트 등 현대적 입력/출력을 모두 지원
  • 시스템 클립보드 연동 기본 내장: Windows/macOS는 바로 동작하고, SSH 원격 환경에서도 X11 포워딩이나 OSC 52 이스케이프 코드를 통해 복사/붙여넣기 가능
  • 기존 Borland C++ 시절 Turbo Vision 소스코드를 최소 수정으로 그대로 빌드 가능
  • CMake 빌드 시스템 지원, vcpkg로 ./vcpkg install tvision 한 줄이면 설치 완료, CMake 서브모듈로 add_subdirectory 추가하면 의존성 자동 링크
  • C++14 이상, libncursesw 필요 / MIT 라이선스
Hacker News 의견들
  • 이 저장소가 프런트 페이지에 올라온 걸 보니 정말 반갑고, 지금은 이 저장소용 wrapper를 직접 만들고 있음
    .Net 위에서 macOS로 Turbo Vision을 돌리고 있는데 꽤 마법 같은 느낌을 줌
    더 높은 수준의 API를 제공하고, 꽤 구식인 palette API도 감싸거나 개선하고, layout도 추가하는 중임
    아직은 비공개 저장소에서 한창 작업 중이고, 오늘은 컨트롤이 놓인 surface 기준으로 palette를 잡고 내일은 또 다른 부분을 다듬는 식으로 계속 손보고 있음
    layout 정리, 요즘 기준으로 빠진 기본 컨트롤 추가 같은 할 일도 남아 있음
    예전에 Terminal.Gui도 써봤는데 v2 전환 중이라 그런지 버그 없이 다루기 꽤 어려웠고, Claude도 실제 터미널 고려 없이 TUI 라이브러리를 만들면 무엇을 하면 안 되는지 잘 보여줬음
    그래서 현대판 Turbo Vision이 있으면 좋겠다고 생각하던 차에 이 저장소를 발견했고, Unicode 지원까지 들어간 걸 보고 정말 고마웠음

    • Oxygene은 RemObjects의 Elements 제품군 일부라서, Pascal 계열 Oxygene 말고도 여러 인기 언어를 섞어 쓰면서 Windows, macOS, Linux, Android 등으로 가져갈 수 있음
      https://www.remobjects.com/elements/oxygene/
      https://www.remobjects.com/elements/
    • 나도 이 tvision 포트로 작업해봤는데, 새 TUI 프레임워크를 만질 때마다 결국 Turbo Vision 쪽이 더 낫다고 느끼게 됨
      나 역시 .NET wrapper를 만들고 있고, 아마 진도는 덜 나갔지만 Windows Forms API를 최대한 비슷하게 흉내 내면서 drag-and-drop TUI 디자이너까지 넣고 싶음
      예제는 여기 있음: https://github.com/brianluft/terminalforms/tree/main/src/TerminalFormsDemo
      C++ 쪽의 까다로운 통합 작업은 대부분 여기서 처리했음: https://github.com/brianluft/terminalforms/tree/main/src/tfcore
      P/Invoke로 부를 수 있게 단순한 C 함수들을 export해 두고, C# 쪽은 주로 클래스 구조화에 집중하게 했음
      처음에는 C++에서 가능한 건 전부 C#에서도 가능해야 한다고 밀어붙였는데 너무 복잡해졌고, placement new로 C++ 객체를 C# 버퍼 안에 넣어서 사실상 C# 쪽에서 C++ 클래스를 상속하는 수준까지 갔다가 설계가 무너졌음
      결국 더 직접적이고 유연성은 덜하지만 훨씬 단순한 접근으로 바꿨고, 유연성은 C# 쪽에 두기로 했음
      당신의 P/Invoke 시스템은 어떻게 구성했는지 궁금함
    • 이 TV 라이브러리를 만지면 향수를 제대로 긁어줘서 즐거움
      덕분에 GEOS용 앱을 만든다거나 1인 Hurd 팀에 들어간다거나 하는 헛된 시도를 안 하게 된 것 같음
    • 나도 같은 걸 해보고 싶었음
      Terminal.Gui를 써보긴 했지만 TV 쪽이 더 끌려서 wrapper를 고민했었고, 공개되면 정말 보고 싶음
  • 내 프로그래밍 경력은 말 그대로 90년대에 쓰레기통에서 시작됐음
    누가 버린 Turbo Vision 책을 주웠고, 누구나 만들 수 있던 푸른빛 TUI에 바로 반해버렸음

  • 원래 버전은 Turbo Pascal 6에 들어 있었고, C++ 포트는 나중에 나왔음
    그러니 이건 포트의 현대식 포트라고 보면 됨
    Borland는 다른 프레임워크도 비슷했는데, OWL도 원래는 Turbo Pascal for Windows 1.5 쪽이 먼저였고, C++ Builder 도구 상당수도 사실 Delphi로 작성됐음
    Turbo Pascal 5.5의 Object Pascal, 그리고 6의 Turbo Vision이 내 OOP 입문이었는데 그 길로 들어간 건 운이 좋았다고 느낌
    MS-DOS 같은 환경에서도 OOP와 Turbo Vision이 주는 프레임워크의 장점을 제대로 배울 수 있었음

    • 재미있는 건 Free Vision은 한때 퍼블릭 도메인으로 풀린 C++판을 누군가 수동 번역해서 다시 Object/Free Pascal로 옮긴 결과물이라는 점임
    • OWL은 정말 시대를 앞서갔음
  • Borland가 Turbo Pascal, Turbo C++, TurboVision을 내놓았을 때 가능성의 우주가 확 펼쳐졌다고 느꼈음
    컴파일러 성능도 훌륭했고 매뉴얼은 예술품 같았는데, 그 책들을 아직 갖고 있었으면 좋겠음
    이건 그냥 문화적 보물임

    • 매뉴얼들은 정말 대단했음
      90년대 초반에 C/C++를 거의 Turbo C++와 함께 온 Borland 책 더미만 읽으면서 독학했는데, 요즘은 참고서만 읽고 그렇게 배우는 장면을 상상하기조차 어려움
    • Turbo Vision은 오랫동안 내 기준 황금 표준 같은 존재였음
      새 TUI 프레임워크들은 늘 뭔가 빠진 느낌이 있었고, 이제 이걸 다시 써보면서 그게 단순한 향수였는지 확인해볼 생각임
      다음 도구에 넣어볼 예정이고, 만든 사람들에게 크게 박수 보내고 싶음
    • Borland 올인이었던 시절이 있었음
      GW-BASIC과 MS-DOS를 빼면 Turbo BASIC, Turbo Pascal, Turbo C++ for MS-DOS and Windows 3.x, Turbo Vision, OWL까지 전부 Borland였음
      VC++는 5 버전쯤 들어가서 썼는데 MFC는 Borland 제품들에 비하면 늘 너무 밋밋하게 느껴졌음
      지금도 C++ Builder의 RAD 역량을 제대로 따라오는 건 드물고, .NET도 Delphi 같은 저수준 코딩과 AOT 스토리를 정리하는 데 꽤 오랜 시간이 걸렸음
      Go, C++, Rust 개발자들에게 MS-DOS용 Turbo Pascal 7이랑 최신 Delphi를 몇 부씩 쥐여줘야 한다고 봄
  • Turbo Vision 2.0은 지금도 꽤 실용적이라서, 1년 전에 프로토타입 작업에 직접 써봤음
    LLDB 디버거용 Turbo Vision 프런트엔드를 만들어서 Borland의 Turbo Debugger처럼 동작하게 해보려 했고, 대부분은 뜻대로 됐음
    199x년에 멈춘 자리를 그대로 이어받은 느낌이라 놀라웠고, 1993년 코드를 큰 문제 없이 컴파일하고 실행할 수도 있었음
    내부 에디터도 Scintilla 기반으로 더 나은 버전이 있어서 syntax highlighting 같은 기능도 들어가 있지만, 내가 개조하려던 건 잘 안 돼서 아마 작성자에게 도움을 요청해야 할 듯함
    다만 요즘식 공용 지식이라는 의미의 문서화는 부족해서 Stack Overflow나 AI에 묻기 어렵고, 예제 코드를 보며 배우고 Turbo Vision 책 몇 권을 반복해서 읽는 옛 방식으로 가야 했음
    수동 layout은 꽤 번거로워서 Qt 같은 자동 layout이 있으면 좋겠고, splitter도 좀 그립지만 구현 자체는 어렵지 않아 보임
    또 하나 놀란 건 TV가 실제로는 꽤 작고 컴팩트하다는 점임. 90년대에는 엄청 거대하게 느껴졌었음
    전체적으로 현대화 작업은 정말 잘됐고, 나는 이걸 아주 마음에 들어 함

  • cmake 지시문이 잔뜩 있는 걸 보니 괜히 과거로 돌아가고 싶어짐
    Turbo C나 Pascal에서는 F9만 누르면 바로 돌았는데 말임
    한편으론 이게 우리 도구 체인의 무능함도 보여준다고 느낌
    지금 시대라면 온라인 컴파일러 하나 가리켜서 바로 실행하거나, 내려받아 폴더 하나 열고 실행하는 정도면 끝나야 하는데, 도구가 아니라 의식 절차처럼 돼버렸음

    • 현대 Unix에서 소프트웨어 컴파일은 한때 이미 풀린 문제였음
      ./configure && make && make install이야말로 여전히 gold standard여야 함
  • 이건 Turbo Vision 포트/클론 중 하나일 뿐임
    C++ 쪽에는 이것도 있음: https://github.com/kloczek/tvision
    FreePascal/Lazarus에 들어가는 버전은 Pascal로 작성됐고, Rust판도 하나 있는데 좀 vibe-coded 같아 보이기도 함: https://github.com/aovestdipaperino/turbo-vision-4-rust

  • 터미널에서 이걸 돌리면 원래 텍스트 모드 화면의 마우스가 주던 핵심 감각이 조금 사라짐
    진짜 텍스트 모드 화면에서는 마우스 포인터가 아니라 마우스로 움직이는 노란 블록처럼 보였음
    고해상도 Linux 텍스트 모드에 GPM으로 돌려본 사람이 있는지 궁금함

    • 본질적으로 노란색이었던 건 아님
      위에 덮인 셀의 색을 반전해서 보여주는 방식이었고, 대부분의 화면을 채운 메인 창이 짙은 파란색이라 결과적으로 밝은 노란 블록처럼 보인 경우가 많았음
  • 최근 Wookash podcast에서 Chuck Jazdzewski를 다룬 편을 추천함
    원래 Turbo Vision을 만든 팀의 일원이었고, 그 생태계 전반 이야기도 많이 나옴

  • 나는 아직도 C++판보다 진짜 Turbo Vision, 그러니까 Pascal 버전을 더 원함
    C++판은 결국 Pascal판을 옮긴 쪽에 더 가깝게 느껴짐
    예를 들어 Pascal에서는 uses가 키워드인데, #define으로 모듈을 include하는 방식은 아무래도 해킹처럼 느껴짐
    뭐 지금은 큰 차이가 아닐 수도 있겠지만 말임

    • Free Pascal에 포함된 Free Vision이 사실상 그 역할을 함
      텍스트 모드 IDE도 Free Vision을 사용함
      https://wiki.lazarus.freepascal.org/images/1/19/Userscreen.png
      다만 핵심 차이는 Free Vision과 Turbo Vision이 Delphi의 class가 아니라 Turbo Pascal 5.5 시절의 object 타입을 쓴다는 점임
      class는 RTTI 덕분에 자동 직렬화 같은 걸 구현하기 쉬운데, object는 그런 게 없어서 서로 다른 타입을 런타임에 구분하려면 객체 포인터의 고정 오프셋에 있는 VMT 포인터를 등록하는 식으로 수동 직렬화를 해야 함
      Free Pascal이 object에 private/protected/public, property 같은 편의 기능을 좀 추가하긴 했지만, Free Vision은 원래 Turbo Vision API를 구현하느라 그런 확장을 쓰지 않음