가이드

키보드 단축키

gori의 단축키는 Hotkeys 편집기에서 재지정합니다. Preferences(Ctrl-, → Editor & Keys → Hotkeys에서 ↵)로 들어가거나, 커맨드 팔레트(Ctrl-P)의 **settings:hotkeys**로 바로 갈 수 있습니다. 에디터는 재지정 가능한 모든 동작을 발생 위치별(GLOBAL, HISTORY, REPEATER, FUZZER, INTERCEPT, …)로 묶어 나열합니다. 행을 고르고, 새 키를 누르면, 끝입니다.

Ctrl-,  → Editor & Keys → Hotkeys
Ctrl-P  → settings:hotkeys

키 예산 (새 단축키가 키를 얻는 방식)

맨 글자 키는 귀합니다. 새 동작은 키를 차지하기 전에 가격 등급을 정해야 합니다.

등급 가격 언제 예시
L0 구조적 Esc Enter Tab 화살표 Space(리더) 항상 포커스, 열기/닫기, READ/INS, space 메뉴
L1 루프 맨 글자 또는 스티키 패밀리(^R) 분당 여러 번 History/Issues j/k / y t(표시), History v(뷰), 서브탭 스트립 t(표시), Repeater 전송
L2 세션 호흡 Global 맨 글자(상한: c i s만) 세션당 여러 번 capture, intercept, scope 렌즈
L3 맥락적 Space 다음 니모닉 가끔, 패널 로컬 compare, mine, send-group, copy-as
L4 드문 동작 / 설정 팔레트(Ctrl-P) 또는 Preferences(Ctrl-,) 드물게 설정, Match & Replace, 알림

경험칙:

  • 새 패널 동작의 기본값은 L3(space 메뉴 전용)입니다. 루프가 입증된 뒤에야 직접 키로 승격하세요.
  • Ctrl은 타이핑 중(INS)에도 작동해야 하는 동작, 그리고 워크벤치의 실행·중지(Ctrl-R / Ctrl-X)를 위한 것입니다. 맨 글자에서 한 단계 올리는 범용 승격 수단이 아닙니다.
  • Shift는 탭 전체를 비우는 동작을 맡습니다. ⇧X는 clear가 있는 모든 탭(History·Probe·Authorize·Issues·프로젝트 ACTIVITY 피드)에서 같은 키이고, space 메뉴 글자는 그 옆의 X입니다. c가 아니라 x인 이유는 shift 아래에 무엇이 있느냐입니다: 맨 x는 그 다섯 스코프 어디에도 바인딩되어 있지 않지만 맨 c는 다섯 곳 모두에서 살아 있고(capture.toggle, Probe 목록에서는 dismiss), 프로젝트를 지우는 동작이 하루 종일 누르는 키 바로 위 shift에 있어서는 안 됩니다. 파괴적인 코드는 누르기 전에 읽을 수 있는 곳에 이름이 적혀 있어야 하고(space 메뉴만이 아니라 Help 시트와 그 탭의 본문 힌트에), 먼저 확인을 물어야 합니다.
  • d는 파괴합니다. 맨 d는 이 키를 바인딩한 모든 스코프(16곳)에서 선택한 행을 삭제하거나 무시합니다. Repeater의 응답 diff가 유일한 예외였고, 이제 ⇧D로 옮겨서 반사적으로 누른 d가 표시 토글에 떨어지지 않습니다. 메뉴 행은 Z d(Display… → Response diff)이고, 첫 단계의 d는 모든 서브탭 스트립에서처럼 서브탭 복제입니다(space 메뉴 참고). 삭제가 아닌 새 패널 동작은 d를 가져가지 않습니다.
  • 패널 고유의 키는 그 패널에서만 응답합니다. Repeater의 p(본문 보기 좋게)와 ⇧D(diff)는 응답 패널에서, Fuzzer의 m(매치된 것만)과 v(분포 사이드바)는 RESULTS에서만 동작합니다. 요청 패널과 템플릿 패널에서는 맨 키가 아무것도 하지 않습니다. 그 렌즈들은 거기에 아무것도 그리지 않고, Fuzzer 템플릿에서 v는 메뉴의 Clear selection입니다.
  • 복사가 그 규칙의 실례입니다. y는 READ에서, Ctrl-Y는 INS에서도, 모든 텍스트 상자에서 복사합니다. INS에서 맨 y는 그냥 문자이고, Shift+화살표로 만든 선택 위에 타이핑하면 그 선택을 덮어씁니다. 그래서 복사 반사에는 타이핑을 견디는 코드가 필요합니다. 둘은 같은 동사(*.copy)이므로 재지정은 READ 쪽 글자만 옮기고 Ctrl-Y는 그대로 남습니다. 모든 스코프에서, 명시적인 해제(unbind)를 해도 마찬가지입니다. y를 푸는 것은 READ 모드에 대한 결정이지, 방금 선택한 것을 복사할 방법을 텍스트 패널에서 조용히 없애도 된다는 뜻이 아니기 때문입니다.
  • 복사할 것이 있는 목록은 모두 y를 바인딩합니다. 바이트나 행, 기록 한 줄을 보여주면서 y에 아무 반응이 없는 패널은 설계가 아니라 구멍입니다. Intercept 큐, Evidence 보관함, 프로젝트 ACTIVITY 피드, OAST 콜백 상세가 각각 그런 구멍이었고 이제 모두 이 글자에 응답합니다. 한 곳에 복사가 둘 있고 서로 반대 방향을 가리킬 때(OAST 목록은 gori가 보낸 페이로드를, 상세는 돌아온 것을 복사합니다) 코드는 하나만 가질 수 있고(키맵에는 포커스 차원이 없습니다), 나머지는 space 메뉴 글자를 유지합니다.
  • /는 지금 보고 있는 목록을 거릅니다. 스크롤이 필요한 목록은 모두 이 키에 응답하며, 그렇지 않던 세 규칙 목록(Colormarker, Match & Replace, 세 섹션에 걸친 내장 규칙 약 40개가 있는 Probe RULES 서브탭)도 이제 포함됩니다. 이 바는 렌즈입니다. 행을 숨길 뿐 비활성화하지 않으며, Esc로 지웁니다. 바뀌는 것은 순서 변경 하나뿐입니다: 어떤 규칙이 이기는지를 순서가 결정하는 두 목록에서는, 질의가 걸린 동안 이동이 거절됩니다. 걸러진 목록은 규칙 엔진이 들고 있는 순서가 아니기 때문입니다.
  • f는 두 계층과 예외 하나를 가집니다. 증거 맥락(Issue의 RELATED 카드, 증거 뷰어)에서는 freeze이고, 서브탭 스트립에서는 find입니다. 계층이 다르므로 충돌할 수 없습니다. History의 follow와 Comparer의 변경 없는 줄 접기는 대신 Space 메뉴 항목입니다. 둘 다 세션에 한 번 뒤집는 토글이고, 그것이 L3의 용도입니다. 예외는 Intercept 큐입니다. 거기서 f는 잡아둔 요청을 전달하고 ⇧F는 전부 전달합니다. 그 탭 고유의 루프 키이고 f/⇧F 가족이 그 자체로 일관되므로, 옮기는 대신 문서로 남깁니다. History → Repeater가 Ctrl-R에서 받은 것과 같은 판단입니다.
  • x는 줄을 선택하고, t는 행의 플래그를 뒤집습니다. x는 열다섯 개 스코프에서 "이 줄 선택"이고, 네 곳(Colormarker·Match & Replace·Probe RULES 목록·OAST providers)에서만 "이 규칙 활성/비활성"이었습니다. 이제 그 넷은 t에 응답합니다. t는 History·Issues·Sitemap·Intercept 큐에서 이미 **표시(mark)**를 뜻하고, 규칙 목록에는 표시가 없으므로 충돌하지 않습니다. 덕분에 Rewriter의 토글도 손으로 짠 컨트롤러 키를 벗어나 평범한 재지정 가능 코드가 되었습니다.
  • s는 출처로 가거나, scope 렌즈를 뒤집습니다. 의미는 이 둘뿐입니다. s는 행이 사는 탭을 엽니다(Evidence 보관함, Issue의 RELATED 카드, Probe 목록과 상세). 그 밖의 모든 곳에서는 전역 scope 렌즈입니다. 더 이상 뜻하지 않게 된 것: Comparer와 Diff의 A ⇄ B 교체(이제 w), Colormarker와 Match & Replace 규칙 목록의 global ⇄ project(이제 Space 메뉴 항목이라 렌즈를 가리지 않습니다). 가리는 곳이 한 군데 남아 있고 그것은 이름을 붙여 둡니다: 프로젝트 ACTIVITY 피드의 s는 source 칩을 순환합니다. 그 패널의 / 바는 자유 텍스트 질의라 source: / level: / actor:를 파싱하지 않아 세 칩을 접어 넣을 곳이 없기 때문입니다.
  • space 메뉴는 INS의 대체 수단이 아닙니다. 텍스트 에디터가 키를 먼저 소비하므로 그곳에서 Space는 그냥 문자입니다. 타이핑 중에도 닿아야 하는 동작에는 Ctrl 코드가 필요하고, 니모닉만으로는 부족합니다. (Repeater/Fuzzer의 디코더 체인 편집기가 Ctrl-Y를 Copy에 넘겨준 뒤 space 메뉴만이 아니라 Ctrl-Q에 실린 이유가 이것입니다.)
  • History → Repeater와 Repeater 전송은 **Ctrl-R**로 유지됩니다(동일한 근육 기억). History→Repeater를 맨 글자 r로 옮기지 마세요.
  • r은 Repeater로 보내고, Ctrl-R은 실행합니다. 맨 r은 보낼 플로우가 있는 다섯 스코프에서 "이 행을 Repeater로 보내기"이고, 그 밖에서는 아무것도 아닙니다. Diff의 Run은 Ctrl-R로 옮겼고(아홉 스코프에서 이미 Run을 맡고 있습니다), OAST의 Resume listener는 Shift-R로, 프로젝트 ACTIVITY 피드의 Refresh는 팔레트 전용(Ctrl-P → Refresh feed)이 되었습니다. 피드는 진입할 때, 피어가 쓸 때, 폴링할 때 이미 다시 읽기 때문입니다. 서브탭 스트립은 r이 아니라 메뉴의 Rename 글자인 e로 이름을 바꿉니다.
  • Match & Replace와 알림은 키 없이(팔레트 / 배지) 제공됩니다. Global 키 조합을 원하면 재지정하세요.

