개발/Visual Studio Code

커맨드 팔레트 42부: VS Code Terminal 포커스일 때만 Task 종료 단축키 켜기

반응형
VS CODE 초보자 시리즈 · 커맨드 팔레트 42부

Terminal에 포커스가 있을 때만 Task 종료 단축키 켜기

실행 중인 Task를 끝내는 단축키가 코드 편집 중에는 반응하지 않고, 통합 Terminal을 직접 선택했을 때만 동작하도록 범위를 좁힙니다.

User keybindings.json의 when을 taskRunning && terminalFocus로 바꾸고, Editor 포커스에서는 비활성·Terminal 포커스에서는 활성·종료 후에는 다시 비활성인 상태를 확인합니다.

taskRunning만 쓰면 Task가 실행 중인 동안 편집기에서도 단축키가 활성입니다. terminalFocus를 함께 쓰면 의도하지 않은 편집 중 종료를 줄일 수 있습니다.

1. 시작하기 전에

난이도는 초급입니다. 이전 편에서 만든 특정 Task 종료 단축키를 한 줄 수정하지만, User 단축키 전체에 영향을 주는 파일을 다루므로 백업과 충돌 확인을 먼저 합니다.

준비할 것

  • Windows 11의 VS Code Stable — Help > About에서 버전을 확인합니다. 2026-09-10 기준 최신 Windows x64 User Stable은 1.137.0이며, 이 원고의 로컬 자동 검증 환경은 1.136.2입니다.
  • PowerShell을 실행할 수 있는 신뢰 가능한 연습 폴더 — File > Open Folder로 열고 Restricted Mode가 아닌지 확인합니다.
  • User keybindings.json — Ctrl+Shift+P 후 Preferences: Open Keyboard Shortcuts (JSON)을 실행합니다.
  • 충돌하지 않는 예제 chord ctrl+k ctrl+alt+t — Keyboard Shortcuts에서 해당 키를 검색하고 Show Same Keybindings로 중복을 확인합니다.

적용 환경 한국어 초보자 · Windows 11 · VS Code Stable 1.137.0 기준 · PowerShell · User 범위 keybindings.json

안전하게 시작하기 이 실습은 실행 중인 프로세스 Task를 강제 종료할 수 있습니다. 저장·빌드·배포처럼 중요한 작업에는 적용하지 말고, 기존 keybindings.json을 별도 파일로 복사한 뒤 연습용 Task만 사용하세요. Human Gate: 종료 전 Terminal 출력의 RUN_ID를 확인합니다. 중단 조건: 같은 chord가 다른 명령과 충돌하거나, Target 이름이 실제 Task와 다르거나, 종료하면 안 되는 작업이 실행 중이면 키를 누르지 않습니다. 되돌리기: 추가한 객체 한 개를 제거하거나 백업을 복원합니다.

2. 알아둘 핵심 개념

when은 Boolean 활성 조건입니다

Keyboard rule의 when 값은 String이지만, 안의 식은 현재 Context Key 상태를 Boolean으로 평가합니다. 키를 눌렀을 때 같은 키의 rule을 아래에서 위로 검사하고, key와 when이 모두 맞는 첫 rule의 명령을 실행합니다.

taskRunning과 terminalFocus

taskRunning은 현재 Task 시스템에 실행 중 Task가 있는지를 나타냅니다. 특정 Target만의 상태가 아닙니다. terminalFocus는 통합 Terminal에 키보드 포커스가 있을 때 true입니다. Terminal이 열려 있기만 한 terminalIsOpen과는 다릅니다.

&&는 두 조건을 모두 요구합니다

taskRunning && terminalFocus는 “Task가 하나 이상 실행 중이고, 지금 통합 Terminal에 포커스가 있음”을 뜻합니다. Editor를 클릭하면 첫 조건은 true여도 두 번째가 false이므로 단축키가 비활성입니다.

포커스 조건과 Target 선택은 별개입니다

