mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-22 05:22:09 +00:00
fix(tui): right-click copies selection, only pastes when no selection
Sub-issue 5 of #22034. Right-click on the composer always pasted from the clipboard, even when the user had highlighted text — diverging from terminal-native behavior (xterm/iTerm/gnome-terminal) where right-click copies an active selection and only pastes when nothing is selected. Extract a small pure helper, decideRightClickAction(value, range), and route the existing onMouseDown right-click branch through it. Selection present and non-empty -> writeClipboardText(slice). Otherwise fall back to the existing emitPaste path.
This commit is contained in:
parent
59d3f24f10
commit
a2920b1762
2 changed files with 83 additions and 2 deletions
48
ui-tui/src/__tests__/textInputRightClick.test.ts
Normal file
48
ui-tui/src/__tests__/textInputRightClick.test.ts
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { decideRightClickAction } from '../components/textInput.js'
|
||||
|
||||
describe('decideRightClickAction', () => {
|
||||
it('returns paste when there is no selection', () => {
|
||||
expect(decideRightClickAction('hello world', null)).toEqual({ action: 'paste' })
|
||||
})
|
||||
|
||||
it('returns paste for a collapsed (empty) range', () => {
|
||||
expect(decideRightClickAction('hello world', { end: 5, start: 5 })).toEqual({
|
||||
action: 'paste'
|
||||
})
|
||||
})
|
||||
|
||||
it('copies the slice when range covers non-empty text', () => {
|
||||
expect(decideRightClickAction('hello world', { end: 5, start: 0 })).toEqual({
|
||||
action: 'copy',
|
||||
text: 'hello'
|
||||
})
|
||||
})
|
||||
|
||||
it('copies a middle slice', () => {
|
||||
expect(decideRightClickAction('hello world', { end: 11, start: 6 })).toEqual({
|
||||
action: 'copy',
|
||||
text: 'world'
|
||||
})
|
||||
})
|
||||
|
||||
it('falls back to paste when slice is empty (out-of-range indices)', () => {
|
||||
expect(decideRightClickAction('', { end: 5, start: 0 })).toEqual({ action: 'paste' })
|
||||
})
|
||||
|
||||
it('handles unicode (emoji, CJK) in the slice', () => {
|
||||
const value = 'hi 你好 🎉'
|
||||
expect(decideRightClickAction(value, { end: 5, start: 3 })).toEqual({
|
||||
action: 'copy',
|
||||
text: '你好'
|
||||
})
|
||||
})
|
||||
|
||||
it('preserves leading/trailing whitespace in the copied slice', () => {
|
||||
expect(decideRightClickAction(' spaced ', { end: 10, start: 0 })).toEqual({
|
||||
action: 'copy',
|
||||
text: ' spaced '
|
||||
})
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue