Small and Simple Nextvi
last updated: 2024-05-04 03:56
vi는 배우는 것이 아니라 몸으로 익히는 것이다.
vi는 단순하고 일관성이 있다.
Intro
- 장점
- vi의 기본 명령을 제공한다.
- 단순하고 용량이 작아 임베디드 환경 및 원격지에서 사용하기에 좋다.
- neatvi로 부터 여러 기능이 추가되었다.
- vim, nvim과는 다르게 간단한 설정과 빠른 동작이 장점이다.
- utf-8을 지원한다. 한글 입출력 가능.
- 쉘명령 출력을 ex-mode(명령라인)에서 터미널 깨짐 없이 불러올 수 있다.
- 각종 플러그인이 없는 대신 ex-mode에서 터미널 툴과 상호 작용할 수 있다.
개인적으로 vim보다는 nvim을 더 선호한다. lua와 결합된 플러그인과의 연결이 정말 좋기 때문이다. 하지만 단점도 많다. lua를 공부해야하고 또 설정에 적응하려면 많은 시간과 노력이 필요하다. 더군다나 수많은 플러그인을 장착하게 되면 느려지고 무거워진다. 설정이 잘 못 되면 바로 잡느라 삽질을 해야한다. 물론 자신만의 설정을 잘 만들어서 백업해 두었다가 재사용하면 좋다. 하지만 nvim 자체의 패키지 사이즈와 수 많은 플러그인의 사이즈를 생각하면 작고 가볍게라는 말이 무색해진다.
데비안을 쓰는 경우에는 더욱 문제가 많아진다. 버전이 낮아 플러그인 적용이 어려운 경우가 빈번히 발생한다. 최신 소스를 받아 컴파일하면 되지만 이것도 쉽지 않다. 컴파일 환경을 만들고 필요한 라이브러리를 준비하고 에러가 나면 이를 상황에 맞게 조정해 주어야 한다. 더군다나 라즈베리파이 같은 환경에서는 더더욱 어렵다.
이러 저러한 문제로 상황에 맞게 작고 가볍고 빠른 vi 에디터를 찾아보기 시작했다. vi의
수많은 변종과 후손들 중에 nvi
를 찾았다. 소스를 가져다 컴파일해서 쓰기에도 문제가
없다. 하지만 한글이 지원되지 않는다. 즉 utf8을 지원하지 않는다는 것이다. 이를 패치한
것이 있는 지 알아보았지만 찾을 수 없었다.
다음은 vis 라는 것을 찾았다. nvim과 같이 lua를 지원하고 더욱 놀라운 것은 여러 줄을 동시에 편집할 수 있는 기능이 있다. 용량도 nvim에 비해 작고 빠르다. 한글도 지원이 된다. 한 동안 공부하면서 사용하다가 조금씩 껄끄러운 면이 드러났다. lua 버전이 최신 버전에 가깝기 때문에 luajit 기반으로 사용하는 입장에서 혼란을 준다. 더군다나 lua 플러그인도 nvim에 비해서 많이 부족하다. 필요한 것이 대부분 없다고 봐도 무방하다. 이것을 사용하는 유일한 장점은 다중 라인 편집이라고 생각한다. 전문 코딩을 하는 것이 아니기 때문에 개인적으로 그렇게 와닿지 않았다.
그 다음으로 찾은 것이 neatvi
이다. 말 그대로 neat한 vi인 것이다. 정말 작고 간단하지만
상태 표시와 코드 문법의 컬러 표시가 지원된다. 165kb 정도의 사이즈이다. 편집에 필요한
기본적인 vi 명령은 모두 지원한다. ex 명령줄에 터미널 명령과 상호 작용도 가능하다.
이것은 정말 놀라운 것이다. 보통 nvim
의 기능과 플러그인에서 제공하는 것을 모두 터미널
명령과의 상호작용으로 해결할 수 있기 때문이다. 더욱 놀라운 것은 터미널의 출력결과가
vim, nvim 등과는 다르게 투명하게 아무 문제 없이 표시된다는 것이다. 즉 컬러와 한글,
nerd font 등이 그대로 neatvi
에서 출력된다. ls
,find
,grep
,awk
,sed
등
수많은 쉘 명령을 ex 모드에서 조합해 쓸 수 있다. 자주 빈번하게 사용된다면 스크립트나
프로그램을 만들어서 플러그인 역할을 하게 만들면 된다.
neatvi
가 왜 훌륭한가. 여러 가지가 있지만 위에서 언급한 것 이외에 기본 c 라이브러리만을
의존하고 그 어떤 의존성도 없고, 더욱이 utf8을 지원하여 다국어 표시와 입력이
가능하다는 점, 그럼에도 불구하고 작고 빠르다는 것이다. 작은 것이 아름답다
라는 유닉스
철학과도 잘 부합한다. 필요한 툴은 터미널 명령어와 상호작용할 수 있다. 에디터는 파일
편집에만 집중하면 된다. 드디어 에디터 찾아 삼만리는 이제 끝을 향하고 있었다.
참고로 youtube에 neatvi에 대한 소개가 있다. 시작하기 전에 아래 링크를 통해 전체적인 내용을 살펴 보면 좋다.
https://www.youtube.com/watch?v=ZUdnHtvX4l4&pp=ugMICgJrbxABGAHKBQZuZWF0dmk%3D
neatvi
의 주소는 다음과 같다.
https://github.com/aligrudi/neatvi
작고 가볍고 임베디드 환경 및 여타 조건에서 가볍게 사용할 수 있는 neatvi
를 매우 만족하다가
조금 불편하다는 생각이 들었다. 고성능, 다기능의 nvim을 사용하다 거의 아무 기능도
없는 것을 쓰게 된 후유증 같은 것이다. 예를 들어 줄 번호를 표시할 수 없다거나 워드랩,
현재 디렉토리 내의 파일검색 및 불러오기, 자동 들여쓰기, 문서 내의 단어 완성 지원 등이
그것이다. 그래서 neatvi의 faq나 다른 사람의 요구사항 등을 살펴보다가 분기된 nextvi
를
알게 되었다. neatvi
로 부터 분기되어 여러 아쉬운 기능을 추가한 버전이다.
이러한 이유로 nextvi
를 최종적으로 선택하여 사용하게 되었다. 물론 nvim
등에 비할
바는 아니겠지만, 최소한의 기능과 성능으로 소스를 편집하거나 문서를 작성하는 데 있어
매우 훌룽하하고 본다. 이에 더하여 conf.c
라는 파일에 자신이 선호하는 언어의 컬러를
설정해주고 컴파일해 사용한다면 더욱 쾌적한 환경이 된다. 물론 vi.c
파일을 편집하여
자신만의 키매핑도 추가할 수 있다. 복잡하다면 설정 변경 없이 써도 무방하다.
모든 것이 그렇듯이 장점만 있는 것은 아니다. vim
등에서의 다양한 기본 기능과
플러그인이 없다. 하지만 이를 보완할 수 있는 여러 방법들을 살펴본다.
아래 정리된 내용을 보기 전에 깃허브 소스의 README
파일이나 nextvi
홈의 README
를
읽어 보자. neatvi
와는 다르게 정말 많은 기능이 추가되었다. 그리고 독자적으로 변경된
것들도 있다. 개인적으로 주로 사용하는 방법을 적었으므로 그 외의 것들은 도움말을
참조해야 한다.
자 그럼 설치부터 기본 사용법, 그리고 응용까지 정리해볼까 한다.
설치
- 설치전에 gcc, clang, tcc 등의 컴파일러가 있어야한다.
- 컴파일 후
vi
를 적절한 위치로 옮기고PATH
에 추가한다.
$ git clone https://github.com/kyx0r/nextvi
$ cd nextvi
$ ./build.sh
$ ./vi
기본 사용법
vi의 기본 명령과 모두 호환된다.
- 파일 열기
$ vi # 파일이름 없이 열기 (:wq <filename> 으로 저장하고 종료)
$ vi file_name.c # 파일이름 열기 (:wq 로 저장하고 종료)
- 파일 저장 및 종료 (ex-mode)
:w (저장: 또는 명령모드에서 `^k`)
:q (나가기: 저장하지 않고)
:q! (강제로 나가기: 문서 변경 무시)
:wq <filename> (filename으로 저장하고 종료)
:wq (저장하고 종료)
:wq! (강제로 저장하고 종료)
`qq`,`zz` (`:q!`)
- 이동
h
- 커서 앞으로 한 칸 이동l
- 커서 뒤로 한 칸 이동k
- 커서 위로 한 칸 이동j
- 커서 밑으로 한 칸 이동^
- 행의 첫 글자로 이동$
- 행의 마지막 글자로 이동+
- 다음 행의 첫 글자로 이동-
- 이전 행의 첫 글자로 이동{
- 이전 문단 이동}
- 다음 문단 이동gg
- 문서의 처음으로 이동 (1G
)G
- 문서의 마지막으로 이동H
- 화면의 맨 처음으로 이동M
- 화면의 중간으로 이동L
- 화면의 하단으로 이동w
- 다음 단어 이동b
- 이전 단어 이동번호G
,:번호
- n 번째 행으로 이동
- 입력
i
- 커서 바로 앞에서 입력하기I
- 커서 줄 맨 앞에서 입력하기a
- 커서 바로 뒤에서 입력하기A
- 커서 줄 맨 뒤에서 입력하기esc
- 입력을 종료하고 명령모드로 나가기
- 삭제
dd
,d1d
- 커서 행을 지우기3dd
- 커서 행 포함 아래로 3 줄 지우기d0
- 커서 위치에서 행의 처음까지 삭제D
,d$
- 커서 위치에서 행의 끝까지 삭제
- 복사/ 붙이기
3yw
- 커서 위치에서 3 단어 복사3yy
- 커서 위치에서 3 줄 복사p
,1p
- 복사 또는 지운 것을 커서 기준 1번 붙이기
- 마킹(Marking)
ma
- 현 커서 위치를 a로 마킹'a
- a 마킹한 곳으로 이동''
- 이전 위치로 이동
- undo/redo
u
- undo^r
- redo (Ctrl + r
)
- 줄 번호 표시
#
- 줄 번호 표시<space>
- 줄 번호 표시 없애기 (또는 방향키 명령hjkl
)- 절대 줄 번호와 상대 줄 번호가 모두 표시된다.
#
명령으로만 표시할 수 있다. 항상 표시해서 사용할 수 없다.- 여러 줄을 복사나 지우기 할 때,
- Tip.
^g
(Ctrl+g) - 해당 줄 번호와 단어 수 등 확인가능
- 숨은 문자 표시
V
- 숨은 문자 표시/ 감추기
- 단어 자동 완성 (auto complete)
^g
- 입력 모드에서 실행하면 이전까지 입력했던 단어를 기억하고 자동완성 동작.- 일부 문자를 적고
^n
다음,^r
이전 명령으로 선택 - 한글도 된다. 입력 중간 중간에
^g
해 주어야 한다.
터미널 쉘(Shell)과 상호 작용
쉘(Shell) 전환
잠시 편집을 멈추고 쉘로 갔다가 다시 vi로 돌아와야 할 때가 있다. 소스를 컴파일하고 테스트를 한다던가 잠시 다른 작업을 해야 하는 경우이다. 다음 두 가지 방법이 있다. 이것은 모든 vi clone 에서 사용할 수 있는 방법이다.
- Ex-Mode
:!sh
또는:!bash
- 본쉘 실행 또는 bash 쉘 실행- 쉘에서 필요한 작업을 한다.
$ exit
- vi로 돌아오기- 자식 쉘을 하나 더 생성하는 방식이다.
- Job Control
<esc>
로 명령모드로 전환한다.^z
- 터미널에서 해당 프로세스(vi)를 스톱하는 명령어- 이를 통해 vi를 실행했던 부모 쉘로 돌아간다.
- 부모 쉘에서 필요한 작업을 한다.
$ fg
명령으로 vi로 돌아온다. ($ jobs
로 stop된 명령어 확인 가능)- 부모 쉘을 사용하므로 편하지만 vi가 stop 되어 있는 지를 까먹을 때가 있다.
vi를 빠져 나가지 않고 여러 쉘 명령을 바로 사용할 수 있다. 예시 중 ff
,gg
등은
빠른 파일 또는 내용을 찾기 위한 플러그인 역할을 멋지게 해 낼 수 있다. 후에 상세히
설명한다. 쉘 명령어가 출력되면 vi에서 멈춤이 일어나고 아무 키나 누르면 vi로 돌아온다.
쉘(Shell)과의 상호 작용
- Shell Command
:!쉘명령어
-ex-mode
에서 사용:!pwd
- 현재 작업 디렉토리 확인:!ls
- 현재 디렉토리 파일 리스트 출력:!date
- 시간 확인:!ff <keyword>
- fast find (빠른 파일 찾기 스크립트):!gg <keyword>
- fast grep (빠른 파일 내용 찾기 스크립트):!luajit %
- 현재 파일(루아스크립트)을 실행 테스트하기- Tip1. 명령모드에서
v;
하면:!
를 빠르게 입력할 수 있다. - Tip2. 명령모드에서
vv
하면 ex모드의:이전명령
를 재실행할 수 있다. - Tip3. ex모드에서
^a
로 다음 이전 명령을 불러와서 엔터로 재실행할 수 있다.
- 상호 작용
:w \!less
- 본문 내용을 터미널의 less로 보냄:w \!cat > file.txt
- 본문 내용을 cat으로 보내고 이를 file.txt로 저장:w \!cat >> file.txt
- 본문 내용을 cat으로 보내고 이를 file.txt로 덧붙임:r \!date
- date 명령 결과를 본문에 삽입\!쉘명령
의 형식이고\!
은 ex명령 내에서 shell 명령임을 표시한다.
!!
명령- 명령모드에서
!!
를 사용하면 sed나 awk등으로 문자 치환을 할 수 있다. - ex모드의
:시작줄번호,끝줄번호!쉘명령
과 같다. - snippet 프로그램 또는 스크립트를 만들어 스니팻 대용으로 쓸 수도 있다.
:1,1!
ex명령이 하단에 찍힌다. 여기에 쉘명령을 넣으면 상호작용한다.:1,1!date
- 날짜를 해당 라인에 삽입:23,23!awk '{print $1, $3}'
- 23번 줄에서 1과 3 번째 단어로 대체:5,5!sed 's/foo/bar/g'
- 5번 줄에서 foo를 bar로 치환:1,1!mysnip.sh mfront
- 1번 줄에 스크립트 실행 결과를 삽입(front matter)
- 명령모드에서
여러 개의 파일 편집하기
여러 개의 파일을 편집할 경우가 많다. 읽어 온 파일은 vi에서 버퍼라는 공간으로 복사된다. 사실은 버퍼를 편집하는 것인데, 버퍼간의 이동하는 법과 파일을 찾는 법 등을 설명한다.
- 여러 파일 불러 오기
$ vi *.c
- 쉘에서 vi로 여러 파일을 불러 올 때:e filename.c
- vi에서 특정 파일을 불러 올 때:e ./filename.c
- vi에서 특정 파일을 불러 올 때:e /home/user01/filename.c
- vi에서 특정 파일을 불러 올 때- 참고로
:e *.c
하면 좋을 것 같은데nextvi
는 지원하지 않는다. - 정확한 파일이름이 기억나지 않는다면
:!ls
명령으로 파일 리스트를 확인한 후 입력. - 파일이름이 상당히 길다면 마우스로 드래그해서 copy and paste 하는 것도 한 방법이다.
nnn
과fzf
를 이용한 방법도 생각해 볼 수 있다.- 다만 동작 중에
nnn
을 사용할 경우 파일 편집시 또 다른vi
가 동작한다.
fd
를 이용한 선택적 파일 불러 오기\
- 명령모드에서 이 명령을 수행하면 임의의 버퍼 창이 열린다.:fd
-ex-mode
에서 fd(find) 명령을 수행한다.- 그러면 현재 디렉토리의 파일 리스트가 버퍼에 올라온다.
/<keyword>
명령이나hjkl
등으로 원하는 파일로 이동한다.^i
또는<tab>
을 사용하여 해당 파일을 버퍼에 불러온다.- 주의할 것은 위 명령 사용시에 커서가 행의 맨 앞에 와야한다.
- 그렇지 않으면 커서 이후의 문자열이 전달되어 해당 파일이 열리지 않는다.
- 파일이 열리면 이를 편집하고
\
를 통해 다른 파일을 또 불러 올 수 있다. - 말하자면
\
은nextvi
의 내장 파일 검색 플러그인이다. - Tip) - 파일 리스트를 다른 조건으로 가져오기.
\
로 파일 리스트로 이동:fd
명령으로 전에 불러온 파일 리스트를dG
로 모두 지운다.- 아래와 같이 c 소스파일 리스트만 불러 올 수 있다.
:1,1! find . -type f -name '*.c'
- 동일하게 원하는 파일이름으로 이동하여
<tab>
키로 파일을 연다.
- 파일 버퍼 간의 이동
^7
- 파일 버퍼 리스트를 볼 수 있다.- 버퍼 리스트의 번호를 입력하면 해당 버퍼로 이동한다.
:b
- ex모드에서 사용하며^7
과 같다.:b번호
- ex모드에서 해당 버퍼로 바로 이동한다.^n
- 명령모드에서 다음 파일 버퍼로 바로 전환한다.- 파일 버퍼는 기본 10개이다.
:bx <버퍼수>
로 재지정 가능하다. - 주의할 것은 vi 종료 시, 파일 버퍼가 모두 저장되어 있지 않으면 종료되지 않는다.
README
를 찾아 보았는데 열린 버퍼를 개별적으로 닫는 방법은 아직 모른다.
Links
- Next Vi Home
- Neat Vi Home