when은 명령 실행 가능 시점만 제한합니다. args의 String은 종료할 Task를 고릅니다. 다른 Task만 실행 중이면 두 Context Key는 true일 수 있지만 Target이 없으므로 선택 UI가 열릴 수 있습니다. “현재 Terminal이 바로 Target Task의 Terminal인지”까지 보장하려면 다음 편의 taskTerminalActive 같은 추가 조건이 필요합니다.

3. 순서대로 진행하기

각 단계의 정상 결과를 확인한 뒤 다음 단계로 이동합니다. 실제 User 설정을 바꾸는 Step 5와 종료 키를 누르는 Step 7에는 Human Gate가 있습니다.

1. User 단축키 파일을 백업하고 충돌을 확인하기

목적 기존 개인 단축키를 보호하고 예제 chord의 기존 동작을 파악합니다.

  1. Ctrl+K Ctrl+S로 Keyboard Shortcuts를 연 뒤 ctrl+k ctrl+alt+t를 검색하고, 같은 키 항목이 있으면 Show Same Keybindings를 실행합니다. 이어 Open Keyboard Shortcuts (JSON)을 열고 전체 내용을 keybindings.backup-20260910.json에 복사합니다.

입력 위치 Keyboard Shortcuts UI와 User keybindings.json; 백업은 사용자가 선택한 로컬 폴더

백업 파일 예: C:\Users\<사용자이름>\Documents\keybindings.backup-20260910.json
<사용자이름>은 Windows 계정 폴더명으로 바꿉니다.
정상 결과 같은 chord를 쓰는 rule과 적용 조건을 확인했고, 원본 JSON 전체가 백업 파일에 있습니다.

확인 백업 파일을 읽기 전용으로 다시 열어 첫 줄과 마지막 줄이 보이는지 확인합니다.

실패 신호 백업이 비어 있거나, 현재 chord가 중요 명령에 이미 연결되어 있습니다.

주의 충돌한 rule을 무작정 삭제하지 않습니다. 되돌리기: 아직 설정을 바꾸지 않았으므로 창을 닫고 다른 chord를 정하면 됩니다.

2. 종료해도 안전한 연습용 Task 만들기

목적 고유 RUN_ID와 heartbeat를 출력하는 독립 프로세스로 종료 여부를 관찰합니다.

  1. 연습 폴더의 .vscode/tasks.json에 아래 JSON을 저장합니다. 파일이 이미 있으면 tasks 배열 안에 객체 한 개만 병합합니다.

입력 위치 연습 Workspace의 .vscode/tasks.json

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "JCOS Focus Gate Target",
      "type": "process",
      "command": "powershell.exe",
      "args": [
        "-NoProfile",
        "-Command",
        "$id=[guid]::NewGuid().ToString('N').Substring(0,8); Write-Output ('FOCUS_GATE RUN_ID='+$id); for($i=0;$i -lt 30;$i++){ Write-Output ('FOCUS_GATE HEARTBEAT='+$i); Start-Sleep -Seconds 1 }"
      ],
      "problemMatcher": [],
      "presentation": { "reveal": "always", "panel": "dedicated", "clear": true }
    }
  ]
}
정상 결과 Problems에 JSON 오류가 없고 Tasks: Run Task 목록에 JCOS Focus Gate Target이 보입니다.

확인 파일의 tasks가 Array, args가 String Array, problemMatcher가 Array인지 확인합니다.

실패 신호 “Expected comma”, “End of file expected” 또는 Task가 목록에 없습니다.

주의 기존 tasks 배열을 덮어쓰지 않습니다. 되돌리기: 추가한 JCOS Focus Gate Target 객체만 제거하고 저장합니다.

3. Task를 실행하고 기준 상태 확인하기

목적 taskRunning=true가 될 연습 프로세스와 관찰 가능한 출력 기준을 만듭니다.

  1. Ctrl+Shift+P → Tasks: Run Task → JCOS Focus Gate Target을 선택합니다.

입력 위치 Command Palette와 자동으로 열린 전용 Terminal

FOCUS_GATE RUN_ID=<8자리 값>
FOCUS_GATE HEARTBEAT=0
FOCUS_GATE HEARTBEAT=1

