updating files

This commit is contained in:
2026-01-11 17:38:25 -05:00
parent d75196b4f9
commit 86504eec55
13 changed files with 764 additions and 224 deletions

95
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,95 @@
name: 🐛 Bug Report
description: Create a bug report to help us improve Avante
title: 'bug: '
labels: ['bug']
body:
- type: markdown
id: issue-already-exists
attributes:
value: |
Please search to see if an issue already exists for the bug you encountered.
See [Searching Issues and Pull Requests](https://docs.github.com/en/search-github/searching-on-github/searching-issues-and-pull-requests) for how to use the GitHub search bar and filters.
- type: textarea
id: describe-the-bug
validations:
required: true
attributes:
label: Describe the bug
description: Please provide a clear and concise description about the problem you ran into.
placeholder: This happened when I ...
- type: textarea
id: to-reproduce
validations:
required: false
attributes:
label: To reproduce
description: |
Please provide a code sample or a code snippet to reproduce said problem. If you have code snippets, error messages, or a stack trace please also provide them here.
**IMPORTANT**: make sure to use [code tags](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks#syntax-highlighting) to correctly format your code. Screenshots are helpful but don't use them for code snippets as they don't allow others to copy-and-paste your code.
placeholder: |
Give a minimal config to reproduce the issue.
- type: textarea
id: expected-behavior
validations:
required: false
attributes:
label: Expected behavior
description: 'A clear and concise description of what you would expect to happen.'
- type: textarea
id: how-to-install
validations:
required: true
attributes:
label: Installation method
description: |
Please share your installation method with us.
value: |
Use lazy.nvim:
```lua
{
"yetone/avante.nvim",
event = "VeryLazy",
lazy = false,
version = false, -- set this if you want to always pull the latest change
opts = {
-- add any opts here
},
-- if you want to build from source then do `make BUILD_FROM_SOURCE=true`
build = "make",
-- build = "powershell -ExecutionPolicy Bypass -File Build.ps1 -BuildFromSource false" -- for windows
dependencies = {
"nvim-lua/plenary.nvim",
"MunifTanjim/nui.nvim",
},
}
```
- type: textarea
id: environment-info
attributes:
label: Environment
description: |
Please share your environment with us, including your neovim version using `nvim -v` and `uname -a`.
placeholder: |
neovim version: ...
distribution (if any): ...
platform: ...
validations:
required: true
- type: textarea
attributes:
label: Repro
description: Minimal `init.lua` to reproduce this issue. Save as `repro.lua` and run with `nvim -u repro.lua`
value: |
vim.env.LAZY_STDPATH = ".repro"
load(vim.fn.system("curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua"))()
require("lazy.minit").repro({
spec = {
-- add any other plugins here
},
})
render: lua
validations:
required: false

2
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,2 @@
blank_issues_enabled: true
version: 2.1

View File

@@ -0,0 +1,35 @@
name: 🚀 Feature Request
description: Submit a proposal/request for new Avante feature.
title: 'feature: '
labels: ['new-feature', 'enhancement']
body:
- type: textarea
id: feature-request
validations:
required: true
attributes:
label: Feature request
description: |
A clear and concise description of the feature request.
placeholder: |
I would like it if...
- type: textarea
id: motivation
validations:
required: false
attributes:
label: Motivation
description: |
Please outline the motivation for this feature request. Is your feature request related to a problem? e.g., I'm always frustrated when [...].
If this is related to another issue, please link here too.
If you have a current workaround, please also provide it here.
placeholder: |
This feature would solve ...
- type: textarea
id: other
attributes:
label: Other
description: |
Is there any way that you could help, e.g. by submitting a PR?
placeholder: |
I would love to contribute ...

View File

@@ -0,0 +1,24 @@
name: 'Close stale issues and PRs'
on:
schedule:
- cron: '30 1 * * *'
permissions:
contents: write # only for delete-branch option
issues: write
pull-requests: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.'
stale-pr-message: 'This PR is stale because it has been open 14 days with no activity. Remove stale label or comment or this will be closed in 10 days.'
close-issue-message: 'This issue was closed because it has been stalled for 5 days with no activity.'
close-pr-message: 'This PR was closed because it has been stalled for 10 days with no activity.'
days-before-issue-stale: 30
days-before-pr-stale: 14
days-before-issue-close: 5
days-before-pr-close: 10

86
.github/workflows/lua.yaml vendored Normal file
View File

@@ -0,0 +1,86 @@
name: Lua CI
on:
push:
branches:
- main
paths:
- "**/*.lua"
- .github/workflows/lua.yaml
pull_request:
branches:
- main
paths:
- "**/*.lua"
- .github/workflows/lua.yaml
jobs:
# reference from: https://github.com/nvim-lua/plenary.nvim/blob/2d9b06177a975543726ce5c73fca176cedbffe9d/.github/workflows/default.yml#L6C3-L43C20
run_tests:
name: unit tests
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
rev: v0.10.0
steps:
- uses: actions/checkout@v6
- id: todays-date
run: echo "date=$(date +%F)" >> "$GITHUB_OUTPUT"
- name: Restore cache for today's nightly.
id: cache-neovim
uses: actions/cache@v4
with:
path: _neovim
key: ${{ runner.os }}-${{ matrix.rev }}-${{ steps.todays-date.outputs.date }}
- name: Download neovim ${{ matrix.rev }}
env:
GH_TOKEN: ${{ github.token }}
NEOVIM_VERSION: ${{ matrix.rev }}
if: steps.cache-neovim.outputs.cache-hit != 'true'
run: |
mkdir -p _neovim
gh release download \
--output - \
--pattern nvim-linux64.tar.gz \
--repo neovim/neovim \
"$NEOVIM_VERSION" | tar xvz --strip-components 1 --directory _neovim
- name: Prepare
run: |
sudo apt-get update
sudo apt-get install -y ripgrep
sudo apt-get install -y silversearcher-ag
echo "${PWD}/_neovim/bin" >> "$GITHUB_PATH"
echo VIM="${PWD}/_neovim/share/nvim/runtime" >> "$GITHUB_ENV"
- name: Run tests
run: |
nvim --version
make luatest
typecheck:
name: Typecheck
runs-on: ubuntu-latest
strategy:
matrix:
nvim_version: [ stable ]
luals_version: [ 3.13.6 ]
steps:
- uses: actions/checkout@v6
- uses: rhysd/action-setup-vim@v1
with:
neovim: true
version: ${{ matrix.nvim_version }}
- name: Typecheck
env:
VIMRUNTIME: /home/runner/nvim-${{ matrix.nvim_version }}/share/nvim/runtime
run: |
make lua-typecheck

38
.github/workflows/pre-commit.yaml vendored Normal file
View File

@@ -0,0 +1,38 @@
name: pre-commit
on:
pull_request:
types: [labeled, opened, reopened, synchronize]
push:
branches: [main, test-me-*]
jobs:
pre-commit:
if: "github.event.action != 'labeled' || github.event.label.name == 'pre-commit ci run'"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: gh pr edit ${{ github.event.number }} --remove-label 'pre-commit ci run'
if: github.event.action == 'labeled' && github.event.label.name == 'pre-commit ci run'
env:
GH_TOKEN: ${{ github.token }}
- uses: actions/setup-python@v3
with:
python-version: '3.11'
- name: Install uv
uses: astral-sh/setup-uv@v5
- run: |
uv venv
source .venv/bin/activate
uv pip install -r py/rag-service/requirements.txt
- uses: leafo/gh-actions-lua@v11
- uses: leafo/gh-actions-luarocks@v5
- run: luarocks install luacheck
- name: Install stylua from crates.io
uses: baptiste0928/cargo-install@v3
with:
crate: stylua
args: --features lua54
- uses: pre-commit/action@v3.0.1
- uses: pre-commit-ci/lite-action@v1.1.0
if: always()

185
.github/workflows/release.yaml vendored Normal file
View File

@@ -0,0 +1,185 @@
name: Release
on:
push:
tags: [v\d+\.\d+\.\d+]
permissions:
contents: write
packages: write
env:
CARGO_TERM_COLOR: always
jobs:
create-release:
permissions:
contents: write
runs-on: ubuntu-24.04
outputs:
release_id: ${{ steps.create-release.outputs.id }}
release_upload_url: ${{ steps.create-release.outputs.upload_url }}
release_body: "${{ steps.tag.outputs.message }}"
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/checkout@v4
- name: Get version
id: get_version
uses: battila7/get-version-action@d97fbc34ceb64d1f5d95f4dfd6dce33521ccccf5 # ratchet:battila7/get-version-action@v2
- name: Get tag message
id: tag
run: |
git fetch --depth=1 origin +refs/tags/*:refs/tags/*
echo "message<<EOF" >> $GITHUB_OUTPUT
echo "$(git tag -l --format='%(contents)' ${{ steps.get_version.outputs.version }})" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
- name: Create Release
id: create-release
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # ratchet:ncipollo/release-action@v1
with:
draft: true
name: "avante-libs ${{ steps.get_version.outputs.version }}"
tag: ${{ steps.get_version.outputs.version }}
body: "${{ steps.tag.outputs.message }}"
releases-matrix:
needs: [create-release]
strategy:
fail-fast: false
matrix:
feature: [lua51, luajit]
config:
- os: ubuntu-24.04-arm
os_name: linux
arch: aarch64
rust_target: aarch64-unknown-linux-gnu
docker_platform: linux/aarch64
container: quay.io/pypa/manylinux2014_aarch64
- os: ubuntu-latest
os_name: linux
arch: x86_64
rust_target: x86_64-unknown-linux-gnu
docker_platform: linux/amd64
container: quay.io/pypa/manylinux2014_x86_64 # for glibc 2.17
- os: macos-13
os_name: darwin
arch: x86_64
rust_target: x86_64-apple-darwin
- os: macos-latest
os_name: darwin
arch: aarch64
rust_target: aarch64-apple-darwin
- os: windows-latest
os_name: windows
arch: x86_64
rust_target: x86_64-pc-windows-msvc
- os: windows-latest
os_name: windows
arch: aarch64
rust_target: aarch64-pc-windows-msvc
runs-on: ${{ matrix.config.os }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/checkout@v4
- uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # ratchet:Swatinem/rust-cache@v2
if: ${{ matrix.config.container == null }}
- uses: dtolnay/rust-toolchain@7b1c307e0dcbda6122208f10795a713336a9b35a # ratchet:dtolnay/rust-toolchain@master
if: ${{ matrix.config.container == null }}
with:
targets: ${{ matrix.config.rust_target }}
toolchain: "1.85.0"
- name: Build all crates
if: ${{ matrix.config.container == null }}
run: |
cargo build --release --features ${{ matrix.feature }}
- name: Build all crates with glibc 2.17 # for glibc 2.17
if: ${{ matrix.config.container != null }}
run: |
# sudo apt-get install -y qemu qemu-user-static
docker run \
--rm \
-v $(pwd):/workspace \
-w /workspace \
--platform ${{ matrix.config.docker_platform }} \
${{ matrix.config.container }} \
bash -c "yum install -y perl-IPC-Cmd openssl-devel && curl --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal && . /root/.cargo/env && cargo build --release --features ${{ matrix.feature }}"
- name: Handle binaries
if: ${{ matrix.config.os_name != 'windows' }}
shell: bash
run: |
mkdir -p results
if [ "${{ matrix.config.os_name }}" == "linux" ]; then
EXT="so"
else
EXT="dylib"
fi
cp target/release/libavante_templates.$EXT results/avante_templates.$EXT
cp target/release/libavante_tokenizers.$EXT results/avante_tokenizers.$EXT
cp target/release/libavante_repo_map.$EXT results/avante_repo_map.$EXT
cp target/release/libavante_html2md.$EXT results/avante_html2md.$EXT
cd results
tar zcvf avante_lib-${{ matrix.config.os_name }}-${{ matrix.config.arch }}-${{ matrix.feature }}.tar.gz *.${EXT}
- name: Handle binaries (Windows)
if: ${{ matrix.config.os_name == 'windows' }}
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path results
Copy-Item -Path "target\release\avante_templates.dll" -Destination "results\avante_templates.dll"
Copy-Item -Path "target\release\avante_tokenizers.dll" -Destination "results\avante_tokenizers.dll"
Copy-Item -Path "target\release\avante_repo_map.dll" -Destination "results\avante_repo_map.dll"
Copy-Item -Path "target\release\avante_html2md.dll" -Destination "results\avante_html2md.dll"
Set-Location -Path results
$dllFiles = Get-ChildItem -Filter "*.dll" | Select-Object -ExpandProperty Name
Compress-Archive -Path $dllFiles -DestinationPath "avante_lib-${{ matrix.config.os_name }}-${{ matrix.config.arch }}-${{ matrix.feature }}.zip"
- name: Upload Release Asset
uses: shogo82148/actions-upload-release-asset@8482bd769644976d847e96fb4b9354228885e7b4 # ratchet:shogo82148/actions-upload-release-asset@v1
if: ${{ matrix.config.os_name != 'windows' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ASSET_NAME: avante_lib-${{ matrix.config.os_name }}-${{ matrix.config.arch }}-${{ matrix.feature }}.tar.gz
with:
upload_url: ${{ needs.create-release.outputs.release_upload_url }}
asset_path: ./results/avante_lib-${{ matrix.config.os_name }}-${{ matrix.config.arch }}-${{ matrix.feature }}.tar.gz
- name: Upload Release Asset (Windows)
uses: shogo82148/actions-upload-release-asset@8482bd769644976d847e96fb4b9354228885e7b4 # ratchet:shogo82148/actions-upload-release-asset@v1
if: ${{ matrix.config.os_name == 'windows' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ASSET_NAME: avante_lib-${{ matrix.config.os_name }}-${{ matrix.config.arch }}-${{ matrix.feature }}.zip
with:
upload_url: ${{ needs.create-release.outputs.release_upload_url }}
asset_path: ./results/avante_lib-${{ matrix.config.os_name }}-${{ matrix.config.arch }}-${{ matrix.feature }}.zip
publish-release:
permissions:
contents: write
runs-on: ubuntu-24.04
needs: [create-release, releases-matrix]
steps:
- name: publish release
id: publish-release
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # ratchet:actions/github-script@v6
env:
release_id: ${{ needs.create-release.outputs.release_id }}
with:
script: |
github.rest.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: process.env.release_id,
draft: false,
prerelease: false
})

31
.github/workflows/rust.yaml vendored Normal file
View File

@@ -0,0 +1,31 @@
name: Rust CI
on:
push:
branches:
- main
paths:
- "crates/**/*"
- "Cargo.lock"
- "Cargo.toml"
pull_request:
branches:
- main
paths:
- "crates/**/*"
- "Cargo.lock"
- "Cargo.toml"
jobs:
tests:
name: Run Rust tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/checkout@v4
- uses: Swatinem/rust-cache@82a92a6e8fbeee089604da2575dc567ae9ddeaab # ratchet:Swatinem/rust-cache@v2
- uses: dtolnay/rust-toolchain@7b1c307e0dcbda6122208f10795a713336a9b35a # ratchet:dtolnay/rust-toolchain@master
with:
toolchain: stable
components: clippy, rustfmt
- name: Run rust tests
run: cargo test --features luajit

View File

@@ -39,7 +39,7 @@ This project and everyone participating in it is governed by our commitment to c
1. Clone the repository:
```bash
git clone https://github.com/YOUR_USERNAME/codetyper.nvim.git
git clone https://github.com/CarGDev/codetyper.nvim.git
cd codetyper.nvim
```

View File

@@ -1,22 +1,22 @@
---@mod codetyper.llm LLM interface for Codetyper.nvim
local M = {}
local lang_map = require("codetyper.utils.langmap")
local utils = require("codetyper.utils")
--- Get the appropriate LLM client based on configuration
---@return table LLM client module
function M.get_client()
local codetyper = require("codetyper")
local config = codetyper.get_config()
local codetyper = require("codetyper")
local config = codetyper.get_config()
if config.llm.provider == "claude" then
return require("codetyper.llm.claude")
elseif config.llm.provider == "ollama" then
return require("codetyper.llm.ollama")
else
error("Unknown LLM provider: " .. config.llm.provider)
end
if config.llm.provider == "claude" then
return require("codetyper.llm.claude")
elseif config.llm.provider == "ollama" then
return require("codetyper.llm.ollama")
else
error("Unknown LLM provider: " .. config.llm.provider)
end
end
--- Generate code from a prompt
@@ -24,37 +24,40 @@ end
---@param context table Context information (file content, language, etc.)
---@param callback fun(response: string|nil, error: string|nil) Callback function
function M.generate(prompt, context, callback)
local client = M.get_client()
client.generate(prompt, context, callback)
local client = M.get_client()
client.generate(prompt, context, callback)
end
--- Build the system prompt for code generation
---@param context table Context information
---@return string System prompt
function M.build_system_prompt(context)
local prompts = require("codetyper.prompts")
-- Select appropriate system prompt based on context
local prompt_type = context.prompt_type or "code_generation"
local system_prompts = prompts.system
local system = system_prompts[prompt_type] or system_prompts.code_generation
-- Substitute variables
system = system:gsub("{{language}}", context.language or "unknown")
system = system:gsub("{{filepath}}", context.file_path or "unknown")
local prompts = require("codetyper.prompts")
-- Add file content with analysis hints
if context.file_content and context.file_content ~= "" then
system = system .. "\n\n===== EXISTING FILE CONTENT (analyze and match this style) =====\n"
system = system .. context.file_content
system = system .. "\n===== END OF EXISTING FILE =====\n"
system = system .. "\nYour generated code MUST follow the exact patterns shown above."
else
system = system .. "\n\nThis is a new/empty file. Generate clean, idiomatic " .. (context.language or "code") .. " following best practices."
end
-- Select appropriate system prompt based on context
local prompt_type = context.prompt_type or "code_generation"
local system_prompts = prompts.system
return system
local system = system_prompts[prompt_type] or system_prompts.code_generation
-- Substitute variables
system = system:gsub("{{language}}", context.language or "unknown")
system = system:gsub("{{filepath}}", context.file_path or "unknown")
-- Add file content with analysis hints
if context.file_content and context.file_content ~= "" then
system = system .. "\n\n===== EXISTING FILE CONTENT (analyze and match this style) =====\n"
system = system .. context.file_content
system = system .. "\n===== END OF EXISTING FILE =====\n"
system = system .. "\nYour generated code MUST follow the exact patterns shown above."
else
system = system
.. "\n\nThis is a new/empty file. Generate clean, idiomatic "
.. (context.language or "code")
.. " following best practices."
end
return system
end
--- Build context for LLM request
@@ -62,124 +65,49 @@ end
---@param prompt_type string Type of prompt
---@return table Context object
function M.build_context(target_path, prompt_type)
local content = utils.read_file(target_path)
local ext = vim.fn.fnamemodify(target_path, ":e")
local content = utils.read_file(target_path)
local ext = vim.fn.fnamemodify(target_path, ":e")
-- Map extension to language
local lang_map = {
-- JavaScript/TypeScript
ts = "TypeScript",
tsx = "TypeScript React (TSX)",
js = "JavaScript",
jsx = "JavaScript React (JSX)",
mjs = "JavaScript (ESM)",
cjs = "JavaScript (CommonJS)",
-- Python
py = "Python",
pyw = "Python",
pyx = "Cython",
-- Systems languages
c = "C",
h = "C Header",
cpp = "C++",
hpp = "C++ Header",
cc = "C++",
cxx = "C++",
rs = "Rust",
go = "Go",
-- JVM languages
java = "Java",
kt = "Kotlin",
kts = "Kotlin Script",
scala = "Scala",
clj = "Clojure",
-- Web
html = "HTML",
css = "CSS",
scss = "SCSS",
sass = "Sass",
less = "Less",
vue = "Vue",
svelte = "Svelte",
-- Scripting
lua = "Lua",
rb = "Ruby",
php = "PHP",
pl = "Perl",
sh = "Shell (Bash)",
bash = "Bash",
zsh = "Zsh",
fish = "Fish",
ps1 = "PowerShell",
-- .NET
cs = "C#",
fs = "F#",
vb = "Visual Basic",
-- Data/Config
json = "JSON",
yaml = "YAML",
yml = "YAML",
toml = "TOML",
xml = "XML",
sql = "SQL",
graphql = "GraphQL",
-- Other
swift = "Swift",
dart = "Dart",
ex = "Elixir",
exs = "Elixir Script",
erl = "Erlang",
hs = "Haskell",
ml = "OCaml",
r = "R",
jl = "Julia",
nim = "Nim",
zig = "Zig",
v = "V",
md = "Markdown",
mdx = "MDX",
}
return {
file_content = content,
language = lang_map[ext] or ext,
extension = ext,
prompt_type = prompt_type,
file_path = target_path,
}
return {
file_content = content,
language = lang_map[ext] or ext,
extension = ext,
prompt_type = prompt_type,
file_path = target_path,
}
end
--- Parse LLM response and extract code
---@param response string Raw LLM response
---@return string Extracted code
function M.extract_code(response)
local code = response
-- Remove markdown code blocks with language tags (```typescript, ```javascript, etc.)
code = code:gsub("```%w+%s*\n", "")
code = code:gsub("```%w+%s*$", "")
code = code:gsub("^```%w*\n?", "")
code = code:gsub("\n?```%s*$", "")
code = code:gsub("\n```\n", "\n")
code = code:gsub("```", "")
-- Remove common explanation prefixes that LLMs sometimes add
code = code:gsub("^Here.-:\n", "")
code = code:gsub("^Here's.-:\n", "")
code = code:gsub("^This.-:\n", "")
code = code:gsub("^The following.-:\n", "")
code = code:gsub("^Below.-:\n", "")
-- Remove common explanation suffixes
code = code:gsub("\n\nThis code.-$", "")
code = code:gsub("\n\nThe above.-$", "")
code = code:gsub("\n\nNote:.-$", "")
code = code:gsub("\n\nExplanation:.-$", "")
-- Trim leading/trailing whitespace but preserve internal formatting
code = code:match("^%s*(.-)%s*$") or code
local code = response
return code
-- Remove markdown code blocks with language tags (```typescript, ```javascript, etc.)
code = code:gsub("```%w+%s*\n", "")
code = code:gsub("```%w+%s*$", "")
code = code:gsub("^```%w*\n?", "")
code = code:gsub("\n?```%s*$", "")
code = code:gsub("\n```\n", "\n")
code = code:gsub("```", "")
-- Remove common explanation prefixes that LLMs sometimes add
code = code:gsub("^Here.-:\n", "")
code = code:gsub("^Here's.-:\n", "")
code = code:gsub("^This.-:\n", "")
code = code:gsub("^The following.-:\n", "")
code = code:gsub("^Below.-:\n", "")
-- Remove common explanation suffixes
code = code:gsub("\n\nThis code.-$", "")
code = code:gsub("\n\nThe above.-$", "")
code = code:gsub("\n\nNote:.-$", "")
code = code:gsub("\n\nExplanation:.-$", "")
-- Trim leading/trailing whitespace but preserve internal formatting
code = code:match("^%s*(.-)%s*$") or code
return code
end
return M

View File

@@ -0,0 +1,75 @@
local lang_map = {
-- JavaScript/TypeScript
ts = "TypeScript",
tsx = "TypeScript React (TSX)",
js = "JavaScript",
jsx = "JavaScript React (JSX)",
mjs = "JavaScript (ESM)",
cjs = "JavaScript (CommonJS)",
-- Python
py = "Python",
pyw = "Python",
pyx = "Cython",
-- Systems languages
c = "C",
h = "C Header",
cpp = "C++",
hpp = "C++ Header",
cc = "C++",
cxx = "C++",
rs = "Rust",
go = "Go",
-- JVM languages
java = "Java",
kt = "Kotlin",
kts = "Kotlin Script",
scala = "Scala",
clj = "Clojure",
-- Web
html = "HTML",
css = "CSS",
scss = "SCSS",
sass = "Sass",
less = "Less",
vue = "Vue",
svelte = "Svelte",
-- Scripting
lua = "Lua",
rb = "Ruby",
php = "PHP",
pl = "Perl",
sh = "Shell (Bash)",
bash = "Bash",
zsh = "Zsh",
fish = "Fish",
ps1 = "PowerShell",
-- .NET
cs = "C#",
fs = "F#",
vb = "Visual Basic",
-- Data/Config
json = "JSON",
yaml = "YAML",
yml = "YAML",
toml = "TOML",
xml = "XML",
sql = "SQL",
graphql = "GraphQL",
-- Other
swift = "Swift",
dart = "Dart",
ex = "Elixir",
exs = "Elixir Script",
erl = "Erlang",
hs = "Haskell",
ml = "OCaml",
r = "R",
jl = "Julia",
nim = "Nim",
zig = "Zig",
v = "V",
md = "Markdown",
mdx = "MDX",
}
return lang_map

View File

@@ -1,121 +1,137 @@
-- Codetyper.nvim - AI-powered coding partner for Neovim
-- Plugin loader
local g = vim.g
local fn = vim.fn
local api = vim.api
local cmd = vim.cmd
-- Prevent loading twice
if vim.g.loaded_codetyper then
return
if g.loaded_codetyper then
return
end
vim.g.loaded_codetyper = true
g.loaded_codetyper = true
-- Minimum Neovim version check
if vim.fn.has("nvim-0.8.0") == 0 then
vim.api.nvim_err_writeln("Codetyper.nvim requires Neovim 0.8.0 or higher")
return
if fn.has("nvim-0.8.0") == 0 then
api.nvim_err_writeln("Codetyper.nvim requires Neovim 0.8.0 or higher")
return
end
-- Initialize .coder folder and tree.log on project open
vim.api.nvim_create_autocmd("VimEnter", {
callback = function()
-- Delay slightly to ensure cwd is set
vim.defer_fn(function()
local tree = require("codetyper.tree")
tree.setup()
-- Also ensure gitignore is updated
local gitignore = require("codetyper.gitignore")
gitignore.ensure_ignored()
end, 100)
end,
desc = "Initialize Codetyper .coder folder on startup",
api.nvim_create_autocmd("VimEnter", {
callback = function()
-- Delay slightly to ensure cwd is set
vim.defer_fn(function()
local tree = require("codetyper.tree")
tree.setup()
-- Also ensure gitignore is updated
local gitignore = require("codetyper.gitignore")
gitignore.ensure_ignored()
end, 100)
end,
desc = "Initialize Codetyper .coder folder on startup",
})
-- Also initialize on directory change
vim.api.nvim_create_autocmd("DirChanged", {
callback = function()
vim.defer_fn(function()
local tree = require("codetyper.tree")
tree.setup()
local gitignore = require("codetyper.gitignore")
gitignore.ensure_ignored()
end, 100)
end,
desc = "Initialize Codetyper .coder folder on directory change",
api.nvim_create_autocmd("DirChanged", {
callback = function()
vim.defer_fn(function()
local tree = require("codetyper.tree")
tree.setup()
local gitignore = require("codetyper.gitignore")
gitignore.ensure_ignored()
end, 100)
end,
desc = "Initialize Codetyper .coder folder on directory change",
})
-- Auto-initialize when opening a coder file (for nvim-tree, telescope, etc.)
vim.api.nvim_create_autocmd({ "BufRead", "BufNewFile", "BufEnter" }, {
pattern = "*.coder.*",
callback = function()
-- Initialize plugin if not already done
local codetyper = require("codetyper")
if not codetyper.is_initialized() then
codetyper.setup()
end
end,
desc = "Auto-initialize Codetyper when opening coder files",
api.nvim_create_autocmd({ "BufRead", "BufNewFile", "BufEnter" }, {
pattern = "*.coder.*",
callback = function()
-- Initialize plugin if not already done
local codetyper = require("codetyper")
if not codetyper.is_initialized() then
codetyper.setup()
end
end,
desc = "Auto-initialize Codetyper when opening coder files",
})
-- Lazy-load the plugin on first command usage
vim.api.nvim_create_user_command("Coder", function(opts)
require("codetyper").setup()
-- Re-execute the command now that plugin is loaded
vim.cmd("Coder " .. (opts.args or ""))
api.nvim_create_user_command("Coder", function(opts)
require("codetyper").setup()
-- Re-execute the command now that plugin is loaded
cmd("Coder " .. (opts.args or ""))
end, {
nargs = "?",
complete = function()
return {
"open", "close", "toggle", "process", "status", "focus",
"tree", "tree-view", "reset", "gitignore",
"ask", "ask-close", "ask-toggle", "ask-clear",
}
end,
desc = "Codetyper.nvim commands",
nargs = "?",
complete = function()
return {
"open",
"close",
"toggle",
"process",
"status",
"focus",
"tree",
"tree-view",
"reset",
"gitignore",
"ask",
"ask-close",
"ask-toggle",
"ask-clear",
}
end,
desc = "Codetyper.nvim commands",
})
-- Lazy-load aliases
vim.api.nvim_create_user_command("CoderOpen", function()
require("codetyper").setup()
vim.cmd("CoderOpen")
api.nvim_create_user_command("CoderOpen", function()
require("codetyper").setup()
cmd("CoderOpen")
end, { desc = "Open Coder view" })
vim.api.nvim_create_user_command("CoderClose", function()
require("codetyper").setup()
vim.cmd("CoderClose")
api.nvim_create_user_command("CoderClose", function()
require("codetyper").setup()
cmd("CoderClose")
end, { desc = "Close Coder view" })
vim.api.nvim_create_user_command("CoderToggle", function()
require("codetyper").setup()
vim.cmd("CoderToggle")
api.nvim_create_user_command("CoderToggle", function()
require("codetyper").setup()
cmd("CoderToggle")
end, { desc = "Toggle Coder view" })
vim.api.nvim_create_user_command("CoderProcess", function()
require("codetyper").setup()
vim.cmd("CoderProcess")
api.nvim_create_user_command("CoderProcess", function()
require("codetyper").setup()
cmd("CoderProcess")
end, { desc = "Process prompt and generate code" })
vim.api.nvim_create_user_command("CoderTree", function()
require("codetyper").setup()
vim.cmd("CoderTree")
api.nvim_create_user_command("CoderTree", function()
require("codetyper").setup()
cmd("CoderTree")
end, { desc = "Refresh tree.log" })
vim.api.nvim_create_user_command("CoderTreeView", function()
require("codetyper").setup()
vim.cmd("CoderTreeView")
api.nvim_create_user_command("CoderTreeView", function()
require("codetyper").setup()
cmd("CoderTreeView")
end, { desc = "View tree.log" })
-- Ask panel commands
vim.api.nvim_create_user_command("CoderAsk", function()
require("codetyper").setup()
vim.cmd("CoderAsk")
api.nvim_create_user_command("CoderAsk", function()
require("codetyper").setup()
cmd("CoderAsk")
end, { desc = "Open Ask panel" })
vim.api.nvim_create_user_command("CoderAskToggle", function()
require("codetyper").setup()
vim.cmd("CoderAskToggle")
api.nvim_create_user_command("CoderAskToggle", function()
require("codetyper").setup()
cmd("CoderAskToggle")
end, { desc = "Toggle Ask panel" })
vim.api.nvim_create_user_command("CoderAskClear", function()
require("codetyper").setup()
vim.cmd("CoderAskClear")
api.nvim_create_user_command("CoderAskClear", function()
require("codetyper").setup()
cmd("CoderAskClear")
end, { desc = "Clear Ask history" })

View File

@@ -0,0 +1,25 @@
# Create .coder/ folder if does not exist
mkdir -p .coder
# Create .coder/settings.json with default settings if it does not exist
if [ ! -f .coder/settings.json ]; then
cat <<EOL > .coder/settings.json
{
"editor.fontSize": 14,
"editor.tabSize": 2,
"files.autoSave": "afterDelay",
"files.autoSaveDelay": 1000,
"terminal.integrated.fontSize": 14,
"workbench.colorTheme": "Default Dark+"
}
EOL
fi
# Add the .coder/ folder to .gitignore if not already present
if ! grep -q "^.coder/$" .gitignore; then
echo ".coder/" >> .gitignore
fi
# Add the ./**/*.coder.* files to .gitignore if not already present
if ! grep -q "^.*/\.coder/.*$" .gitignore; then
echo ".*/.coder/.*" >> .gitignore
fi