My Zig Configuration for VS Code

Michael Lynch

VS Code용 나의 Zig 설정

마침내 VS Code가 Zig와 일관되게 동작하는 해결책을 찾았습니다. 다른 분들의 고생을 조금이라도 덜어드리고자 제 설정을 공유합니다.

VS Code용 Zig 확장이 정상적으로 동작하는 모습

제대로 동작하는 방법을 찾기 전까지는 Zig 버전 불일치 문제에 계속 부딪혔고, VS Code가 Zig 문법을 전혀 인식하지 못하고 단순 자동 완성으로 넘어가 버리는 경우도 많았습니다.

프로젝트마다 다른 Zig 버전 관리하기

Zig는 아직 안정적인 1.0 버전을 출시하지 않았습니다. Zig로 작성된 소프트웨어를 작업한다면 해당 프로젝트에 맞는 Zig 컴파일러 버전을 사용해야 합니다.

여러 프로젝트를 동시에 작업한다면 같은 시스템에서 서로 다른 Zig 버전을 유연하게 전환할 방법이 필요합니다.

Zig 버전을 관리하는 가장 인기 있는 방법은 Zig Version Manager인 것 같습니다. 저는 직접 써보지 않아서 VS Code와 어떻게 연동되는지는 잘 모르겠습니다.

저는 개인적으로 Nix 개발 셸을 이용해 프로젝트별로 Zig 버전을 관리하고 있으며, 아래에서는 그 방법을 공유하겠습니다.

문제: VS Code가 ZLS를 찾지 못합니다

Zig 프로젝트를 열면 VS Code가 친절하게도 Zig Language Server를 활성화할지 물어봅니다. 하지만 ‘예’를 선택하면 다음과 같은 오류 메시지가 나타납니다.

ZLS 설치 실패

문제는 제가 Nix 개발 환경을 실행하기 전에 VS Code를 먼저 시작한다는 점입니다. 그래서 Zig VS Code 플러그인이 로컬 Zig 컴파일러나 Zig Language Server 바이너리인 zls의 위치를 알지 못합니다.

해결책: direnv VS Code 확장 사용하기

업데이트 (2025-02-14): Nix에 의존하지 않는 더 간단한 해결책이 있습니다.

처음에는 Nix flake가 개발 셸에 진입할 때마다 VS Code 설정을 자동으로 다시 작성하는 다소 기발한 방법을 생각해 냈습니다. 이렇게 하면 VS Code가 항상 Zig와 ZLS 바이너리의 최신 경로를 유지할 수 있었습니다.

그러다 fasterthanlime의 글을 읽고 훨씬 간단한 해결책이 있다는 것을 알게 되었습니다.

direnv VS Code 확장이 있어 Zig 경로를 VS Code와 손쉽게 동기화할 수 있습니다. 덕분에 이 방법은 Remote SSH를 이용한 VS Code 개발 환경에서도 동작합니다.

완성된 전체 해결책

아래에 제 해결책을 설명해 두었지만, 긴 설명 없이 바로 사용하고 싶으시다면 아래에 쉽게 복사할 수 있는 템플릿을 만들어 두었습니다.

flake.nix

여기서 핵심 역할을 하는 것은 Nix flake입니다.

{
  description = "Zig development environment";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
    flake-utils.url = "github:numtide/flake-utils";
    zig-overlay.url = "github:mitchellh/zig-overlay";
    # Keep in sync with zigVersion below.
    zls-overlay.url = "github:zigtools/zls/0.13.0";
  };

  outputs = {
    self,
    nixpkgs,
    flake-utils,
    ...
  } @ inputs:
    flake-utils.lib.eachSystem (builtins.attrNames inputs.zig-overlay.packages) (system: let
      pkgs = import nixpkgs {
        inherit system;
        overlays = [
          (final: prev: {
            zigpkgs = inputs.zig-overlay.packages.${prev.system};
          })
        ];
      };
      zigVersion = "0.13.0";
      zig = pkgs.zigpkgs.${zigVersion};
      zls = inputs.zls-overlay.packages.${system}.zls.overrideAttrs (old: {
        nativeBuildInputs = [zig];
      });
    in {
      devShells.default = pkgs.mkShell {
        packages = with pkgs; [
          zig
          zls
        ];

        shellHook = ''
          echo 'zls' "$(zls --version)"
          echo 'zig' "$(zig version)"
        '';
      };
    });
}

flake.nix 다운로드

이 Nix flake는 Zig 컴파일러와 Zig Language Server(ZLS)를 포함하는 개발 셸을 생성합니다.

Zig 0.13.0으로 설정해 두었지만, 원하는 태그된 릴리스로 변경할 수 있습니다. Zig의 프리릴리스 개발 버전을 사용하려면 두 곳에 있는 0.13.0을 모두 master로 바꾸면 됩니다.