<8자리 값>은 실행마다 달라지는 관찰용 식별자입니다.
정상 결과 전용 Terminal에 RUN_ID 한 줄과 증가하는 HEARTBEAT가 보이며 Task가 계속 실행 중입니다.

확인 RUN_ID를 메모하고 2초 뒤 HEARTBEAT 숫자가 증가했는지 봅니다.

실패 신호 Terminal이 즉시 닫히거나 PowerShell 실행 정책·경로 오류가 표시됩니다.

주의 오류 원문과 exit code를 보존합니다. 되돌리기: Tasks: Terminate Task에서 연습 Task만 선택하고 Step 2의 JSON을 재검사합니다.

4. Editor와 Terminal의 Context Key를 비교하기

목적 조건식을 바꾸기 전에 실제 포커스 상태가 어떻게 달라지는지 눈으로 확인합니다.

  1. Task가 실행 중인 상태에서 Editor를 클릭합니다. Command Palette의 Developer: Inspect Context Keys를 실행하고 Editor를 클릭해 taskRunning과 terminalFocus를 찾습니다. 다시 명령을 실행해 통합 Terminal 안을 클릭하고 같은 두 값을 찾습니다.

입력 위치 Command Palette, Editor, Integrated Terminal, Help > Toggle Developer Tools의 Console

Editor 포커스:   taskRunning=true, terminalFocus=false
Terminal 포커스: taskRunning=true, terminalFocus=true
정상 결과 Task 실행 상태는 유지되며, 클릭한 영역에 따라 terminalFocus만 false와 true로 바뀝니다.

확인 Developer Tools Console의 Context Key 객체에서 두 값을 각각 기록합니다.

실패 신호 Terminal을 열기만 했는데 true라고 단정하거나, 클릭 대상이 아닌 다른 UI 요소의 Context Key를 검사했습니다.

주의 Context Key 목록에는 확장 프로그램 값도 포함될 수 있고 내부 Key는 향후 바뀔 수 있습니다. 되돌리기: Developer Tools를 닫아도 Task와 설정에는 영향이 없습니다.

5. 종료 rule에 두 조건을 함께 넣기

목적 Target 종료 명령을 Task 실행 중이면서 Terminal 포커스일 때만 활성화합니다.

  1. Preferences: Open Keyboard Shortcuts (JSON)에서 아래 객체를 기존 배열 안에 추가합니다. 이전 편의 같은 객체가 있다면 when 값만 교체합니다.

입력 위치 User keybindings.json; User 범위이며 Workspace settings.json이 아닙니다.

[
  {
    "key": "ctrl+k ctrl+alt+t",
    "command": "workbench.action.tasks.terminate",
    "args": "JCOS Focus Gate Target",
    "when": "taskRunning && terminalFocus"
  }
]
정상 결과 JSON 오류가 없고 Keyboard Shortcuts 검색 결과에 명령, chord, When 조건이 한 rule로 표시됩니다.

확인 key·command·args·when이 모두 String인지, && 앞뒤에 공백이 있는지 확인합니다.

실패 신호 빨간 밑줄, 쉼표 오류, 같은 rule 중복 또는 terminalIsOpen을 잘못 사용했습니다.

주의 저장하는 즉시 User 단축키 규칙이 갱신됩니다. Human Gate: 백업이 열리는 것을 확인한 뒤 저장합니다. 되돌리기: 이 객체만 제거하거나 백업 전체를 복원합니다.

6. Editor 포커스에서 단축키가 막히는지 확인하기

목적 Task가 실행 중이어도 편집 중에는 종료 명령이 dispatch되지 않는지 검증합니다.

  1. Task Terminal이 계속 heartbeat를 출력하는 상태에서 코드 Editor를 클릭합니다. Developer: Toggle Keyboard Shortcuts Troubleshooting을 켜고 Ctrl+K Ctrl+Alt+T를 누릅니다.

입력 위치 Editor와 Keyboard Shortcuts Troubleshooting Output

기대 조건: taskRunning=true && terminalFocus=false
기대 판정: 종료 rule 불일치, Target heartbeat 계속 증가
정상 결과 종료 rule이 선택되지 않고, 메모한 RUN_ID는 그대로이며 HEARTBEAT가 계속 증가합니다.

확인 Output의 keybinding resolution 로그와 Task Terminal의 다음 HEARTBEAT를 함께 봅니다.

실패 신호 Task가 종료되거나 다른 명령이 실행됩니다.

주의 다른 명령이 실행되면 chord 충돌입니다. 되돌리기: 즉시 다른 chord로 바꾸거나 추가 rule을 제거하고 Step 1의 충돌 검색으로 돌아갑니다.

7. Terminal 포커스에서 Target만 종료하기

목적 두 조건이 모두 true일 때 지정한 Target 종료 명령이 실행되는지 확인합니다.

  1. 먼저 Task Terminal 안을 클릭하고 RUN_ID와 최신 HEARTBEAT를 확인합니다. 중요한 Task가 아님을 다시 확인한 뒤 같은 chord를 누릅니다.

입력 위치 JCOS Focus Gate Target의 Integrated Terminal

기대 조건: taskRunning=true && terminalFocus=true
기대 결과: 기존 RUN_ID의 HEARTBEAT가 멈추고 Task 종료 메시지 표시
정상 결과 종료 rule이 dispatch되고 해당 Task의 출력 증가가 멈춥니다. 자동 재시작이나 새로운 RUN_ID는 생기지 않습니다.

확인 2초 기다린 뒤 마지막 HEARTBEAT가 그대로인지, Tasks: Show Running Tasks에서 Target이 사라졌는지 확인합니다.

실패 신호 Quick Pick이 열리거나 다른 Task가 종료되거나 새 RUN_ID가 나타납니다.

주의 taskRunning은 특정 Target 조건이 아닙니다. Target이 없고 다른 Task만 실행 중이면 선택 UI가 열릴 수 있습니다. Human Gate: Terminal 제목과 RUN_ID를 확인한 뒤 키를 누릅니다. 되돌리기: 잘못 종료한 작업은 임의로 재실행하지 말고 원래 실행 절차와 저장 상태를 확인합니다.

8. 종료 후 비활성 상태와 Rollback 확인하기

목적 완료 조건을 독립 확인하고 User 설정과 연습 파일을 원상 복구합니다.

  1. Terminal에 포커스를 둔 채 Developer: Inspect Context Keys로 taskRunning=false를 확인합니다. 필요하면 같은 chord를 한 번 눌러 종료 rule이 활성화되지 않는지 봅니다. 검증이 끝나면 추가한 keybinding 객체와 연습 Task 객체를 제거합니다.

입력 위치 Context Key Console, User keybindings.json, Workspace .vscode/tasks.json

종료 뒤: taskRunning=false, terminalFocus=true
조건식: false && true = false
Rollback: 추가한 keybinding 객체와 JCOS Focus Gate Target 객체 제거
정상 결과 종료 뒤 rule은 다시 비활성이고, 백업 전과 동일한 User 단축키 상태로 돌아왔습니다.

확인 JSON 오류 0개, Keyboard Shortcuts에서 예제 rule 0개, Tasks: Run Task에서 연습 Task 0개인지 확인합니다.

실패 신호 제거 후 JSON 배열 구문이 깨지거나 예제 rule·Task가 중복으로 남아 있습니다.

주의 쉼표까지 포함해 객체 경계를 확인합니다. 되돌리기: 원인을 특정하지 못하면 UNKNOWN으로 기록하고 백업 전체를 복원한 뒤 완료 조건을 다시 확인합니다.

4. 완료 확인하기

설정을 입력한 화면과 독립된 Context Key·dispatch 로그·Task 출력을 함께 사용합니다.

  • Editor 포커스 — taskRunning=true, terminalFocus=false, 종료 rule 미선택, 같은 RUN_ID의 HEARTBEAT 증가
  • Terminal 포커스 — 두 Key가 모두 true, 종료 rule dispatch, 기존 RUN_ID 출력 정지
  • 종료 뒤 — taskRunning=false, 조건식 false, 실행 중 Target 없음
  • Rollback 뒤 — 예제 keybinding과 Task가 모두 제거되고 JSON 진단 0개
