ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 좋은 에디터란?
    IT/견물생심 2021. 2. 12. 23:00

    좋은 에디터는 어떤걸까...?

    지금 구현해야 한다면 어떻게 할까?

    를 고민한 내용이다.

     

    직접 만들기엔 시간과 복잡도가 내게 너무 크지만..

     

    3월 업데이트!! 3/19에 Emacs NG에 합류했다.

    github.com/emacs-ng

     

    Emacs NG

    Emacs New Generation. Emacs NG has 2 repositories available. Follow their code on GitHub.

    github.com


     

    우연히 emacs-ng(이슈)라고 Emacs + Deno란 끔직한 혼종(?)을 발견했다.

    저 끔직한 혼종은 Remacs풀리퀘스트로 날라왔던  Webrender까지도 지원하고 있었다.

    Emacs X Deno??

     

    덕분에 Remacs 프로젝트가 잘 돌아가나 확인하니 2020년 들어 업데이트가 안되고 있었다.

    Still Alive/Lost Momentum?란 이슈에서

    For the most part, the stuff that's left to do is hard. The garbage collector, the bytecode interpreter, anything like that. If we were all getting paid to work on it I'm sure we could figure it out, but as things are now, it's quite a challenge.

    It's important to keep some perspective though. If we look at Remacs as a serious attempt to replace the C core of Emacs with Rust, then we can safely call it a failure, because that isn't going to happen any time soon, maybe ever. BUT, if we look at Remacs as a proof-of-concept to show that it would be possible to do such a replacement, then I would call it a wild success.
    - 콜라보레이터
    Although I'm glad there have been more upstream changes than I expected, I think it would have been possible if there wouldn't be that much new code we have to deal with. It's work that doesn't really pay off.

    Maybe we can see this as a decision of the emacs community to stick with things how they are. It's not realistic that such an ambitious project can be handled by a few people since we have to update remacs for code by many more people that lands in upstream.
    - 멤버

    (대충 너무 복잡해서 못해먹겠다는 소리)

    란 코멘트를 보게 되었다.

     

    이맥스의 구조가 얼마나 복잡하냐. ㅋㅋ

    이맥스 GUI의 뿌리인 xdisp.c로 알 수 있다.

       /*
       +--------------+   redisplay     +----------------+
       | Lisp machine |---------------->| Redisplay code |<--+
       +--------------+   (xdisp.c)     +----------------+   |
    	  ^				     |		 |
    	  +----------------------------------+           |
    	    Block input to prevent this when             |
    	    called asynchronously!			 |
    							 |
    		    note_mouse_highlight (asynchronous)	 |
    							 |
    				    X mouse events  -----+
    							 |
    			    expose_frame (asynchronous)	 |
    							 |
    				   X expose events  -----+
    */

     

    GNU Emacs is an old-school C program emulating a 1980s Symbolics Lisp Machine emulating an old-fashioned Motif-style Xt toolkit emulating a 1970s text terminal emulating a 1960s teletype. Compiling Emacs is a challenge. Adding modern rendering features to the redisplay engine is a miracle.
    - Buttery Smooth Emacs

    인용글의 링크를 읽어보라.

    그저 웃음만 나올 것이 틀림없다. ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

    구조도 문제지만 1.1mb의 코드는 더하고 ㅋㅋㅋㅋㅋㅋ

     

    반면 lisp.h, eval.c, bytecode.c처럼 Elisp VM쪽 코드는 각종 C 트릭이 있다고 하지만 사정은 나은 편이다.

    여기서 확 든 생각.

     

    웹브라우저를 따라서 모듈화나 아키텍쳐 구성하면 되는거 아냐?? (comment)

    Emacs VM(JS VM) + Xi-Editor(Web APIS) 조합으로

    Understanding Event Loop, Call Stack, Event & Job Queue in Javascript, 움짤로 보는 자바스크립트 동작 원리(1) - Event Loop

     

    사실 Dart의 이벤트 루프가 마음에 더 든다. [Flutter Threading: Isolates, Future, Async And Await]

     

    여기서 촉발되어 내가 생각하는 이상적인 에디터와 관련된 글을 쓰게 되었다.

    기본적인 생각은 Swiboe의 접근(The Ideal Text Editor, Design for the ideal text editor)과 비슷하다.

    • 무료: 무료가 아니면 요즘 누가 쓸까?
    • 실현 가능성: 실현 가능해야 한다. 기존의 시스템을 최대한 활용하자.
    • 크로스 플랫폼: 어디서든 실행 가능해야 한다.
    • 성능: 당연하지만 빨라야 한다.
    • 확장 가능성: 간단한 모듈이나 스크립트, 매크로 형태는 물론 플러그인을 지원하고 UI의 수정까지 가능해야 한다.
    • 협업: 실시간으로 협업이 가능해야 한다.

     

    이맥스의

    를 읽어도 기본적인 생각은 비슷한 듯.

     

     

    그리고 OSI 7 Layer처럼 추상화가 이루어져

    • Lv1 코어: 에디터 엔진, 스크립트 VM, I/O 기능 등이 들어간다.
    • Lv2 프론트: 각종 기본 UI 컴포넌트와 API 구현에 집중.
    • Lv3 스타터 키트: VS Code처럼 기본적으로 사용하는데 무리가 없을정도로 제공.
    • Lv4 IDE: 디버깅, 프로파일링등 다양한 부가기능이 통합적으로 제공된다.

    와 같은 기능이 될 수 있다.

     

    Lv1 코어

    핵심 가치

    코어의 핵심가치는 앞서 제시한

    • 크로스 플랫폼: 이식 가능성을 고려해야함.
    • 성능: 백엔드다. 절대적으로 빨라야 할 필요가 있다.
    • 확장 가능성: 백엔드단 부터 고려되어야 함.
    • 협업: 네트워킹 및 동시 편집도 백엔드단 부터 고려될 필요가 있음.

     

    참고할 만한 프로젝트

    Neovim과 libvim, Xray, xi-editor는 에디터의 벡엔드 가능성을 충분히 실험 해주었다.

     Neovim · Delft Students on Software Architecture: DESOSA 2017

     

    Onivim 2 - Update #3: A re-architecture...

     

     

    Xray

     

    Xi: an editor for the next 20 years

     

     

    특히 xi-editor의 텍스트에 대한 연구와 집착은 놀라운 수준이다.

    공식문서의 CRDT(Conflict-free Replicated Data Type)와 Rope에 대한 글을 읽어보자..

     

    디자인

    Emacs: The Editor for the Next Forty Years에서도 그렇듯 새로운 프로젝트는 Rust를 적극적으로 활용하는 듯한 모습을 보인다.

    위에서 소개한 Swiboe, Xray, xi-editor말고도

    등이 있다.

     

     

    그럼 Rust로 코어를 구성한다고 가정하고, 필요한 기능은 무엇이 있을까?

    그리고 어떻게 구성해야 될까.

     

     

    Chrome, Firefox Safari Architecture(How Web Browsers Work — Behind the scene Architecture, Technologies, and Internal Working)

     

    Chorme's Multipress

    앞선 에디터 아키텍처와 브라우저 아키텍처를 참고했을때 난

    정도로 요약할 수 있다고 생각한다.

     

    여기서 몇가지 결정은 많은 궁금증을 자아낼 수도 있다고 생각한다.

    아마 뒤이은 설명들을 읽다보면 해소되기를 바란다.

     

     

     

    Editor Engine

     

    앞서 소개한 Xi-Editor가 가장 적합하다고 생각한다.

     

    Xi-Editor는

    • 비동기 디자인
    • 다중 프로세스 아키텍처
    • 텍스트 저장을 위한 Rope 구조
    • 동시 수정을 위한 CRDT

    처럼 기본기가 매우 뛰어나다.

     

    Rope 데이터구조는 최악의 경우에서 성능문제가 적으며, [Data Structures used in Text Editors]

    CRDT를 이용해 중앙서버가 없이도 협업 편집이 가능하다.

    (Gapbuffer, Zipper(JS 구현), Piece table도 흥미로운 데이터구조다)

     

    CRDT의 모델이 상당히 복잡해서 적합하냐는 말들도 있다.

    다음 글은 이에 대한 의문을 해소시켜준다.

     

    VM이 있다지만, 에디터 엔진도 확장 가능하게 만드는게 맞다.

    예를 들어 프로젝트 단위에서 코드를 검색하기 위해 ripgrep을 활용하려 한다면? (스타터킷에서 활용할 수 있다)

     

    러스트의 터미널 유틸리티 관련 생태계는 상당히 발전해서 참고할만한 것들이 꽤나 있다.

    몇몇은 에디터 엔진에 통합하여 사용해도 좋을 듯 하다.

     

    대규모 텍스트에 대한 대응도 이루어져야 한다.

    klogg처럼 디스크에서 읽어온다던가.

     

    여기에 추가될 것 하나.

    키맵 관련이다.

    위 링크는 키맵에 대한 일반적인 형태를 제안한다.

    Mode Tower

    키맵 자체는 관리하고, 프론트단에서 세부적인 사항(예: Vim 키맵, Nano 키맵 등)을 구현하면 된다.

     

     

    Rendering Engine

    모듈화된 코어라 하면 Front 코드가 없는게 맞지 않을까 생각할 수 있다.

     

    하지만

    와 같은 기능을 구현하기 위해서는 백엔드부터 고려되어야 한다.

     

    또한, 프론트단의 파편화와 수고를 줄이기 위해 렌더링 엔진을 통합하는 것도 나쁘지 않은 결정이라 생각한다.

    신규 플젝에서 파편화가 많이 생긴다면 더더욱 퍼지기 힘들다.

     

    아마 가장 좋은 것은 WebRender + Pathfinder 조합이 아닐까.

    둘 다 상당히 낮은 레벨의 구현이므로 GUI 툴킷과는 구분될 수 있다.

     

    +.

    텍스트 렌더링 관련 좋은 시리즈를 발견했다.

     

    Pathfinder가 Freetype을 대체할 수 있다고 한다.

     

    VM

    가장 먼저 고려할 만한 것은 자바스크립트다.

    방대한 NPM의 라이브러리를 모두 사용할 수 있으며, 프론트/스타터 킷 레벨에서 Visual Studio Code 호환 API를 제공하면 Market Place의 확장기능들을 사용할 길이 열린다.

    아마 Deno를 통합하면 간단할 것이다.

     

    Elisp나 Vim Script를 쓰고 싶다고??

    Elisp는 앞서 말한 Emacs 소스를 사용하거나 Emacs 유저들의 꿈 중 하나인 Guile(소스) Emacs를 구현할 수 있겠고,

    Vimscript는 NeoVim의 Eval을 떼어내던가 해야지..

     

    내가 Emacs 사용자에 Vim 키맵도 좋아하지만, Deno가 최선의 선택지 아닐까.

     

    Parser

    LSP를 지원함에도 대체 왜!!

    파싱과 관련된 모듈이 지원되어야 하는가 의문이 들 수 있다.

     

    그렇다면 다음 글들이 답이 될 수 있다.

     

    LSP도 구문강조를 할 수 있다.

    그러나 실시간 문법 강조나 점진적 분석(Incremental Parsing)이 힘들다.

    베스트라 하면 Lezer의 Rust 버전이겠지만, Tree-Sitter도 충분히 좋다고 생각한다.

     

    +.

    마크다운 파서에 관련된 글을 찾다보니

    란 글도 잼나네. ㅎㅎ

     

    LSP(Language Sever Protocol) & DAP(Debugging Adapter Protocol)

    자동완성에서 company-mode/auto-complete, 디버깅에서 GUD/RealGUD처럼 바로 인터페이스를 구현 후 하나하나 대응하는 것보단 LSP, DAP를 구현만 하는게 낫지 않겠는가?

     

    최근에 만들어지는 에디터라면 LSP/DAP를 지원하지 않을 이유가 없다.

     

    +.

    비록 C/C++ 전용이지만 rtags같은 인덱서도 꽤나 매력적이다.

     

    Shell

    유닉스의 강점 중 하나는 강력한 커맨드 라인이다.

    기존에 있던 걸 잘 쓰면 당연히 좋은거 아니겠는가?

     

    Shell을 적극적으로 활용하던 에디터가 있다.

    그때그때 명령하거나 저장된 것을 활용하거나.

     

    맥에서 Notepad++(윈도우), Kate(리눅스)처럼 사용하던 TextMate의 텍스트 필터 기능이다.

     

     

    I/O

    검증된 라이브러리인 Tokio를 베이스로.

    여긴 무슨 할말이 더 있을까.

     

    다만 커다란 크기의 파일을 위한 모드가 있어야 한다.

     

    에디터 성능과 관련된 벤치마크 두개

     

    Lv2 프론트

    핵심 가치

    코어의 핵심가치는 앞서 제시한

    • 크로스 플랫폼: 각 플랫폼 특화 기능 제공.
    • 성능: GPU를 이용한 프로세싱,  최소 60fps를 지원하며 낮은 키입력 레이턴시, 부드러운 스크롤.
    • 확장 가능성: UI 커스텀이 쉬워야 한다.

     

    처음에 Vim을 생으로 사용해본적 있는가?

    리눅스를 처음 다루었을 때였는데 명성에 비해 실망을 했었던 기억이 난다.

    아무리 확장 가능하다지만 너무한 수준으로 기능이 없어보였다.

     

    사실 기초가 되는 프론트 단은 그래도 상관없다.

    대신 쓸만한 수준으로 확장가능하고 커스텀이 가능한게 좋지 않을까.

    Vim/Gvim 정도가 딱 좋다.

     

    참고할 만한 프로젝트

    Flutter vs React Native — Comparing the Features of Each Framework | by Vitaly Kuprenko | Level Up Coding (gitconnected.com)

    플러터의 아키텍처는 확실히 참고해볼만 하지 않을까.

     

    Servo WebRenderer for Xi front-end · Issue #140 · xi-editor/xi-editor · GitHub

     

    Servo WebRenderer for Xi front-end · Issue #140 · xi-editor/xi-editor

    I like the way you think, first goal: performances. But I think about something else: performances, multi-OS and customization. That's just something I think about and I believe I'm not the...

    github.com

     

     

    TUI

    Rust로 TUI 구현은 문제 없다고 생각한다.

    tui-rs란 검증된 라이브러리가 존재하기 때문.

     

    하지만 터미널과 관련된 이슈를 몇가지 적다면

    • 색상: Turbo Vision처럼 BIOS 4bit, Xterm 256(8bit), True Color(24bit), 터미널 기본 색상지원
    • 이벤트: 단축키와 마우스 지원
    • 클립보드: 상호작용 가능해야 한다.
    • 위젯: 2D 셀 형식 말고, 팝업형태도 지원 가능, 반응형(터미널의 크기는 바뀔 수 있다)
    • 이미지 표시: libsixel이나 chafa를 이용한 이미지 표현 | viu란 러스트 이미지 라이브러리도 있다.
    • 성능: TTY로의 빈번한 정보 업뎃은 느리게 만들며, 리페인트되는 영역이 많으면 플리커링이 생기기 때문에 상태관리가 되어야 한다. (버퍼링, 이벤트 루프, 반복된 시퀸스 방지, 동일한 셀 유지등의 기법이 가능하며 심지어 가상터미널을 구현할 수도 있다. ImTUI, Vty도 흥미롭다)
    • 기타: Terminfo, 유니코드 지원등

     

    기타 TUI 라이브러리들

     

    +.

    검색하다 Oberon이란 신기한 물건 발견 ㅋㅋ

    BearLibTerminal도 재밌음.

     

     

    GUI

    사실 러스트의 GUI는 매우

    Rust GUI: Introduction, a.k.a. the state of Rust GUI libraries (As of January 2021)에서 잘 소개해주고 있다.

     

    가 흥미로워보이긴 한다.

     

    텍스트 레이아웃에 대한 좋은 글.

    진정 텍스트에 대한 고민이 느껴진다. (로드맵, 설명, 결과물)

    https://raphlinus.github.io/text/2020/10/26/text-layout.html

     

    Text layout is a loose hierarchy of segmentation

    I love text layout, and have been working with it in one form or other for over 35 years. Yet, knowledge about it is quite arcane. I don’t believe there is a single place where it’s all properly written down. I have some explanation for that: while bas

    raphlinus.github.io

     

    GUI는 이슈가 너무 많아서 터미널과 달리 나열하기가 힘들지 않나.

    대신 최근에 알게된 설계 패턴이나 기억하는 용도로.

     

    기타 인텔리J 개발자의 다양한 고민

     

    키맵

     

    개인적으로 사용하는 키맵은 엄청난 혼종이다.

    대충 서술하자면

    • Emacs: 이맥스 유저니 당연하다.
      이맥스의 키맵은 구린걸로 유명하며 수많은 키맵들을 양산 시켰다.
      나도 이맥스 유저지만 Ctrl+n(next, 다음 줄로 이동), Ctrl+p(prev, 전 줄로 이동) 같은 구린 키맵은 RSI를 유발한다고 믿는다.
      그러나 Ctrl+h(도움말), Ctrl+c(모드 관련), Ctrl+x(기타)같은 프리픽스 키 시스템이나 Ctrl+g(취소), Alt+x(명령)는 잘 만들어졌다.

      프리픽스 키 시스템이 왜 좋냐?
      수많은 경우의 수를 창출 가능하며 프리픽스키를 통해 보다 직관적인 모달 에디터에 가까워질 수 있다.
      예를 들어 한글 워드프로세서 사용자라면 알 수 있다.
      <Ctrl+k h>(하이퍼링크), <Ctrl+k o>(개요)처럼 비슷한 기능끼리 직관적으로 모아놓는게 가능하며 능숙한 사람이라면 키보드만으로도 사용이 가능하지 않은가?
    • Evil: 최고의 Vim 키맵 에뮬레이터. 기존 키맵과 완전히 통합된 것은 Evil-Mode 밖에 없다고 생각한다.
      IdeaVim/ViEmu도 나쁘지 않지만.. 기존 키맵과 통합이 뭔가 부족함.
    • Terminal Based Common: Ctrl+c, Ctrl+v는 이맥스 키맵과 겹친다.
      이를 해결하기 위해 내장된 CUA(Common User Access) 키바인딩도 충돌 해결이 안되서 섞어쓰기 어렵다.
      원래 이맥스 키맵과 충돌을 피하기 위해 같은 Ctrl+c/Ctrl+x라도 블럭 지정시 복사/잘라내기(이맥스 프리픽스키는 Ctrl+Shift+c/Ctrl+Shift+x), 안했을때는 이맥스의 프리픽스로 지정이 되나 추가되는 기능인 Whole Line or Region 개념, Vim의 Ctrl+v등과 충돌, 일부 이맥스 키맵의 변경등 때문에 사용성에 문제가 생긴다.

      그러나 Ctrl+Shift+c, Ctrl+Shift+v 형태로 일반적인 키맵들을 설정하면 충돌 위험이 없다.
      Ctrl+Shift+x(잘라내기), Ctrl+Shift+z(undo), Ctrl+Shift+r(redo), Ctrl+Shift+n(새 파일), Ctrl+Shift+o(파일 찾기등등처럼 하면 되며 CUA모드처럼 쓰고 싶으면 Capslock을 사용한다.

      Cua 모드 전용 기능 중 Cua-Rect 하나만큼은 발군으로 Rectangle Selection Mode를 대체해서 사용 중. [More Batteries Included with Emacs]
    • 일부 Brief : Emacs의 Brief-Mode/Brf-Mode, Brief Keyboard Layout, Cheet Sheet 문서들을 읽어보면 알겠지만 Home/End 키 연타(라인-윈도우-파일 순으로 이동)처럼 번뜩이는 아이디어가 참 좋다.
      Emacs도 의미 기반으로 이루어졌지만, Brief 키맵이 훨씬 설득력 있는 듯.

     

    추가적으로 고려중이었던 것 몇가지..

    물론 확장과 변형은 정답이 아닐수도 있지만 sam 에디터 구조적 정규표현식은 흥미로운듯.

     

    좋은 에디터라면 다음의 키맵을 기본적으로 선택가능해야 한다.

    Common

    Atom, Vistual Studio, Visual Studio Code, IntelliJ, Sublime등처럼 일반적인 키맵을 베이스로 한다.

    다만, 앞서 소개한 Brief, Emacs, Emacs Others(Boon, Fingers)의 장단점을 잘 분석하여 인체공학/의미기반/호환성등을 염두하여 Global Keymap을 만들 필요가 있다.

     

    Vim

    Vim 에뮬레이션에 충실

     

    Emacs

    Emacs 에뮬레이션에 충실

     

    Vim+

    내가 쓰고 있는 키맵과 같은 혼종. 그러나 재설계가 포함되어 있다.

    • Global Keymap
    • 수정된 Vim 키맵 포함

     

    기타 UI 요소

    툴바, 상단메뉴, 콘텍스트 메뉴(우클릭 메뉴), 팝업, 스플릿 등의 기본적인 UI 요소들은 모두 제공되어야만 한다.

     

    Lv3 스타터 킷

    핵심 가치

    • 즉시 사용: 잘 설정되서 바로 쓰기 편한 상태여야 한다. VS Code나 Doom Emacs가 예시로 쓰일 수 있음.
    • UX: 일관성있고 자동화된 사용자 경험을 제시 해줘야한다.
    • 다양한 기능: Git, 프로젝트 단위로 열기 등은 이제 필수 기능이다.
    • 가벼움: 그럼에도 불구하고 가벼워야..

     

    VS 코드와 둠 이맥스가 가장 적절한 예.

     

    원래 IDE에 들어갈만한 기능이라지만,

    요즘은 다음 정도 부가기능은 기본으로 들어가야 하지 않을까.

    • 버전관리/배포 
    • 원격접속/협업
    • 파일/터미널/워크스페이스

    Lv4 IDE

    다양한 부가기능: 리소스 에디터, DB/HTTP 클라이언트, 노코드 블럭 기능?(예1, 예2)

    통합: 문서(dash 같은?), 프레임워크(SwiftUI, RAD Studio, XAML Designer), 빌드/컴파일/커버리지/에뮬레이터, 
    디버깅/프로파일링/디컴파일러

     

     

    댓글

Designed by black7375.