0.13.0의 반복을 없애고 한 곳에서만 정의할 수 있는 방법을 여러 가지로 시도해 봤지만, Nix 언어 실력이 부족해서 방법을 찾지 못했습니다. 혹시 해결책을 아시는 분이 계시면 알려주시기 바랍니다.

.envrc

제 해결책은 프로젝트 디렉터리에 있을 때마다 Nix 개발 셸을 시작하기 위해 direnv에 의존합니다. 설정은 아주 간단합니다.

use_flake

.vscode/extensions.json

VS Code를 Zig와 연동하려면 두 개의 VS Code 확장이 필요합니다.

{
  "recommendations": ["mkhl.direnv", "ziglang.vscode-zig"]
}

extensions.json 다운로드

첫 번째는 공식 Zig VS Code 확장입니다.

두 번째는 다소 생소할 수 있는 direnv VS Code 확장으로, VS Code가 Nix 개발 셸 내부의 경로를 인식할 수 있게 해줍니다.

.vscode/settings.json

마지막으로, VS Code가 Zig Language Server를 사용하도록 알려주는 설정 하나만 추가하면 됩니다.

{
  "zig.zls.enabled": "on"
}

settings.json 다운로드

템플릿 복사하기

제 설정을 쉽게 재현할 수 있도록 Nix flake 템플릿을 만들었습니다.

요구 사항

  • Nix (저는 2.24.12 버전을 사용 중입니다)
    • flakes 활성화
  • direnv (저는 2.35.0 버전을 사용 중입니다)
  • VS Code (저는 1.96.4 버전을 사용 중입니다)

Zig VS Code Nix flake 템플릿

Nix flake 템플릿에 저의 Zig + VS Code 해결책을 담아 두었습니다. 다음 명령어를 실행하면 사용할 수 있습니다.

nix flake init \
  --template git+https://codeberg.org/mtlynch/zig-vscode-flake.git

nix flake init을 실행한 뒤 direnv allow를 실행하면 zig와 zls를 사용할 수 있습니다.

$ direnv allow
...
direnv: nix-direnv: Renewed cache
Alejandra 3.0.0
zls 0.13.0
zig 0.13.0

마지막으로 VS Code에서 “Extensions: Show Recommended Extensions”로 이동해 권장 확장을 설치하세요.

이제 zig init을 실행해 새 프로젝트를 생성하면 Zig VS Code 확장이 Zig와 정상적으로 동작하는 것을 확인할 수 있습니다.

모든 것이 정상이라면 src/main.zig에서 언어 오버레이가 표시되고, Zig 라이브러리 정의로 이동할 수 있습니다.

Zig 버전 변경하기

제 flake는 작성 시점 기준 최신 릴리스인 Zig 0.13.0으로 설정되어 있습니다.

다른 태그된 릴리스를 사용하고 싶다면 0.13.0을 다른 버전으로 바꾸면 됩니다.

EXISTING_ZIG_VERSION='0.13.0' # Set to whatever the version in the flake.nix is.
NEW_ZIG_VERSION='0.12.0'      # Set to your desired Zig version.

최신 프리릴리스 버전의 Zig를 사용하려면 버전을 master로 설정하세요.

NEW_ZIG_VERSION='master'      # Set if you want bleeding edge Zig.

flake.nix 파일에서 Zig 버전을 업데이트한 뒤, 다음 명령어를 실행해 변경 사항을 적용하세요.

sed \
  --in-place \
  "s/${EXISTING_ZIG_VERSION}/${NEW_ZIG_VERSION}/g" \
  flake.nix && \
  nix flake update zig zls-overlay && \
  nix develop

변경 사항을 적용하려면 VS Code를 다시 로드하는 것만으로는 부족하고 완전히 재시작해야 할 수도 있습니다.

업데이트: Nix 없이 더 간단하게 해결하기

Zig VS Code 확장 개발자 중 한 분이 이 글에 댓글을 남겨 확장 자체만으로도 Zig 버전을 관리할 수 있어야 한다고 알려주셨습니다.

Zig VS Code 확장이 Zig 설치를 관리할 수 있다는 것을 몰랐기에 직접 시도해 보았습니다. VS Code 확장을 통해 Zig를 설치하려면 VS Code 명령 팔레트를 열고 다음을 선택하세요.

  • Zig Setup: Install Zig

그런 다음 원하는 Zig 버전을 선택하면 정상적으로 동작합니다. 저는 settings.json을 수동으로 설정하고 VS Code를 다시 로드해야 적용되었습니다.

저는 Nix 개발 셸이 마음에 들어 계속 사용할 예정이지만, 간단한 설정을 원하신다면 Zig VS Code 확장이 Zig 설치를 관리하도록 하는 편이 더 좋을 것입니다.

원문은 Michael Lynch님이 에 게재했습니다.

이 글은 muse-spark-1.2-contributor 모델을 사용해 번역했습니다.