Terminal 텍스트 선택 중에는 Task 종료 단축키 잠그기
Task Terminal의 출력을 선택해 복사하는 동안에는 종료 단축키를 막고, 선택을 해제하면 다시 켜지는 안전한 User 단축키를 만듭니다.
이번 편의 핵심
!terminalTextSelected를 추가해 선택 없음 → ON, 텍스트 선택 → OFF 전환을 확인하고 실습 설정을 원복합니다.
출력을 복사하려다 종료 chord를 눌러 실행 중인 Task를 끊는 실수를 줄이는 것이 목표입니다.
1. 시작하기 전에
난이도는 초급 후반입니다. User 범위 JSON 한 곳과 Workspace 범위 Task 두 개를 다루며, 실제 종료 전에 네 Context Key와 Target label을 확인해야 합니다.
준비할 것
- Windows 11, VS Code Stable 1.137.0, PowerShell — Help > About과
$PSVersionTable로 확인합니다. - 신뢰 가능한 연습 폴더 — File > Open Folder로 열고 Restricted Mode가 아닌지 확인합니다.
- User
keybindings.json백업 — Preferences: Open Keyboard Shortcuts (JSON)에서 전체 파일을 별도 위치에 복사합니다. - 기존
.vscode/tasks.json— 파일이 있으면 전체 덮어쓰기 없이 예제 객체만tasks배열에 병합합니다.
적용 환경 한국어 초보자 · Windows 11 · VS Code Stable 1.137.0 · Windows PowerShell
2. 알아둘 핵심 개념
terminalTextSelected와 논리 NOT !
terminalTextSelected는 활성 Terminal에 텍스트 선택 영역이 있으면 true입니다. 앞의 !는 Boolean을 뒤집으므로 !terminalTextSelected는 선택이 없을 때 true, 선택이 있을 때 false입니다.
네 Context Key가 만드는 gate
taskRunning: 하나 이상의 Task가 실행 중입니다.terminalFocus: 통합 Terminal이 키보드 포커스를 가집니다.taskTerminalActive: 활성 Terminal이 Task가 만든 Terminal입니다.terminalTextSelected: 활성 Terminal에 선택된 텍스트가 있습니다.
&&는 모든 조건을 요구합니다. 따라서 전체 식은 실행 중 Task Terminal에 포커스가 있고 선택이 없을 때만 종료 rule을 허용합니다. 하지만 이 gate는 args의 Target이 실행 중인지까지 보장하지 않으므로 Target 부재 Quick Pick을 따로 확인해야 합니다.
3. 순서대로 진행하기
각 단계의 정상 결과를 확인한 뒤 다음 단계로 이동합니다. Ctrl+K Ctrl+Alt+T는 예시 chord이며 충돌하면 미사용 chord로 바꾸세요.
1. User 단축키를 백업하고 충돌 확인하기
목적 기존 단축키를 보호하고 예제 chord의 선점 여부를 확인합니다.
- Ctrl+K Ctrl+S를 열어
ctrl+k ctrl+alt+t를 검색하고 Show Same Keybindings를 확인한 뒤 Userkeybindings.json전체를 별도 백업 파일에 복사합니다.
입력 위치 Keyboard Shortcuts UI, User keybindings.json, 사용자가 선택한 로컬 백업 폴더
C:\Users\<사용자이름>\Documents\keybindings.backup-20260912.json
<사용자이름>은 실제 Windows 계정 폴더명으로 바꿉니다. 이 경로는 파일에 입력하는 설정이 아니라 백업 위치 예시입니다.
정상 결과 충돌 rule과 적용 조건을 확인했고 백업의 첫 줄과 마지막 줄이 보입니다.
확인 백업을 다시 열어 JSON 전체가 읽히는지 확인합니다.
실패 신호 빈 백업, JSON 잘림, 중요 명령과 chord 충돌
2. 두 연습용 process Task 추가하기
목적 종료 Target과 Target 부재 확인용 Guard를 분리합니다.
.vscode/tasks.json의tasks배열에 아래 두 객체를 추가하고 저장합니다.
입력 위치 연습 Workspace의 .vscode/tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "JCOS Selection Lock Target",
"type": "process",
"command": "powershell.exe",
"args": [
"-NoProfile",
"-Command",
"$id=[guid]::NewGuid().ToString('N').Substring(0,8); Write-Output ('SELECTION_LOCK_TARGET RUN_ID='+$id); for($i=0;$i -lt 30;$i++){ Write-Output ('SELECTION_LOCK_TARGET HEARTBEAT='+$i); Start-Sleep -Seconds 1 }"
],
"problemMatcher": [],
"presentation": { "reveal": "always", "panel": "dedicated", "clear": true }
},
{
"label": "JCOS Selection Lock Guard",
"type": "process",
"command": "powershell.exe",
"args": [
"-NoProfile",
"-Command",
"$id=[guid]::NewGuid().ToString('N').Substring(0,8); Write-Output ('SELECTION_LOCK_GUARD RUN_ID='+$id); for($i=0;$i -lt 30;$i++){ Write-Output ('SELECTION_LOCK_GUARD HEARTBEAT='+$i); Start-Sleep -Seconds 1 }"
],
"problemMatcher": [],
"presentation": { "reveal": "always", "panel": "dedicated", "clear": true }
}
]
}
정상 결과 Tasks: Run Task 목록에 JCOS Selection Lock Target과 JCOS Selection Lock Guard가 보입니다.
확인 JSON parser 오류가 없고 두 label이 정확히 일치합니다. type은 String, args는 String Array, problemMatcher는 Array입니다.
실패 신호 Expected comma, End of file expected, Task가 목록에 없음
tasks.json 전체를 덮어쓰지 마세요. 되돌리기: 기존 배열을 복원하고 예제 객체를 하나씩 병합하며 오류 원문을 보존합니다.3. Target Task를 실행하고 선택 없음 확인하기
목적 Task Terminal과 관찰 가능한 RUN_ID/HEARTBEAT를 만들고 선택 없는 기준 상태를 확인합니다.
- Ctrl+Shift+P > Tasks: Run Task > JCOS Selection Lock Target을 선택하고 Terminal의 빈 곳을 한 번 클릭합니다.
입력 위치 Command Palette와 자동으로 열린 전용 Terminal
SELECTION_LOCK_TARGET RUN_ID=<8자리 값>
SELECTION_LOCK_TARGET HEARTBEAT=<증가 숫자>
정상 결과 RUN_ID 한 줄 뒤 HEARTBEAT가 1초마다 증가하고 텍스트 선택 영역이 없습니다.
확인 Developer: Inspect Context Keys에서 taskRunning=true, terminalFocus=true, taskTerminalActive=true, terminalTextSelected=false를 확인합니다.
실패 신호 즉시 종료, PowerShell 경로/정책 오류, 다른 Task label, 선택 영역 잔존
4. 네 조건을 가진 종료 rule 저장하기
목적 Task Terminal의 텍스트 선택 중에는 Target 종료 명령을 비활성화합니다.
- User
keybindings.json배열에 다음 객체를 추가하거나 이전 편 객체의when만 교체합니다.
입력 위치 Preferences: Open Keyboard Shortcuts (JSON), User 범위
[
{
"key": "ctrl+k ctrl+alt+t",
"command": "workbench.action.tasks.terminate",
"args": "JCOS Selection Lock Target",
"when": "taskRunning && terminalFocus && taskTerminalActive && !terminalTextSelected"
}
]
정상 결과 Keyboard Shortcuts 검색 결과에 명령, chord, 네 조건이 한 User rule로 표시됩니다.
확인 key, command, args, when은 모두 String입니다. && 앞뒤 공백과 terminalTextSelected 앞의 !를 확인합니다.
실패 신호 빨간 밑줄, 쉼표 오류, 같은 rule 중복, terminalTextSelected 오탈자
5. 선택 없음에서 rule 활성 확인하기
목적 모든 조건이 true일 때 종료 rule이 활성인 기준선을 만듭니다.
- Target Task Terminal 본문을 클릭하고 Esc를 눌러 선택을 비운 뒤 Context Key와 Target RUN_ID를 기록합니다.
입력 위치 Target Task Terminal, Developer: Inspect Context Keys
terminalTextSelected = false
!terminalTextSelected = true
종료 rule = ON
정상 결과 Keyboard Shortcuts UI에서 rule이 활성이고 네 Context Key가 기대값과 일치합니다.
확인 실제 종료는 아직 하지 않고 Developer: Toggle Keyboard Shortcuts Troubleshooting을 켜 로그 준비 상태만 확인합니다.
실패 신호 terminalTextSelected=true가 남아 있거나 rule이 비활성
6. 텍스트 선택으로 종료 chord 잠그기
목적 복사하려는 출력이 선택된 동안 종료 명령이 dispatch되지 않음을 확인합니다.
- Target Terminal에서 RUN_ID 줄 일부를 마우스로 드래그해 선택하고 Context Key를 다시 검사한 뒤 chord를 한 번 누릅니다.
입력 위치 Target Task Terminal과 Keyboard Shortcuts Troubleshooting Output
terminalTextSelected = true
!terminalTextSelected = false
종료 rule = OFF
정상 결과 종료 rule은 match되지 않고 동일 RUN_ID의 HEARTBEAT가 계속 증가합니다.
확인 Troubleshooting 로그에 종료 command 미호출이 보이고 2초 뒤 Target 출력이 증가합니다.
실패 신호 Target 종료, 다른 명령 실행, 선택 영역 소실
7. Ctrl+C 복사와 선택 해제 후 재활성 확인하기
목적 선택 보호가 복사 흐름을 방해하지 않고 선택 해제 후 종료 rule이 다시 활성화되는지 확인합니다.
- 선택이 유지된 상태에서 Ctrl+C로 복사해 저장하지 않을 새 임시 편집기에 붙여넣고, Terminal로 돌아와 Esc로 선택을 해제합니다.
입력 위치 Target Task Terminal과 새 임시 텍스트 편집기
복사 결과 = 선택한 RUN_ID 문자열
terminalTextSelected = true → false
종료 rule = OFF → ON
정상 결과 붙여넣은 문자열이 선택한 출력과 일치하고 Esc 뒤 rule이 다시 활성화됩니다.
확인 Context Key에서 terminalTextSelected=false를 확인하고 Target HEARTBEAT가 계속 증가하는지 봅니다.
실패 신호 복사 내용 불일치, Esc 뒤 선택 잔존, rule 비활성
8. 선택 없음에서 Target 종료하기
목적 보호할 선택이 없을 때만 Target을 종료합니다.
- 선택 영역이 없고 label/RUN_ID가 맞는지 확인한 뒤 chord를 한 번 누릅니다.
입력 위치 Target Task Terminal
Human Gate
label = JCOS Selection Lock Target
terminalTextSelected = false
RUN_ID = <Step 3에서 기록한 값>
정상 결과 Target만 종료되고 동일 RUN_ID의 출력이 더 이상 증가하지 않습니다.
확인 2초 뒤 출력 길이가 그대로이며 Tasks: Show Running Tasks에 Target이 없습니다.
실패 신호 Quick Pick 열림, 다른 Task 종료, 새 RUN_ID 생성
9. Target 부재 fallback을 취소하고 원복하기
목적 gate가 Target 존재를 보장하지 않는 한계를 확인하고 실습 상태를 제거합니다.
- Guard Task를 실행하고 선택이 없는 Guard Terminal에서 chord를 누른 뒤 나타난 Quick Pick을 Esc로 닫습니다. 이어 Guard를 수동 종료하고 keybinding 객체와 두 Task 객체를 제거합니다.
입력 위치 Guard Task Terminal, Select a task to terminate Quick Pick, User keybindings.json, Workspace .vscode/tasks.json
Target = 없음
Guard = 실행 중
Quick Pick = Esc로 취소
최종 User rule / 예제 Task = 없음
정상 결과 Esc 취소 뒤 Guard가 계속 실행되고, 정리 후 실행 중 연습 Task·User rule·예제 label이 모두 없습니다.
확인 Tasks: Show Running Tasks, Keyboard Shortcuts @source:user, Problems를 교차 확인합니다.
실패 신호 Guard 종료, All Running Tasks 선택, JSON 오류, User rule 또는 예제 label 잔존
keybindings.json을 복원합니다. tasks.json은 예제 객체만 제거합니다.4. 완료 확인하기
입력 화면과 독립된 Context Key, Troubleshooting 로그, Task 출력 수명주기로 교차 확인합니다.
- 선택 없음 —
taskRunning/terminalFocus/taskTerminalActive=true,terminalTextSelected=false, 종료 rule ON - 선택 있음 —
terminalTextSelected=true,!terminalTextSelected=false, 종료 rule OFF, 같은 RUN_ID의 HEARTBEAT 유지 - 복사 — Ctrl+C로 붙여넣은 문자열이 선택한 출력과 일치하고 Target이 계속 실행
- 선택 해제 — Esc 뒤
terminalTextSelected=false와 종료 rule ON으로 복귀 - 종료 — 2초 뒤 같은 RUN_ID 출력이 멈추고 Running Tasks에서 Target이 사라짐
- 원복 — User rule과 두 연습 Task가 제거되고 Problems의 JSON 오류가 없음
완료 기준 선택 없음 → ON, 텍스트 선택 → OFF, 복사 → 유지, 선택 해제 → ON 전환을 실제 Context Key와 출력으로 확인하고 Target 부재 fallback을 취소한 뒤 User 설정과 Workspace Task를 원복했습니다.
5. 문제가 생겼다면
텍스트를 선택했는데 terminalTextSelected가 false입니다
먼저 확인 활성 Terminal 본문에 실제 선택 영역이 있는지, Inspect Context Keys에서 Terminal 본문 요소를 검사했는지 확인합니다.
복구 선택을 유지한 채 Terminal 본문을 다시 검사합니다. 계속 재현되면 버전, 확장 목록, Context 객체를 보존하고 원인을 UNKNOWN으로 둡니다.
재합류 Step 6
선택 중에도 종료 rule이 match됩니다
먼저 확인 when에 && !terminalTextSelected가 정확히 있고 Troubleshooting 로그의 실제 매칭 rule과 source가 무엇인지 확인합니다.
복구 같은 chord의 중복 User rule을 제거하거나 미사용 chord로 바꾸고 백업과 비교합니다.
재합류 Step 4
Ctrl+C가 복사 대신 프로세스에 전달됩니다
먼저 확인 선택 영역이 남아 있고 terminalTextSelected=true인지 확인합니다.
복구 Command Palette의 Terminal 복사 명령으로 비교하고 선택 문자열, Context Key, 로그를 보존합니다. Evidence가 없으면 원인을 단정하지 않습니다.
재합류 Step 7
Target이 없는데 Quick Pick이 열립니다
먼저 확인 Target이 Running Tasks에 없고 Guard만 실행 중인지 확인합니다.
복구 이는 String args 불일치 시의 fallback일 수 있습니다. 아무 항목도 선택하지 않고 Esc로 닫습니다.
재합류 Step 8
6. 핵심 정리와 공식 자료
terminalTextSelected는 활성 Terminal의 텍스트 선택 유무를 나타냅니다.!terminalTextSelected를 추가하면 선택 중 종료 chord를 잠글 수 있습니다.- Windows Ctrl+C 복사와 Esc 선택 해제를 확인해 복사와 종료 흐름을 분리합니다.
- gate는 Target 전용이 아니므로 Target 부재 Quick Pick은 Esc로 취소합니다.
- 실습 후 User rule과 두 Task 객체를 제거해 원복합니다.
공식 자료
아래 자료는 2026-09-12 Asia/Seoul에 확인했습니다. 공식 Context Key 목록은 비완전 목록이며 일부 내부 Key는 향후 바뀔 수 있어 Stable commit 고정 소스로 정의와 기본값을 보완했습니다.
- VS Code Stable Update API · Microsoft
- Visual Studio Code 1.137 Release Notes · Microsoft
- Keyboard shortcuts for Visual Studio Code · Microsoft
- when clause contexts · Microsoft
- Terminal Basics · Microsoft
- Integrate with External Tools via Tasks · Microsoft
- Stable 1.137 terminalContextKey.ts · Microsoft
- Stable 1.137 terminalActions.ts · Microsoft
- Stable 1.137 abstractTaskService.ts · Microsoft
!terminalFindVisible 조건을 추가해 검색 입력과 종료 동작의 충돌을 줄입니다.'개발 > Visual Studio Code' 카테고리의 다른 글
| 커맨드 팔레트 46부: VS Code Task 종료 단축키의 매칭 로그로 충돌 진단하기 (0) | 2026.09.16 |
|---|---|
| 커맨드 팔레트 45부: VS Code Terminal Find가 열려 있을 때 Task 종료 단축키 잠그기 (0) | 2026.09.13 |
| 커맨드 팔레트 43부: VS Code Task Terminal에서만 종료 단축키 켜기 (0) | 2026.09.12 |
| 커맨드 팔레트 42부: VS Code Terminal 포커스일 때만 Task 종료 단축키 켜기 (0) | 2026.09.11 |
| 커맨드 팔레트 41부: VS Code Task 실행 중일 때만 종료 단축키 켜기추천 태그: (0) | 2026.09.10 |