맨 글자 하나에 질문 하나

맨 글자는 탭별이 아니라 질문별로 정해집니다. 어떤 동작이 아래 글자를 가져가려면 그 글자의 질문에 답해야 하고, 그렇지 않으면 L3(space 메뉴)에서 시작합니다.

키 뜻
Enter 이 행을 그 자리에서 보여주기
o 이 행 자신의 상세 열기(Enter의 별칭. Sitemap에서는 Enter가 펼치기이므로 o가 유일한 키)
s 이 행이 사는 탭으로 가기, 아니면 scope 렌즈
d 선택한 행 삭제·무시
y 복사
t 이 행의 플래그 뒤집기(표시, 또는 규칙의 on/off)
a 여기에 행 추가
e 선택한 행 편집
/ 이 목록 거르기
f freeze(증거) · find(서브탭 스트립)
r 이것을 Repeater로 보내기
Ctrl-R 실행
w A ⇄ B 교체
x 이 줄 선택
Shift-X 이 탭 비우기(먼저 확인)
Space 이 탭의 명령 메뉴

예외는 셋이며 모두 의도적입니다. 각각 그 탭 고유의 루프 키입니다: Intercept의 f는 전달(Shift-F는 전부 전달), History → Repeater와 Repeater 전송은 Ctrl-R 유지, 프로젝트 ACTIVITY 피드의 s는 source 칩 순환.

편집

에디터는 작업 복사본을 엽니다. Enter를 누르기 전에는 아무것도 저장되지 않으며, Esc는 모든 변경을 버립니다.

키 동작
↑ / ↓ (또는 j / k), 휠 선택 이동
/ 동작 목록 검색
e 또는 Space 선택한 동작 재지정, 그다음 새 키를 누릅니다
x 또는 Backspace 선택한 동작의 바인딩 해제
r 선택한 동작을 기본값으로 초기화
Shift-R 모든 동작을 기본값으로 초기화
← / → OS 기본 프로파일 순환(아래 참고)
Enter 저장 + 적용(실시간, 재시작 없음)
Esc 버리고 닫기

재지정을 시작하면 푸터에 *"press a key to bind"*가 표시됩니다. 아래 예약된 키에 나열된 것들을 제외하고, 원하는 키 조합을 수식 키와 함께 누르세요. 키가 예약되어 있거나 같은 위치의 다른 동작에서 이미 사용 중이면, 에디터는 이를 거부하고 이유를 알려줍니다. 키 입력 대기 상태는 그대로 열려 있으므로 다른 키를 눌러 보면 됩니다.

바인딩된 것이 없으면 행의 키 조합에 (unbound)가 표시됩니다. ● 마커는 기본값에서 변경했음을 뜻하고, ·은 기본값 상태를 뜻합니다.

충돌

두 동작은 다른 위치에서 발생할 때만 키를 공유할 수 있습니다. 이는 의도된 동작입니다(s는 거의 모든 곳에서 "scope 렌즈"지만 Probe에서는 "출처로 가기", c는 전역으로는 "toggle capture"지만 Intercept 큐에서는 catch 방향을 순환하고, Probe에서는 dismiss, Cookie에서는 crack, Evidence에서는 compare, Sequencer에서는 재설정). 에디터는 같은 위치의 충돌만 막습니다. 거기서는 키맵이 둘 중 하나만 남길 수 있기 때문입니다.

숫자 키 패밀리

탭 바는 번호가 매겨진 아홉 개의 슬롯이고, 탭을 옮겨 다니는 기본 수단은 그 숫자입니다.

키 동작
1-9 탭 바의 N번 슬롯으로 점프
0 Go to tab…: 21개 탭 전체를 타이핑으로 걸러 고르는 목록. 행마다 그 탭이 무엇을 위한 것인지 한 줄이 붙습니다
⇧1-⇧9 현재 탭의 N번 서브탭으로 점프
⇧0 Find sub-tab…: 스트립의 f가 여는 것과 같은 피커
gori Go to tab 카드: 탭 카탈로그 전체 위에 필터 바가 있고, 바에 올라간 아홉 개는 1부터 9까지 숫자를 달고 나머지는 숫자가 없으며, 각 행 뒤에 그 탭이 무엇을 위한 것인지 한 줄 설명이 붙은 모습
0은 카탈로그 전체를 엽니다. 바 위의 아홉 개는 자기를 여는 숫자를 달고 있고 나머지는 달고 있지 않습니다. 바 밖에 있어서 생기는 차이는 그것뿐입니다.

