mirror of
https://github.com/zsh-users/zsh-autosuggestions.git
synced 2026-02-23 16:47:56 +01:00
fix(ai): prevent async suggestion duplication
- Add buffer validation to check suggestion starts with buffer - Discard stale suggestions that don't match current content Fixes text duplication bug when accepting async suggestions after buffer changes during suggestion fetch. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
8f1d53df7a
commit
55cd4ec23d
3 changed files with 85 additions and 1 deletions
52
.claude/git.local.md
Normal file
52
.claude/git.local.md
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
---
|
||||||
|
enabled: true
|
||||||
|
# Commit Message Conventions
|
||||||
|
scopes:
|
||||||
|
- ai
|
||||||
|
- widget
|
||||||
|
- strategy
|
||||||
|
- spec
|
||||||
|
- integration
|
||||||
|
- option
|
||||||
|
- docs
|
||||||
|
- ci
|
||||||
|
types:
|
||||||
|
- feat
|
||||||
|
- fix
|
||||||
|
- docs
|
||||||
|
- refactor
|
||||||
|
- test
|
||||||
|
- chore
|
||||||
|
- perf
|
||||||
|
- style
|
||||||
|
# Branch Naming Conventions
|
||||||
|
branch_prefixes:
|
||||||
|
feature: feature/*
|
||||||
|
fix: fix/*
|
||||||
|
hotfix: hotfix/*
|
||||||
|
refactor: refactor/*
|
||||||
|
docs: docs/*
|
||||||
|
# .gitignore Generation Defaults
|
||||||
|
gitignore:
|
||||||
|
os: [macos, linux, windows]
|
||||||
|
languages: [ruby, shell]
|
||||||
|
frameworks: []
|
||||||
|
tools: [rspec, github-actions]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Project-Specific Git Settings
|
||||||
|
|
||||||
|
This file configures the `@git/` plugin for this project. The settings above in the YAML frontmatter define valid scopes, types, and branch naming conventions that the plugin will enforce.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
- **Scopes**: When creating a commit with `/commit`, choose from the defined `scopes`.
|
||||||
|
- **Branching**: When creating a new branch via the `git` skill, use the defined `branch_prefixes`.
|
||||||
|
- **Gitignore**: When running `/gitignore` without arguments, the technologies listed above will be used as defaults.
|
||||||
|
|
||||||
|
## Additional Guidelines
|
||||||
|
|
||||||
|
- Always run tests before committing.
|
||||||
|
- Ensure linting passes before pushing.
|
||||||
|
- Reference issue numbers in commit footers (e.g., `Closes #123`).
|
||||||
|
- Use `BREAKING CHANGE:` prefix in the body for breaking changes.
|
||||||
|
|
@ -405,3 +405,29 @@ EOFCURL
|
||||||
wait_for { session.content }.to eq('temp 0.3')
|
wait_for { session.content }.to eq('temp 0.3')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'suggestion buffer validation' do
|
||||||
|
let(:options) { ["ZSH_AUTOSUGGEST_AI_API_KEY=test-key", "ZSH_AUTOSUGGEST_STRATEGY=(ai)"] }
|
||||||
|
|
||||||
|
context 'when suggestion does not match current buffer' do
|
||||||
|
let(:before_sourcing) do
|
||||||
|
-> {
|
||||||
|
session.run_command('curl() {
|
||||||
|
if [[ "$*" == *"max-time"* ]]; then
|
||||||
|
cat <<EOFCURL
|
||||||
|
{"choices":[{"message":{"content":"git status --long"}}]}
|
||||||
|
200
|
||||||
|
EOFCURL
|
||||||
|
fi
|
||||||
|
}')
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'discards suggestion that does not match buffer' do
|
||||||
|
# Suggestion is "git status --long" but buffer is unrelated
|
||||||
|
session.send_string('ls')
|
||||||
|
wait_for { session.content }.to_not match(/git status/)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,13 @@ _zsh_autosuggest_suggest() {
|
||||||
local min_input="${ZSH_AUTOSUGGEST_AI_MIN_INPUT:-1}"
|
local min_input="${ZSH_AUTOSUGGEST_AI_MIN_INPUT:-1}"
|
||||||
|
|
||||||
if [[ -n "$suggestion" ]] && { (( $#BUFFER )) || (( min_input == 0 )); }; then
|
if [[ -n "$suggestion" ]] && { (( $#BUFFER )) || (( min_input == 0 )); }; then
|
||||||
POSTDISPLAY="${suggestion#$BUFFER}"
|
# Only extract suffix if suggestion starts with buffer
|
||||||
|
if [[ "$suggestion" == "$BUFFER"* ]]; then
|
||||||
|
POSTDISPLAY="${suggestion#$BUFFER}"
|
||||||
|
else
|
||||||
|
# Suggestion doesn't match current buffer, discard it
|
||||||
|
POSTDISPLAY=
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
POSTDISPLAY=
|
POSTDISPLAY=
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue