kartikvashistha/zed-ansible

Ansible Extension for the Zed editor

Tree-sitter Query

59

45 commits

updated May 4, 2026

See the code

README

zed-ansible

Community maintained Ansible extension for the Zed editor.

Pre-requisites

Ensure python3, ansible and ansible-lint are installed via your system's package manager:

# For macos, when using the homebrew package manager
brew install ansible ansible-lint

# For Fedora based systems
sudo dnf install ansible python3-ansible-lint

# For Ubuntu based systems
sudo apt install ansible ansible-lint python3

For the best experience, add the following configuration(s) as needed under Zed's global settings:

Filetype detection

By default, the Ansible LSP attaches to all files ending with .ansible due to this.

Currently, it is not possible to use glob patterns within this extension's code to detect Ansible files under common directory patterns - as such, for the time being, it is recommended to configure the file detection under file_types under Zed's settings:

...
"file_types": {
    "Ansible": [
      "**.ansible.yml",
      "**.ansible.yaml",
      "**/defaults/*.yml",
      "**/defaults/*.yaml",
      "**/meta/*.yml",
      "**/meta/*.yaml",
      "**/tasks/*.yml",
      "**/tasks/*.yaml",
      "**/handlers/*.yml",
      "**/handlers/*.yaml",
      "**/group_vars/*.yml",
      "**/group_vars/*.yaml",
      "**/playbooks/*.yaml",
      "**/playbooks/*.yml",
      "**playbook*.yaml",
      "**playbook*.yml"
    ]
  }

Feel free to modify this list as per your needs.

If your inventory file is in the YAML format, you can either:

  • Append the ansible-lint inventory json schema to it via the following comment at the top of the file (example):
# yaml-language-server: $schema=https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/inventory.json
  • Or configure setting this schema under lsp.yaml-language-server under Zed's settings for your inventory pattern (ref):
"lsp": {
    "yaml-language-server": {
      "settings": {
        "yaml": {
          "schemas": {
            "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/inventory.json": [
              "./inventory/*.yaml",
              "hosts.yml",
            ]
          }
        }
      }
    }
},

LSP Configuration

By default, the following config is passed to the Ansible language server:

{
  "ansible": {
    "ansible": {
      "path": "ansible"
    },
    "executionEnvironment": {
      "enabled": false
    },
    "python": {
      "interpreterPath": "python3"
    },
    "validation": {
      "enabled": true,
      "lint": {
        "enabled": true,
        "path": "ansible-lint"
      }
    }
  }
}

When desired, the above default settings can be overridden via Zed's settings.json configuration file under the lsp key:

...
"lsp": {
  "ansible": {
    "settings": {
      // Note: the Zed Ansible extension prefixes all settings with the `ansible` key to provide for a cleaner config under here.
      // So instead of using `ansible.ansible.path` use `ansible.path`and so on.
      "ansible": {
        "path": "ansible"
      },
      "executionEnvironment": {
        "enabled": false
      },
      "python": {
        "interpreterPath": "python3"
      },
      "validation": {
        "enabled": false, //disable validation
        "lint": {
          "enabled": false, //disable ansible-lint
          "path": "ansible-lint"
        }
      }
    }
  }
}

This config conveniently mirrors nvim-lspconfig's defaults for Ansible language server. A full list of options/settings, that can be passed to the server, can be found here.

Using with uv-managed virtual environments

If you use uv to manage your project's virtual environment, point the language server to the .venv Python interpreter and ansible-lint:

"lsp": {
  "ansible": {
    "settings": {
      "python": {
        "interpreterPath": ".venv/bin/python"
      },
      "validation": {
        "lint": {
          "path": ".venv/bin/ansible-lint"
        }
      }
    }
  }
}

Highlighting

This extension uses YAML for base syntax highlighting. For enhanced highlighting of Ansible keywords, module names, and parameters, enable semantic tokens in your Zed settings:

"languages": {
  "Ansible": {
    "semantic_tokens": "combined"
  }
}

This leverages the Ansible language server to distinguish:

  • Module names (e.g., ansible.builtin.copy)
  • Module parameters (e.g., src, dest)
  • Ansible keywords (when, become, register, tasks, etc.)

Jinja2 Highlighting