이 키들은 어디서나 동작합니다(탭 바, 서브탭 스트립, 리스트 본문, 드릴인 상세, 읽기 전용 패널). 예외는 하나뿐입니다. 필드가 텍스트를 받는 동안(INS 상태의 에디터, / 쿼리 바와 검색, 한 줄 프롬프트, 피커의 필터, CVSS 계산기, Decoder의 CHAIN 필드)에는 숫자가 문자입니다. Space와 같은 규칙입니다. Space가 공백을 입력하는 자리에서는 3도 3을 입력합니다. base64, sha256, rot13을 변환 체인에 칠 수 있는 이유가 이것입니다.

바는 기본적으로 번호를 그립니다(Preferences → Layout → Tab numbers, settings:layout). 마지막 탭 바로 뒤의 알약은 0:Tabs로 읽힙니다. 키와 그 키가 여는 것을 나타냅니다. 오른쪽 끝에 못박히는 대신 아홉 번째 슬롯에서 두 칸 뒤에 붙어서, →로 걷는 순서와 눈으로 읽는 순서가 같아집니다. 탭이 알약 옆에 더는 들어가지 않을 때만 오른쪽 끝에 고정되고 탭이 스크롤합니다. 레이아웃이 무엇이든 자리를 지킵니다. 0은 바 위의 아홉 개를 포함해 카탈로그 전체에 닿으므로 셀 것이 없고, 알약이 사라지는 레이아웃도 없습니다. 알약 오른쪽의 남는 구역은 일부러 비워 둡니다. 탭이 아닌 정보를 놓을 자리입니다.

아홉 슬롯, 그리고 열 번째 탭

settings:tabs는 열 번째 탭을 거부하고 그 이유를 알려줍니다. 대신 ⇧K로 이음선 위로 올리면 그 탭이 바에 올라가고 마지막 슬롯이 내려갑니다. 이전 빌드가 저장한 레이아웃(예전 바에는 상한이 없었습니다)은 사용자 자신의 순서대로 앞의 아홉 개로 잘리고, 잘린 탭 이름을 그 실행에서 한 번 알려줍니다.

한 탭만은 아홉 번째 슬롯 너머에 설 수 있습니다. 0으로 점프해 간 바깥 탭은 그 탭을 떠날 때까지 바의 맨 오른쪽에 번호 없이 놓입니다. 사용자가 배치한 슬롯이 아니라 지금 서 있는 자리이고, 어떤 숫자도 그것을 가리키지 않습니다.

상한 없는 예전 바를 되돌리려면 Preferences → Layout → Tab bar slots를 끄세요. 바는 다시 ‹ ›로 스크롤하고, 1-9는 여전히 앞의 아홉 탭에 닿고, 0은 여전히 모든 탭에 닿습니다.

키보드 레이아웃