완료 기준 하나의 연습 Task가 실행되는 동안 Editor에서는 chord가 Target을 종료하지 않고 Terminal에서는 동일 chord가 Target을 종료하며, 종료 뒤 다시 비활성이고 원래 설정으로 복구되었습니다.

5. 문제가 생겼다면

Editor에서도 Task가 종료됩니다

먼저 확인 같은 chord의 다른 User rule, when 누락, taskRunning만 남은 중복 rule을 Keyboard Shortcuts의 Show Same Keybindings로 찾습니다.

복구 중복 예제 rule을 제거하고 when: "taskRunning && terminalFocus"인 한 객체만 남깁니다.

재합류 VSC-STEP-06

Terminal을 열었는데 단축키가 비활성입니다

먼저 확인 Terminal이 보이는 것과 포커스를 가진 것은 다릅니다. Terminal 입력 줄을 클릭하고 커서가 보이는지, terminalFocus=true인지 확인합니다.

복구 Terminal 입력 영역을 클릭한 뒤 Context Key를 다시 검사합니다. 접근성 버퍼나 검색 입력에 포커스가 있으면 Esc로 닫고 입력 줄로 돌아갑니다.

재합류 VSC-STEP-07

Quick Pick에 여러 Task가 표시됩니다

먼저 확인 args 문자열이 Task의 label과 대소문자·공백까지 같은지, Target이 실제로 실행 중인지 확인합니다.

복구 Target label을 정확히 맞추고 Tasks: Run Task로 Target을 실행합니다. 목록이 열린 상태에서 추측으로 다른 Task를 종료하지 말고 Esc로 취소합니다.

재합류 VSC-STEP-03

다른 단축키 명령이 실행됩니다

먼저 확인 Keyboard Shortcuts Troubleshooting 로그에서 실제 수신 키와 선택된 rule의 source·when을 확인합니다.

복구 같은 키 충돌 목록을 보고 사용하지 않는 chord로 변경합니다. 운영체제 또는 확장이 키를 가로채면 임의로 비활성화하지 말고 다른 chord를 고릅니다.

재합류 VSC-STEP-01

JSON 오류가 납니다

먼저 확인 쉼표, 배열 대괄호, 객체 중괄호, 큰따옴표와 Problems의 오류 원문·줄 번호를 보존합니다.

복구 백업을 복원하고 예제 객체 한 개만 다시 추가합니다. 원인이 확인되지 않으면 UNKNOWN으로 중단합니다.

재합류 VSC-STEP-05

핵심 판단 terminalFocus는 “현재 Terminal에 포커스가 있음”만 말합니다. 특정 Task Terminal까지 가리키는 조건으로 오해하지 않습니다. 원인을 확인하지 못하면 로그와 설정 백업을 보존하고 임의 변경 없이 중단합니다.

6. 핵심 정리와 공식 자료

  • taskRunning && terminalFocus는 실행 상태와 현재 포커스를 모두 요구합니다.
  • Editor에서는 false, Integrated Terminal에서는 true가 되는 전환을 Context Key로 확인합니다.
  • when은 실행 시점, args는 종료 Target을 담당하며 서로 대신할 수 없습니다.
  • 완료는 dispatch 로그, RUN_ID 출력 정지, 종료 뒤 false 상태와 Rollback으로 교차 확인합니다.

공식 자료

아래 자료는 2026-09-10 Asia/Seoul에 확인했습니다. Windows x64 User Stable API는 1.137.0을 반환했고 로컬 CLI는 1.136.2였습니다. 문서의 Context Key 목록은 비완전 목록이며 일부 내부 Key는 향후 변경될 수 있으므로 실제 UI 검사는 독자 환경 Human Gate입니다.

다음 편 예고 커맨드 팔레트 43부에서는 taskTerminalActive를 더해 일반 Terminal이 아니라 실제 Task Terminal이 선택된 경우에만 종료 단축키를 켜고, 일반 Terminal·Task Terminal 비교와 안전한 Rollback을 확인합니다.
반응형
이 글이 유용했다면 링크를 공유해 보세요.