Jinja2 expressions are highlighted within Ansible YAML files via Tree-sitter injection:

  • {{ variable }} — variable expressions in YAML values
  • {% for %}, {% if %}, {% block %} — control flow tags
  • {# comment #} — Jinja2 comments
  • when: expression — bare Jinja2 in conditional fields (when, changed_when, failed_when, check_mode)

For standalone .j2 template files, install the Jinja2 Template Support extension.

Notes

In it's current state, the language server gets started and performs decently well. Sometimes, the language server may crash either when the completion list returned from the LSP is quite large or when switching between multiple Ansible files. For the time being, I'm unable to determine how this can be fixed permanently.

To restart the language server, open the Command Palette and execute editor: Restart Language Server.

If completions from the community or any other collection dont appear, create an ansible.cfg file in your project and add the path of your collection in there.

ansible
zed-editor
zed-extension

kartikvashistha/zed-ansible

Ansible Extension for the Zed editor

Tree-sitter Query

59

45 commits

updated May 4, 2026

See the code

README

zed-ansible

Community maintained Ansible extension for the Zed editor.

Pre-requisites

Ensure python3, ansible and ansible-lint are installed via your system's package manager:

# For macos, when using the homebrew package manager
brew install ansible ansible-lint

# For Fedora based systems
sudo dnf install ansible python3-ansible-lint

# For Ubuntu based systems
sudo apt install ansible ansible-lint python3

For the best experience, add the following configuration(s) as needed under Zed's global settings:

Filetype detection

By default, the Ansible LSP attaches to all files ending with .ansible due to this.

Currently, it is not possible to use glob patterns within this extension's code to detect Ansible files under common directory patterns - as such, for the time being, it is recommended to configure the file detection under file_types under Zed's settings:

...
"file_types": {
    "Ansible": [
      "**.ansible.yml",
      "**.ansible.yaml",
      "**/defaults/*.yml",
      "**/defaults/*.yaml",
      "**/meta/*.yml",
      "**/meta/*.yaml",
      "**/tasks/*.yml",
      "**/tasks/*.yaml",
      "**/handlers/*.yml",
      "**/handlers/*.yaml",
      "**/group_vars/*.yml",
      "**/group_vars/*.yaml",
      "**/playbooks/*.yaml",
      "**/playbooks/*.yml",
      "**playbook*.yaml",
      "**playbook*.yml"
    ]
  }

Feel free to modify this list as per your needs.

If your inventory file is in the YAML format, you can either:

  • Append the ansible-lint inventory json schema to it via the following comment at the top of the file (example):
# yaml-language-server: $schema=https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/inventory.json
  • Or configure setting this schema under lsp.yaml-language-server under Zed's settings for your inventory pattern (ref):
"lsp": {
    "yaml-language-server": {
      "settings": {
        "yaml": {
          "schemas": {
            "https://raw.githubusercontent.com/ansible/ansible-lint/main/src/ansiblelint/schemas/inventory.json": [
              "./inventory/*.yaml",
              "hosts.yml",
            ]
          }
        }
      }
    }
},

LSP Configuration

By default, the following config is passed to the Ansible language server:

{
  "ansible": {
    "ansible": {
      "path": "ansible"
    },
    "executionEnvironment": {
      "enabled": false
    },
    "python": {
      "interpreterPath": "python3"
    },
    "validation": {
      "enabled": true,
      "lint": {
        "enabled": true,
        "path": "ansible-lint"
      }
    }
  }
}

When desired, the above default settings can be overridden via Zed's settings.json configuration file under the lsp key:

...
"lsp": {
  "ansible": {
    "settings": {
      // Note: the Zed Ansible extension prefixes all settings with the `ansible` key to provide for a cleaner config under here.
      // So instead of using `ansible.ansible.path` use `ansible.path`and so on.
      "ansible": {
        "path": "ansible"
      },
      "executionEnvironment": {
        "enabled": false
      },
      "python": {
        "interpreterPath": "python3"
      },
      "validation": {
        "enabled": false, //disable validation
        "lint": {
          "enabled": false, //disable ansible-lint
          "path": "ansible-lint"
        }
      }
    }
  }
}

This config conveniently mirrors nvim-lspconfig's defaults for Ansible language server. A full list of options/settings, that can be passed to the server, can be found here.

Using with uv-managed virtual environments

If you use uv to manage your project's virtual environment, point the language server to the .venv Python interpreter and ansible-lint:

"lsp": {
  "ansible": {
    "settings": {
      "python": {
        "interpreterPath": ".venv/bin/python"
      },
      "validation": {
        "lint": {
          "path": ".venv/bin/ansible-lint"
        }
      }
    }
  }
}

Highlighting

This extension uses YAML for base syntax highlighting. For enhanced highlighting of Ansible keywords, module names, and parameters, enable semantic tokens in your Zed settings:

"languages": {
  "Ansible": {
    "semantic_tokens": "combined"
  }
}

This leverages the Ansible language server to distinguish:

  • Module names (e.g., ansible.builtin.copy)
  • Module parameters (e.g., src, dest)
  • Ansible keywords (when, become, register, tasks, etc.)

Jinja2 Highlighting

Jinja2 expressions are highlighted within Ansible YAML files via Tree-sitter injection:

  • {{ variable }} — variable expressions in YAML values
  • {% for %}, {% if %}, {% block %} — control flow tags
  • {# comment #} — Jinja2 comments
  • when: expression — bare Jinja2 in conditional fields (when, changed_when, failed_when, check_mode)

For standalone .j2 template files, install the Jinja2 Template Support extension.

Notes

In it's current state, the language server gets started and performs decently well. Sometimes, the language server may crash either when the completion list returned from the LSP is quite large or when switching between multiple Ansible files. For the time being, I'm unable to determine how this can be fixed permanently.

To restart the language server, open the Command Palette and execute editor: Restart Language Server.

If completions from the community or any other collection dont appear, create an ansible.cfg file in your project and add the path of your collection in there.

ansible
zed-editor
zed-extension

Languages

Tree-sitter Query

60.2%

Rust

38.9%