kitty 키보드 프로토콜을 쓰는 터미널은 ⇧3을 3 + shift 플래그로 보고하고, gori는 그것을 바인딩합니다. 다른 터미널은 시프트된 숫자를 문자로 보냅니다(US 레이아웃에서는 #). 그래서 gori가 그것을 다시 ⇧3으로 접습니다. 비(非)US 레이아웃에서는 그 문자가 달라지므로, ⇧1-⇧9는 터미널이 shift 모디파이어를 보고하는 경우에만 동작합니다. 대체 수단은 항상 살아 있습니다. 서브탭 스트립의 **f**는 ⇧0과 같은 피커를 열고, Ctrl-1…Ctrl-9는 그것을 전달하는 터미널에서 ⇧1-⇧9의 별칭입니다.

시프트 줄의 나머지 문장 부호는 반대로 처리합니다. Shift를 눌러야만 나오는 문자(>, ?, {, }, ~, | 등)는 그 자체로 Shift를 눌렀다는 뜻이므로, 터미널이 함께 보고하는 shift 플래그(kitty의 report-all-keys, xterm의 modifyOtherKeys)를 gori가 버립니다. 그래서 이런 터미널에서도 맨 >가 Send flow to…를 열고 ?가 Help를 엽니다.

space 메뉴

메뉴를 처음 익히나요? space 메뉴와 팔레트가 space 메뉴와 두 번째 카드, 팔레트 검색을 5분 연습과 함께 차근차근 안내합니다. 이 절은 레퍼런스입니다. 모든 글자 뒤의 규칙과 전체 표가 있습니다.

탐색 가능한 패널에서 Space를 누르면 지금 서 있는 자리의 액션 메뉴가 열립니다. 그 패널의 동사들이 COMMON과 포커스된 영역 레이블 아래 묶이고, 각 행 앞에 니모닉 한 글자가 붙습니다. 팔레트와는 다릅니다. 입력도 필터도 없고, 한 행당 키 한 번입니다.

↑/↓나 j/k는 선택을 옮기고, ←/→나 h/l은 열을 바꾸며, ↵는 강조된 행을 실행합니다. 어느 단계에서도 h, j, k, l 글자를 쓰는 행은 없으므로, 이 넷은 앱의 모든 목록에서처럼 언제나 움직이기만 하고 습관처럼 누른 j가 동작을 실행하는 일은 없습니다. 이를 어기는 행이 있으면 gori가 시작하지 않습니다. (Send selection to… 카드(S)는 메뉴 단계가 아니라 고르개입니다. JWT에 j, Cookie에 k를 쓰고 화살표로 움직입니다.)

이 규칙과 함께 옮겨진 것: **Link…**와 Manage links는 모든 탭에서 L(원래 k나 l), Add host to scope는 H(원래 h), Activity 피드의 Filter by level은 메뉴에서 v입니다(맨 키는 여전히 l). Discover 탭의 다음/이전 실행과 Fuzzer의 Add List payload set도 옮겨졌고, 이후 메뉴를 떠나 팔레트로 갔습니다.

이름으로 찾고 싶다면 팔레트(Ctrl-P)에 입력하세요. 검색어를 입력하면 팔레트는 앱 전체 명령과 함께 팔레트를 연 패널의 동작도 찾습니다. 그 자리에서 Space가 보여줄 목록과 같고, 메뉴 글자가 없는 동작도 포함됩니다. 패널의 결과가 THIS TAB 아래 먼저 나오고, 앱 명령은 APP 아래에 이어집니다. 탭 행의 오른쪽에는 가장 빠른 길이 표시됩니다. 키가 있으면 그 키를, 없으면 메뉴 글자를 보여줍니다(␣ t는 Space 다음 t, ␣ > c는 Send flow to… 안의 행). 표시해 둔 행이 있으면 space 메뉴처럼 제목이 COMMANDS · 3 MARKED로 바뀌어, 일괄 동작이 그 행 전부에 적용된다는 것을 알 수 있습니다. 검색어가 비어 있으면 예전처럼 앱 명령만 나열합니다.

History 흐름 상세 위에서 열면 팔레트는 상세의 동작을 찾습니다. 팔레트에서 Esc를 누르면 그 상세로 돌아가고, 고른 동작은 화면에 떠 있는 흐름에 적용됩니다.

팔레트에만 있는 동작

space 메뉴는 자주 누르는 것을 위한 곳이고, 드물게 쓰는 것은 팔레트가 맡습니다. 이미 있는 키를 편집이나 이동의 편의로 되풀이할 뿐인 동작, 또는 세션에 한 번쯤 설정을 바꾸는 동작은 메뉴 행이 없습니다. 그 동작이 속한 탭에서 Ctrl-P에 이름을 입력하면 THIS TAB 아래에 나옵니다. 키가 있는 동작은 그 키가 예전과 똑같이 동작하고, Help는 가는 길을 알려 줍니다. 키가 있으면 그 키를, 없으면 ^P → <이름>을 보여줍니다.

탭 동작 키
Repeater Mark word · Edit decoder chain · Pretty-print request Ctrl-K · Ctrl-Q · Ctrl-U
Repeater Minimize request · Use as refresh for slot… · GraphQL: insert introspection query · GraphQL: insert legacy introspection query 팔레트
Fuzzer Mark word · Edit decoder chain · Pretty-print template Ctrl-K · Ctrl-Q · Ctrl-U
Fuzzer Add List payload set · Save results Ctrl-L · ⇧E
Fuzzer Run history 팔레트
History gRPC: reflect schema 팔레트
JWT · Cookie Toggle decode/encode (decode/forge) · Cycle signing alg (format) Ctrl-T · Ctrl-A
Comparer Next change · Previous change ⇧N · ⇧P
Decoder Save chain by name · Load a saved chain · Cycle output mode Ctrl-S · Ctrl-O · Ctrl-X
이슈 상세 Edit title/severity · Retest… t · ⇧R
이슈 상세 Raise severity · Lower severity 팔레트 (Set severity는 Space s 그대로)
Rewriter · Colormarker Move up · Move down ⇧K · ⇧J
Rewriter · Colormarker Reload rules 팔레트
Discover Previous run · Next run 팔레트
Sequencer Export report (JSON)… 팔레트 (Export report는 Space E 그대로)
Project Refresh feed (ACTIVITY) · Change prefix (ENV) 팔레트
Notes Go to line 팔레트

포커스와 무관하게, 탭당 하나의 메뉴

아홉 개 탭이 서브탭 스트립을 가집니다: Repeater, Fuzzer, Miner, Sequencer, Decoder, JWT, Cookie, Comparer, Notes. 예전에는 스트립 자신의 액션도 다른 컨텍스트 섹션과 똑같이 다뤄져서, 스트립에 포커스가 있을 때만 나타났습니다. 그래서 본문 패널에서는 Space가 "이 서브탭 닫기"를 제안하게 하려면 포커스를 한 단계 위로 옮겨야 했습니다.

이제 그것들은 자기 몫의 SUB-TABS 버킷이 되었고, 스트립이 있는 탭이라면 모든 레벨의 메뉴에 들어갑니다. 본문 패널, 스트립 자신, 탭 바입니다. ⇧1-⇧9가 어디로든 데려다주는 만큼, Space가 무엇을 제안하는지가 커서가 놓인 행에 좌우되어서는 안 됩니다.

본문 패널에서 이 버킷은 한 행, T **Sub-tabs…**입니다. 누르면 아래 글자 그대로 버킷 전체가 든 카드가 열리므로, 더 이상 카드의 절반을 차지하지 않습니다. 요청 편집기에서 Space T w가 서브탭을 닫습니다. 스트립이나 탭 바에 포커스가 있을 때는 스트립 자체가 맥락이므로 버킷이 첫 단계에 펼쳐져 그려지고 Sub-tabs… 행은 없습니다. 어느 쪽이든 글자는 같습니다. 스트립에서 n은 패널에서 T n입니다. Paste cURL(U, Repeater)은 패널에서도 자기 행을 그대로 가지며, Ctrl-N / Ctrl-W는 어디서나 동작합니다.

아홉 스트립에서 똑같은 아홉 글자

이 버킷은 아홉 개가 아니라 하나의 표로 익히는 것입니다. 해당 액션이 없는 탭은 그 행을 그냥 빼놓을 뿐, 그 글자를 다른 데 쓰지 않습니다.

키 동작 직접 코드
n 새 서브탭 Ctrl-N
w 서브탭 닫기 (마크된 것 전부) Ctrl-W
d 서브탭 복제
e 서브탭 이름 변경 스트립에서 e
t 현재 서브탭 마크 / 해제 스트립에서 t
f 서브탭 검색(⌕ 피커) 스트립에서 f, 어디서나 ⇧0
/ 스트립 필터 (이름 / 호스트 / 메서드 / 태그) 스트립에서 /
T 필터가 보여주는 서브탭 전부 마크 스트립에서 ⇧T
N 서브탭 마크 해제 스트립에서 Esc
g 서브탭 태그 (Repeater)

Ctrl-N과 Ctrl-W는 해당 행 옆에 표시되며, 아홉 탭 어느 패널에서도 동작합니다. 메뉴가 더 빠른 키를 감추지 않고 가르칩니다. (Miner와 Sequencer는 실행으로 세션을 만들므로 n이 없습니다.)

패널에서 T는 서브탭 전부 마크였는데, 이제 T T이므로 예전 손버릇이 알맞은 카드에 떨어집니다. 메뉴의 t는 스트립의 t와 같이 지금 서브탭을 마크하므로, Repeater의 태그는 어느 스트립 키도 답하지 않는 g로 옮겼습니다.

아홉 글자는 해당 탭의 COMMON 행에서 예약됩니다. COMMON은 스트립에서 펼쳐진 버킷과 같은 카드를 쓰기 때문이며, COMMON 행이 이를 어기면 gori가 시작하지 않습니다. 패널 자신의 행은 더 이상 이 글자와 겨루지 않습니다. 패널에서는 버킷이 한 단계 아래에 있고, 거기서 차지된 것은 Sub-tabs… 행의 T뿐입니다. 모든 패널이 버킷 전체를 그리던 시절에는 패널 동작이 아홉 글자를 내주었습니다. Repeater/Fuzzer 편집기의 Mark word와 JWT·Cookie의 렌즈 토글(지금은 Ctrl-K와 Ctrl-T의 팔레트 전용 동작), JWT와 Cookie의 OUTPUT 복사(C), Notes의 $EDITOR(o)가 그렇습니다. 당분간은 그 글자를 그대로 씁니다.

의도 하나에 글자 하나

여러 탭에 반복되는 동작은 그 동작이 있는 모든 탭에서 같은 메뉴 글자를 씁니다. 글자는 각 행이 아니라 소스의 표 하나(Verb::Lexicon)에서 오므로, 두 탭이 서로 다른 글자로 흘러갈 수 없습니다.

키 동작
/ 이 목록 필터
d 선택한 행 삭제 또는 해제
x · v 줄 선택 · 선택 해제
y · Y · S 복사 · 다른 형식으로 복사… · 선택 영역 보내기…
t · T · N 마크 · 전부 마크 · 마크 해제 (규칙 목록에서 t는 켜기/끄기)
o 선택한 행 열기 (↵의 별칭)
a · e 추가 · 편집. 대부분의 탭에서 a는 이슈 등록도 맡습니다
r · s 실행·전송·다시 읽기 (Ctrl-R의 메뉴 대응) · 중지, A ⇄ B 맞바꾸기, 스코프 렌즈, 이슈 심각도 지정
E 내보내기
K 워크벤치 입력 비우기 (먼저 확인을 묻습니다)
I § 마커 삽입
C § 마커 전부 지우기 · 이슈 상태 설정 · 규칙 복제
L · H Link…(이슈나 노트에 첨부, 또는 링크 관리) · 호스트를 스코프에 추가
O · M · V OAST 페이로드 삽입(History에서는 복사) · 이 응답을 모킹 · 이슈의 CVSS 설정
X 탭 비우기 (먼저 확인을 묻습니다). 다른 용도로는 쓰지 않습니다

/ d x y Y S t T N과 X는 예약입니다. 그 동작이 있는 탭에서는 다른 행이 그 글자를 쓰지 않습니다. 나머지는 그 동작이 있는 곳에서는 그 동작의 글자이고, 없는 탭에서는 탭 고유의 행이 써도 됩니다. Rewriter와 Colormarker의 Enable/disable everywhere가 T인 이유가 이것입니다. X는 비우기입니다.

그 글자를 직접 바인딩하지 않는 탭에서는 어떤 행도 c나 i를 쓰지 않습니다. 거기서 Space를 빠뜨린 입력은 전역 키로 넘어가는데, 그 두 키는 캡처를 멈추고 모든 트래픽을 잡아 둡니다. 그래서 상태 설정, 규칙 복제, 마커 지우기는 C이고, Diff의 Add issue는 자기 ⇧F와 같은 F입니다.

Send flow to…

선택한 플로우를 다른 도구로 넘기는 동작은 > Send flow to… 한 행이고, 누르면 두 번째 카드가 열립니다. 그 안에서는 도구마다 모든 탭에서 같은 글자를 씁니다.

키 플로우를 보내는 곳
r Repeater
f Fuzzer
c Comparer
m Miner (Params 탭의 Mine parameters도)
s Sequencer
a Authorize
D Discover
b 브라우저 (Open response in browser)

그래서 History, Sitemap, Repeater 탭, Fuzzer 결과 어디서든 Space > c가 Comparer로 보냅니다. 탭은 자기가 보낼 수 있는 도구만 보여줍니다. 글자는 Send selection to… 카드(S)와 같습니다. 두 카드 모두 Sequencer가 s이고, Decoder는 거기서 이미 쓰던 d를 그대로 가지므로 Discover가 D입니다.

  • >만 눌러도 이 카드가 열립니다. 이 행이 있는 모든 탭에서 > f는 Space 없이 Fuzzer로 보내고, Space를 빠뜨려도 같은 카드에 도착합니다. >를 다른 동작에 쓰는 탭은 없습니다.
  • Send to Repeater는 자기 글자도 그대로 가집니다. History, 상세, Sitemap, Probe, Evidence, 이슈에서는 r, r이 탭을 실행하는 Fuzzer와 Miner에서는 R입니다.
  • > 행은 탭에 보내기 동작이 있으면 선택한 것이 없어도 그려집니다. 그때 카드는 nothing here right now라고 보여주므로, Space > r을 빠르게 쳐도 아래 패널로 새지 않습니다.
  • Esc나 Backspace는 한 단계 뒤로 가고, Esc를 한 번 더 누르면 닫힙니다. 그 밖의 키는 첫 단계에서와 마찬가지로 메뉴 전체를 닫습니다.
  • 제목은 SPACE › SEND FLOW TO이고, 표시한 행이 있으면 · 3 MARKED가 붙습니다.
  • 직접 키는 그대로입니다. Repeater로 Ctrl-R / r, Fuzzer로 ⇧I가 여전히 동작합니다.

옮겨진 것: History에서는 이 동작들이 c z m q u d ⇧B였고, Discover가 빠지면서 삭제가 자기 맨 키인 d를 가져갔습니다. 상세의 삭제도 d입니다.

Display…와 Protocol…

토글은 카드 두 장에 들어 있습니다. **Z Display…**는 패널이 가진 것을 그리는 방식을 바꾸는 토글이고, **P Protocol…**은 Repeater나 Fuzzer 요청이 보내는 것을 바꾸는 토글입니다. 요청 자체를 고쳐 쓰는 동작(pretty-print request, Ctrl-U 등)은 토글이 아니므로 두 카드 어디에도 들어가지 않습니다.

Display… Protocol…
x 헥스 (History 상세, Repeater 두 패널) 2 HTTP/2
p · u · b Pretty · Unicode 이스케이프 · 공백 s SNI 재정의
d · e 응답 diff · envelope/decoded c Content-Length 자동 계산
s · f · c 정적 자산 · follow · Columns… w Sec-WebSocket-Key 재사용
g · q · J id 접기 · 쿼리 접기 · JS 참조 r · f gRPC reframe · gRPC 필드 편집기
m · v · G Fuzzer: 매치만 · 분포 · 응답 모양별 묶기 t TLS 지문
t · z Comparer: 요청/응답 · 변경 없는 구간 접기
a 모두 보기: Probe의 닫힌 이슈, Params 탭의 표준 헤더

두 카드는 sticky입니다. 행을 실행하면 카드가 같은 행에서 다시 열리므로 한 번에 두세 개를 바꿀 수 있고, 각 행은 상태를 보여줍니다. ●는 켜짐, ○는 꺼짐, TLS 프리셋 이름 같은 값도 있습니다. Esc로 닫습니다. 행이 SNI 필드, gRPC 필드 목록, 요청 헥스 편집기, 컬럼 편집기처럼 자기 것을 열었거나 포커스를 옮겼다면 카드는 다시 열리지 않습니다.

  • ⇧Z와 ⇧P만 눌러도 카드가 열립니다. >와 같습니다. Space 없이 Z c를 쳐도 캡처를 멈추는 맨 c가 아니라 Columns…에 도착합니다.
  • Display…는 V가 아니라 Z입니다. vim 키셋에서는 이 토글이 있는 모든 패널에서 ⇧V가 줄을 선택하므로, Space를 빠뜨리면 카드 대신 선택이 일어납니다.
  • Fuzzer의 Cycle sort는 결과를 읽을 때 가장 자주 누르는 행이라 직접 행(Space o)으로 남습니다.
  • 직접 키는 그대로입니다. Ctrl-X 헥스(Repeater에서는 포커스가 있는 패널의 것: 요청의 헥스 편집이나 응답의 헥스 덤프이며, 두 행 모두 이 키를 보여줍니다), p pretty, u Unicode, b 공백, ⇧D diff, Ctrl-T envelope, a 모두 보기, Ctrl-V HTTP/2, Ctrl-S SNI, Ctrl-L Content-Length 자동 계산.

옮겨진 것: 헥스는 History 상세에서 e, Repeater 요청 패널에서 x, 응답 패널에서 h였고 이제 셋 모두 Z x입니다. Probe의 Show closed와 Params 탭의 All headers는 Space a였고 이제 Z a이며, Params의 Mine parameters는 Space m에서 > m으로 옮겼습니다. 맨 a와 m은 그대로 동작합니다. Fuzzer의 결과 저장은 P를 내주었습니다(내보내기 코드인 ⇧E이며, 팔레트 전용입니다). History 상세의 Copy flow 행은 없어졌습니다. REQUEST 패널에서 Space Y(Copy as…)의 Raw request가 같은 텍스트입니다.

에디터 키셋

gori의 텍스트 패널은 모달입니다. Esc와 i로 READ와 INSERT를 오가고, READ에서는 맨 글자가 명령입니다. 기본으로 제공되는 문법은 helix 형태로, 먼저 선택하고 그다음 동작합니다. x로 줄을 선택한 뒤 y로 복사하거나 d로 지우고, p로 붙여넣습니다. vim에서는 같은 편집을 yy, dd, p, 또는 V 다음 y / d로 쓰며, 그 차이가 vim에 익숙한 손이 하루 종일 부딪히는 지점입니다.

Preferences → Editor & Keys → Keys → Editor keyset(Ctrl-,) 또는 팔레트의 **settings:keys**에서 전환합니다. 팔레트(Ctrl-P)에 vim, helix, keyset을 입력해도 이 항목이 나옵니다. 첫 실행 마법사(gori wizard)는 키셋을 묻지 않고, Review 스텝에서 현재 키셋과 이곳을 알려 줍니다. Editor keyset 아래의 Keyset playground 행은 시험 중인 키셋으로 동작하는 세 줄짜리 연습 패드를 열어 x d와 dd를 직접 눌러 보고 정할 수 있게 하며, 그 키셋의 READ 모드 키를 모두 그 아래에 보여 줍니다. ↑/↓로 키셋을 바꾸고, ⇥, ↵, 아무 글자를 누르면 패드로 들어갑니다. 체험만 하는 곳이므로 키셋은 바로 위의 Editor keyset 행에서 고릅니다. 패드에서 복사한 내용은 gori의 붙여넣기 레지스터에만 남고 클립보드에는 들어가지 않으며, playground는 닫힐 때 레지스터를 원래대로 되돌립니다.

키셋 줄 선택 줄 삭제 줄 복사 붙여넣기 실행 취소 찾기 뒤에 삽입 맨 위 / 맨 아래
helix-ish (기본) x x 다음 d x 다음 y p Ctrl-Z Ctrl-F — —
vim-ish ⇧V dd yy p u / a g / ⇧G

표에 없는 것은 두 키셋에서 동일합니다. gori가 이미 vim과 같게 쓰고 있기 때문입니다. i로 INSERT에 들어가고, Esc로 나오고, Ctrl-G로 줄로 이동하고, 화살표에 Shift를 더해 선택을 넓힙니다. READ에서는 모든 텍스트 패널에서 h j k l이 화살표처럼 커서를 움직이고, ⌥← / ⌥→(Linux와 Windows에서는 Ctrl)는 단어 단위로 이동합니다. 삭제와 복사 키는 줄뿐 아니라 어떤 선택에도 작용합니다. vim-ish에서 ⇧V 다음 d나 y는 vim과 똑같이 동작합니다.

줄 선택은 넓혀도 줄 단위를 유지합니다. 두 키셋 모두 ⇧↑ / ⇧↓가 한 줄씩 더하고, vim-ish에서는 그냥 j / k도 그렇게 하므로 ⇧V j j d는 세 줄을 지웁니다. 옆으로 움직이면 보통의 문자 선택이 됩니다. 두 키셋 모두 READ 선택 위에서 Esc를 누르면 선택이 풀리고, 그다음 Esc가 전처럼 패널을 나갑니다.

vim-ish에서는 READ에서 w / b로 단어 단위 이동을 하고, ⇧A / ⇧I로 커서가 있는 줄의 끝 / 처음에서 입력을 시작합니다.

READ에서 삭제와 붙여넣기

모든 텍스트 에디터 패널에서 동작합니다. Repeater 요청, Fuzzer 템플릿, Intercept 에디터, Notes, 이슈 노트, Project 설명, 그리고 Decoder·JWT·Cookie 입력입니다.

  • 삭제(선택 뒤 d, vim-ish에서는 dd)는 텍스트를 지우고 p를 위해 보관합니다. 줄 전체를 선택했다면 줄바꿈까지 함께 지워 빈 줄이 남지 않습니다.
  • 붙여넣기(p)는 마지막으로 복사하거나 지운 것을 캐럿 뒤에 되돌려 놓습니다. 줄 단위로 가져온 것은 캐럿이 있는 줄 아래에 새 줄로 들어가고, 그 밖의 것은 줄 안에 삽입됩니다.
  • p가 붙여넣는 내용은 gori 자체의 붙여넣기 레지스터에 있습니다. gori의 모든 복사(y와 복사 선택기)와 모든 삭제가 이 레지스터를 채웁니다. 시스템 클립보드는 읽지 않습니다. 터미널이 클립보드를 돌려주기를 거부하거나 먼저 확인을 요구하기 때문입니다. 다른 프로그램의 텍스트는 지금처럼 터미널 붙여넣기로 가져오면 되고, 그러면 INSERT가 저절로 열립니다. 삭제는 시스템 클립보드를 덮어쓰지 않습니다.
  • READ에서 한 편집도 평범한 편집이고, 패널은 직접 입력한 것과 똑같이 다룹니다. Repeater는 Content-Length를 맞추고, Fuzzer는 § 마커를 그대로 보호하며, 이슈 노트는 Esc처럼 저장됩니다. Ctrl-Z(vim-ish에서는 u)는 삭제를 한 번에 되돌리고, 붙여넣기는 그 패널에서 터미널 붙여넣기가 되돌아가는 방식대로 되돌립니다. 대부분 한 번이지만, 붙여넣기를 키 단위로 받는 Project 설명과 이슈 노트에서는 줄 단위로 되돌아갑니다.
  • 선택이 없으면 helix-ish의 d는 지우지 않고 그렇다고 알려 줍니다. vim-ish에서는 첫 d나 y가 두 번째 키를 기다리고, 다른 키를 누르면 취소되며, Esc는 메시지 없이 취소합니다. vim-ish에서 선택 없이 누른 y는 패널 전체를 복사하지 않고 yy를 기다리므로, 전체 복사에는 Ctrl-Y를 쓰세요.
  • 읽기 전용 패널은 자기 글자를 유지합니다. Repeater 응답과 History 상세에서 p는 여전히 Pretty bodies입니다.

키셋은 매핑이지 에뮬레이션이 아닙니다

키셋은 소수의 고정된 에디터 동작에 대한 키 재정의 묶음입니다. OS 기본 프로파일이 쓰는 것과 정확히 같은 메커니즘을 한 층 위에 얹은 것입니다. 연산자 뒤의 모션도, 반복 횟수도, 텍스트 오브젝트도, 이름 붙은 레지스터도, gori의 패널에 없는 편집 연산도 추가하지 않습니다. READ 모드 패널은 캐럿, 선택 영역, 복사, 삭제, 붙여넣기가 전부이고, 없는 연산에 키 이름을 붙이는 것이야말로 "vim 모드"가 지키지 못할 약속이 되는 길입니다.

그래서 일부 vim 표기는 의도적으로 제공하지 않습니다. 각각 확인 가능한 이유가 있습니다.

  • dd와 yy를 뺀 gg 등 두 키 시퀀스 전부. gori의 키 조합은 한 번의 키 입력입니다. dd와 yy만 예외로, 첫 입력이 두 번째를 기다립니다. g 하나가 패널 맨 위입니다. d와 y는 모션을 받지 않으므로 dw, dj, d2d는 추측하지 않고 취소합니다.
  • $와 0. $는 네 번째 서브탭으로 이동하는 ⇧4로 들어오고, 0은 Go to tab을 엽니다. 에디터가 둘 중 하나를 가져가면 텍스트 패널 안에서 그 키를 잃습니다. 줄 끝과 처음은 두 키셋 모두 End와 Home으로 갑니다.
  • :42를 포함한 : 명령. 맨 :는 gori 자체의 명령줄로 예약되어 있으므로, go-to-line은 두 키셋 모두에서 Ctrl-G로 남습니다.
  • x, D, P, o, J 등 vim의 나머지 편집 키. gori의 READ 모드 편집은 삭제와 붙여넣기이고, 나머지는 INSERT에서 일어납니다.
  • 규칙 목록의 활성/비활성(Colormarker, Probe rules, OAST providers, Rewriter). 넷 모두 t입니다. 규칙을 켜고 끄는 것이지 선택이 아니므로 어떤 키셋도 옮기지 않습니다.
  • Intercept 큐의 줄 선택. 의도적으로 키가 없습니다. 그 패널은 space 메뉴로 닿고, 키셋은 있는 키의 표기만 바꿀 뿐 키 없이 설계된 패널에 키를 새로 주지 않습니다.

재정의 순서

가장 구체적인 것부터 네 겹입니다.

직접 지정한 재바인딩  >  키셋  >  OS 기본 프로파일  >  기본 제공 키 조합

따라서 키셋은 더 나은 기본값이지 상한이 아닙니다. vim-ish를 고른 뒤 Hotkeys 에디터에서 동작 하나를 재지정하면, 그 하나는 지정한 자리에 그대로 남습니다. 행의 "기본값으로 되돌리기"는 현재 키셋의 표기로 되돌아가며, 기본 제공 키로 돌아가지 않습니다.

모든 화면이 별도 조치 없이 현재 키셋을 따릅니다. 전부 유효 키맵에서 읽기 때문입니다. 상태 표시줄 힌트 스트립, Help 탭, 커맨드 팔레트, space 메뉴, 그리고 Hotkeys 에디터의 충돌 메시지까지 모두 그렇습니다. vim-ish에서 Notes 푸터는 ^F find 대신 / find로 읽히고, ⇧V에 무언가를 바인딩하려 하면 Select line이 거기 있다고 이름을 대며 거절합니다.

space 메뉴의 글자는 건드리지 않습니다

키셋이 옮기는 것은 패널에서 누르는 키이지, space 메뉴가 각 행 앞에 붙이는 글자가 아닙니다. 개별 재지정이 따르는 규칙과 같고, 그 글자들이 안정적인 식별자인 이유이기도 합니다. vim-ish에서도 메뉴는 Select line을 여전히 x로 앞세우고, 그 옆에 실제 키 조합을 함께 씁니다.

│ x Select line   ⇧V │

그래서 카드가 둘 중 어느 쪽인지 짐작하게 만드는 대신 양쪽을 모두 가르쳐 줍니다. 아홉 개 SUB-TABS 글자(n w d e t f / T N, 패널에서는 Sub-tabs… 안)도 어떤 키셋을 고르든 아홉 스트립 전부에서 같은 뜻입니다. 두 네임스페이스는 충돌할 수 없습니다. 메뉴는 모달이고, 키셋은 키맵에만 씁니다.

/도 마찬가지입니다. SUB-TABS 글자이면서 동시에 vim-ish의 찾기 키지만, 둘은 다른 계층입니다. 메뉴 글자는 카드가 떠 있는 동안 스트립에 작용하고, 키 조합은 지금 서 있는 텍스트 패널을 검색합니다. 의도적으로 겹치는 패널 키 하나는 Repeater의 읽기 전용 응답에서 쓰는 u입니다. 표시 전용 JSON 유니코드 디코딩을 켜고 끕니다. 요청 편집기는 여전히 Editor 스코프에 있어 u가 실행 취소입니다. validate_chords!는 부팅 시 같은 스코프 안의 충돌을 검사하며, 이 교차 스코프 예외는 spec/verb/keyset_spec.cr에 고정했습니다.

몇몇 메뉴 글자는 편집기 패널에서 vim-ish 모션이기도 합니다. Auto-mark a(append), Repeater·Cookie·이슈 상세의 g(맨 위), Send race ⇧G(맨 아래), Set CVSS V(줄 선택), Insert marker ⇧I와 Probe active ⇧A(줄 끝·처음에서 입력 시작)입니다. 그 앞의 Space를 빠뜨리면 키는 vim이 하는 대로 동작하며, 이동하거나 선택하거나 입력을 시작할 뿐 보내거나 쓰거나 지우지 않습니다. 편집 글자가 두 키셋 모두에서 의도한 또 하나의 겹침입니다. 텍스트 에디터 안에서 d, y, p는 에디터의 글자이므로, 메뉴의 d(이슈 노트의 Delete issue)나 y(Copy) 앞의 Space를 빠뜨리면 그 패널의 텍스트를 편집하거나 복사하고, 그렇다고 알려 주며, 실행 취소로 되돌릴 수 있습니다. 패널에서 그 밖의 동작에 걸리는 메뉴 글자는 허용하지 않습니다.

무엇을 고르든 그대로인 것

vim-ish에서도 Ctrl-Z는 INSERT 안에서 계속 실행 취소입니다. 그 가드는 모든 텍스트 에디터에서 키맵보다 먼저 동작하고, 타이핑하는 손이 원하는 자리가 거기입니다. Ctrl-F도 마찬가지로 INSERT를 포함해 계속 찾기 프롬프트를 엽니다. /는 READ에서의 추가이지 대체가 아닙니다. 그리고 에디터 옆의 읽기 전용 패널(Repeater 응답, Fuzzer 결과, Decoder 출력)에서 i는 두 키셋 모두에서 메시지와 함께 거절됩니다.

예약된 키

일부 키는 터미널이나 gori가 필요로 하므로 재지정할 수 없습니다.

  • 종료: Ctrl-C, Ctrl-D.

  • 명명된 키와 구별 불가: Ctrl-M / Ctrl-J (Enter), Ctrl-I (Tab), Ctrl-H (Backspace), Ctrl-[ (Escape).

  • 구조적: Enter, Esc, Tab, Backspace, Space(space 메뉴 리더), 그리고 맨 :(명령줄).

  • 키맵보다 먼저 점유되는 gori 단축키: Ctrl-G (go to line), Ctrl-F (find, Tab으로 find & replace), Ctrl-B (reveal whitespace), Ctrl-E (external editor), Ctrl-P (command palette), Ctrl-N (new repeater/fuzz/note), Ctrl-W (서브탭 닫기, 마크가 있으면 전부), Ctrl-Z (undo. 모든 텍스트 에디터가 소비합니다: Repeater, Fuzzer, Notes, Issues, Intercept, Decoder, JWT, Cookie, Rewriter, Project 설명), Ctrl-, (Preferences), 그리고 Ctrl-1…Ctrl-9 (switch sub-tab, ⇧1-⇧9의 별칭입니다. 숫자 키 패밀리 참고). 이들은 키맵보다 먼저 하드코딩된 가드로 처리되므로, 여기에 바인딩해도 절대 발동하지 않습니다. 같은 이유로 Command palette, Reveal whitespace, Quit, Back to projects, 각 탭의 New …(Repeater, Fuzzer, Decoder, JWT, Cookie, Notes, Comparer)와 서브탭 닫기 동작은 에디터에 나열되지 않습니다. 그 키는 고정입니다.

    이 패밀리에서 개별 키를 옮길 수는 없지만, 패밀리 전체에 두 번째 모디파이어를 줄 수는 있습니다. 아래 커맨드 모디파이어를 참고하세요.

    Ctrl-G / Ctrl-F는 포커스가 있는 여러 줄 패널에 적용됩니다. Repeater의 요청/응답, History 상세, Intercept 편집기, Notes, Project 설명, Decoder의 INPUT/OUTPUT, Fuzzer의 템플릿/결과 상세입니다. 편집 가능한 여섯 곳에서는 Tab이 find를 find & replace로 바꿉니다. 나머지는 읽기 전용이고, 프롬프트가 할 수 없는 교체를 제안하는 대신 그렇다고 알려줍니다.

Ctrl-S 같은 흐름 제어/시그널 키 조합은 예약되어 있지 않습니다. gori는 터미널을 raw 모드로 실행하므로 이들이 앱에 도달합니다(Repeater의 SNI 토글은 Ctrl-S로 제공됩니다).

OS 기본 프로파일

← / → 프로파일 선택기는 새(재정의되지 않은) 바인딩이 어떤 기본 키 세트를 사용할지 고릅니다: auto(gori가 빌드된 플랫폼을 추적), macOS, Linux, Windows. 직접 지정한 재바인딩은 OS와 무관하게 항상 선택한 프로파일 위에 얹힙니다.

현재 OS별 기본값은 동일합니다. 터미널에서 Ctrl+글자 조합은 macOS, Linux, Windows 모두에서 애플리케이션에 도달하며, 정말 위험한 키는 위의 예약된 제어 문자들입니다(어디서나 차단됨). 프로파일 메커니즘은 실제 터미널별 충돌이 생겼을 때 디스패치를 건드리지 않고 바로잡을 수 있도록 마련해 둔 것입니다. 지금으로서는 auto가 모두에게 옳은 선택입니다.

커맨드 모디파이어

예약된 키에 나열된 키 조합 패밀리는 키맵보다 먼저 하드코딩된 가드가 소비하기 때문에 고정입니다. 문제는 터미널이 Ctrl 형태를 아예 전달하지 않는 경우입니다.

  • Ctrl-1…Ctrl-9는 상당수 터미널에서 전달 불가입니다. 대응하는 제어 문자가 없어서 서브탭 점프가 애초에 도착하지 않습니다. 없어도 됩니다. 서브탭 점프의 기본 키는 **⇧1-⇧9**이고(숫자 키 패밀리), 서브탭 스트립에서는 어느 칩에 있든 **f**로 열려 있는 서브탭 전체를 나열·검색할 수 있습니다. (스트립 왼쪽 끝의 **⌕**도 같은 목록을 엽니다. 클릭하거나, 첫 칩에서 ←를 누르면 됩니다.)
  • 멀티플렉서가 먼저 먹습니다. tmux의 기본 프리픽스는 Ctrl-B인데, gori도 reveal-whitespace로 씁니다.

Preferences → Editor & Keys → Keys → Command modifier(Ctrl-,), 또는 팔레트의 **settings:keys**에서 이 패밀리를 Ctrl과 Option (⌥) 사이에서 고를 수 있습니다. 이는 교체가 아니라 별칭 추가입니다. Option을 고르면 ⌥P로도 팔레트가 열리고 ^P도 그대로 동작합니다. 바뀌는 것은 표시뿐입니다. 상태 힌트, Help 탭, 팔레트가 모두 ⌥P, ⌥N, ⌥1-9로 표시됩니다.

모디파이어 동작
Ctrl (기본) ^P ^N ^W ^G ^F ^B ^E ^Z ^, ^1-^9
Option (⌥) 위 전부 더하기 ⌥P ⌥N ⌥W ⌥G ⌥F ⌥B ⌥E ⌥Z ⌥, ⌥1-⌥9

Ctrl이 계속 살아있으므로 Option을 골라도 팔레트에 못 들어가는 상황은 생기지 않습니다. 다만 바꾸기 전에 알아둘 점이 있습니다. macOS에서는 터미널이 Option을 Meta/Esc+로 보내도록 설정해야 합니다. 그러지 않으면 ⌥P가 π로 도착해 아무 일도 일어나지 않습니다.

  • Terminal.app: 설정 → 프로파일 → 키보드 → Option을 Meta 키로 사용
  • iTerm2: Settings → Profiles → Keys → Left/Right Option key → Esc+

하지 않는 일 두 가지. 에디터에서 이미 재지정할 수 있는 키 조합(^R send, ^S SNI 등)은 건드리지 않습니다. 그건 동작별로 재지정하세요. 그리고 이 패밀리의 Option 조합(예: alt-n)에 어떤 동작을 바인딩해 뒀다면, 별칭을 켜는 순간 가려집니다. 가드가 이기고 해당 동작은 기본값으로 되돌아가며, 저장 토스트가 그 동작을 알려줍니다.

첫 실행 마법사의 Review 스텝에서도 이 값을 요약해 보여주므로, 앱에 들어가기 전에 모디파이어를 고를 수 있습니다.

저장 위치

~/.gori/settings.json(디렉터리는 $GORI_HOME으로 재정의)의 hotkeys 블록에, 필요한 값만 담아 저장됩니다. 변경한 바인딩만 동작 id별 키 조합 라벨 목록으로 기록되며, 빈 목록은 명시적 바인딩 해제입니다.

{
  "hotkeys": {
    "os": "auto",
    "command_modifier": "alt",
    "keyset": "vim",
    "bindings": {
      "rules.edit": ["g"],
      "scope.edit": []
    }
  }
}

command_modifier는 "ctrl"(기본) 또는 "alt"이고, keyset은 "helix"(기본) 또는 "vim"입니다. 에디터 키셋을 참고하세요. 둘 다 알 수 없는 값은 키가 없는 상태가 아니라 기본값으로 되돌아갑니다. 손대지 않은 설치본은 hotkeys 블록 자체를 쓰지 않습니다.

없는 동작은 프로파일 기본값을 사용합니다. 알 수 없는 id와 파싱할 수 없는 키 조합은 로드할 때 무시되므로, 수동 편집이나 버전 차이가 있어도 무리 없이 동작합니다.

제약

  • 동작의 주 키 조합만 표시/편집됩니다. 탐색 별칭(예: j / k의 화살표 키 중복)은 나열되지 않습니다.
  • 재지정 가능한 키 조합을 표시하는 모든 화면은 유효 키맵에서 읽습니다. 커맨드 팔레트, space 메뉴, Help 탭과 팝업, 상태 표시줄의 힌트 스트립, 빈 상태 카드가 여기에 해당합니다. 리터럴로 남는 것은 동작(verb)이 아닌 키입니다. 예약된 ^P / ^N / ^W / ^1-9 계열과 구조 키(esc, ↵, 화살표, ↹)가 그렇습니다.
  • Space 메뉴 니모닉 글자는 동작을 가리키는 안정적인 식별자입니다(Helix와 비슷). 재지정은 직접 누르는 키 조합만 바꿀 뿐 space 메뉴 글자는 바꾸지 않습니다.
  • 서브탭 스트립이 어떤 동작에 글자를 바인딩해 두었다면 메뉴도 같은 글자로 그 동작을 씁니다: t는 서브탭 마크, f는 서브탭 목록·검색, ⇧T는 스트립 전체 마크, e는 이름 변경입니다. 이름 변경은 원래 스트립에서 r이었지만, Repeater·Fuzzer·Miner·Sequencer에서 r은 Ctrl-R을 메뉴에서 되울리는 Run/Send이므로, 메뉴를 바꾸는 대신 스트립이 메뉴의 e로 옮겼습니다. 이제 스트립의 r은 아무 동작도 하지 않습니다. 전체 표는 space 메뉴를 참고하세요.
  • 에디터 동작은 개별로도, 에디터 키셋으로 한 벌씩도 재지정할 수 있습니다. 재지정 에디터가 옮기지 않는 것은 하드코딩된 가드가 먼저 응답하는 몇 개뿐입니다: Esc(READ로 복귀), Ctrl-Z, Ctrl-F, Ctrl-G. 읽을 수 있도록 Help 시트에는 실려 있고, 키셋은 여기에 두 번째 맨 글자 표기를 줄 수 있습니다. vim-ish가 u와 /에 도달하는 방식이 바로 이것입니다.
  • 탐색 가능한 컨텍스트에서 **?**를 누르면 Help 탭(mitmproxy 스타일 치트시트)으로 점프합니다.

다음 단계

  • Settings: Preferences 모달과 그 안의 모든 섹션
  • Themes: 같은 방식으로 컬러 테마를 전환하거나 만듭니다
  • Configuration Reference: settings.json의 hotkeys 키