mirror of
https://github.com/EthanMarti/infio-copilot.git
synced 2026-01-16 16:31:56 +00:00
update vector search result.
This commit is contained in:
parent
34d0f1f70c
commit
7416ddffaa
@ -70,10 +70,55 @@ const SearchView = () => {
|
|||||||
}, [getRAGEngine])
|
}, [getRAGEngine])
|
||||||
|
|
||||||
const handleResultClick = (result: Omit<SelectVector, 'embedding'> & { similarity: number }) => {
|
const handleResultClick = (result: Omit<SelectVector, 'embedding'> & { similarity: number }) => {
|
||||||
openMarkdownFile(app, result.path, result.metadata.startLine)
|
// 如果用户正在选择文本,不触发点击事件
|
||||||
|
const selection = window.getSelection()
|
||||||
|
if (selection && selection.toString().length > 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
console.debug('🔍 [SearchView] 点击搜索结果:', {
|
||||||
|
id: result.id,
|
||||||
|
path: result.path,
|
||||||
|
startLine: result.metadata?.startLine,
|
||||||
|
endLine: result.metadata?.endLine,
|
||||||
|
content: result.content?.substring(0, 100) + '...',
|
||||||
|
similarity: result.similarity
|
||||||
|
})
|
||||||
|
|
||||||
|
// 检查路径是否存在
|
||||||
|
if (!result.path) {
|
||||||
|
console.error('❌ [SearchView] 文件路径为空')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查文件是否存在于vault中
|
||||||
|
const file = app.vault.getFileByPath(result.path)
|
||||||
|
if (!file) {
|
||||||
|
console.error('❌ [SearchView] 在vault中找不到文件:', result.path)
|
||||||
|
().map(f => f.path))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
console.debug('✅ [SearchView] 文件存在,准备打开:', {
|
||||||
|
file: file.path,
|
||||||
|
startLine: result.metadata?.startLine
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
openMarkdownFile(app, result.path, result.metadata.startLine)
|
||||||
|
console.debug('✅ [SearchView] 成功调用openMarkdownFile')
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ [SearchView] 调用openMarkdownFile失败:', error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const toggleFileExpansion = (filePath: string) => {
|
const toggleFileExpansion = (filePath: string) => {
|
||||||
|
// 如果用户正在选择文本,不触发点击事件
|
||||||
|
const selection = window.getSelection()
|
||||||
|
if (selection && selection.toString().length > 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const newExpandedFiles = new Set(expandedFiles)
|
const newExpandedFiles = new Set(expandedFiles)
|
||||||
if (newExpandedFiles.has(filePath)) {
|
if (newExpandedFiles.has(filePath)) {
|
||||||
newExpandedFiles.delete(filePath)
|
newExpandedFiles.delete(filePath)
|
||||||
@ -109,7 +154,7 @@ const SearchView = () => {
|
|||||||
// 移除图片显示,避免布局问题
|
// 移除图片显示,避免布局问题
|
||||||
img: () => <span className="obsidian-image-placeholder">[图片]</span>,
|
img: () => <span className="obsidian-image-placeholder">[图片]</span>,
|
||||||
// 代码块样式
|
// 代码块样式
|
||||||
code: ({ children, inline, ...props }: { children: React.ReactNode; inline?: boolean; [key: string]: unknown }) => {
|
code: ({ children, inline }: { children: React.ReactNode; inline?: boolean; [key: string]: unknown }) => {
|
||||||
if (inline) {
|
if (inline) {
|
||||||
return <code className="obsidian-inline-code">{children}</code>
|
return <code className="obsidian-inline-code">{children}</code>
|
||||||
}
|
}
|
||||||
@ -203,28 +248,34 @@ const SearchView = () => {
|
|||||||
<div className="obsidian-search-results">
|
<div className="obsidian-search-results">
|
||||||
{!isSearching && groupedResults.length > 0 && (
|
{!isSearching && groupedResults.length > 0 && (
|
||||||
<div className="obsidian-results-list">
|
<div className="obsidian-results-list">
|
||||||
{groupedResults.map((fileGroup, fileIndex) => (
|
{groupedResults.map((fileGroup) => (
|
||||||
<div key={fileGroup.path} className="obsidian-file-group">
|
<div key={fileGroup.path} className="obsidian-file-group">
|
||||||
{/* 文件头部 */}
|
{/* 文件头部 */}
|
||||||
<div
|
<div
|
||||||
className="obsidian-file-header"
|
className="obsidian-file-header"
|
||||||
onClick={() => toggleFileExpansion(fileGroup.path)}
|
onClick={() => toggleFileExpansion(fileGroup.path)}
|
||||||
>
|
>
|
||||||
<div className="obsidian-file-header-left">
|
<div className="obsidian-file-header-content">
|
||||||
{expandedFiles.has(fileGroup.path) ? (
|
<div className="obsidian-file-header-top">
|
||||||
<ChevronDown size={16} className="obsidian-expand-icon" />
|
<div className="obsidian-file-header-left">
|
||||||
) : (
|
{expandedFiles.has(fileGroup.path) ? (
|
||||||
<ChevronRight size={16} className="obsidian-expand-icon" />
|
<ChevronDown size={16} className="obsidian-expand-icon" />
|
||||||
)}
|
) : (
|
||||||
{/* <span className="obsidian-file-index">{fileIndex + 1}</span> */}
|
<ChevronRight size={16} className="obsidian-expand-icon" />
|
||||||
<span className="obsidian-file-name">{fileGroup.fileName}</span>
|
)}
|
||||||
{/* <span className="obsidian-file-path">({fileGroup.path})</span> */}
|
{/* <span className="obsidian-file-index">{fileIndex + 1}</span> */}
|
||||||
</div>
|
<span className="obsidian-file-name">{fileGroup.fileName}</span>
|
||||||
<div className="obsidian-file-header-right">
|
</div>
|
||||||
{/* <span className="obsidian-file-blocks">{fileGroup.blocks.length} 块</span> */}
|
<div className="obsidian-file-header-right">
|
||||||
{/* <span className="obsidian-file-similarity">
|
{/* <span className="obsidian-file-blocks">{fileGroup.blocks.length} 块</span> */}
|
||||||
{fileGroup.maxSimilarity.toFixed(3)}
|
{/* <span className="obsidian-file-similarity">
|
||||||
</span> */}
|
{fileGroup.maxSimilarity.toFixed(3)}
|
||||||
|
</span> */}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="obsidian-file-path-row">
|
||||||
|
<span className="obsidian-file-path">{fileGroup.path}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -310,9 +361,6 @@ const SearchView = () => {
|
|||||||
padding: 12px;
|
padding: 12px;
|
||||||
background-color: var(--background-secondary);
|
background-color: var(--background-secondary);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
transition: background-color 0.1s ease;
|
transition: background-color 0.1s ease;
|
||||||
border-bottom: 1px solid var(--background-modifier-border);
|
border-bottom: 1px solid var(--background-modifier-border);
|
||||||
}
|
}
|
||||||
@ -321,6 +369,18 @@ const SearchView = () => {
|
|||||||
background-color: var(--background-modifier-hover);
|
background-color: var(--background-modifier-hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.obsidian-file-header-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.obsidian-file-header-top {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
.obsidian-file-header-left {
|
.obsidian-file-header-left {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -336,6 +396,10 @@ const SearchView = () => {
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.obsidian-file-path-row {
|
||||||
|
margin-left: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
.obsidian-expand-icon {
|
.obsidian-expand-icon {
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
@ -354,6 +418,8 @@ const SearchView = () => {
|
|||||||
font-size: var(--font-ui-medium);
|
font-size: var(--font-ui-medium);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
user-select: text;
|
||||||
|
cursor: text;
|
||||||
}
|
}
|
||||||
|
|
||||||
.obsidian-file-path {
|
.obsidian-file-path {
|
||||||
@ -363,7 +429,6 @@ const SearchView = () => {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
margin-left: 4px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.obsidian-file-blocks {
|
.obsidian-file-blocks {
|
||||||
@ -430,6 +495,8 @@ const SearchView = () => {
|
|||||||
font-size: var(--font-ui-medium);
|
font-size: var(--font-ui-medium);
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
|
user-select: text;
|
||||||
|
cursor: text;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Markdown 渲染样式 */
|
/* Markdown 渲染样式 */
|
||||||
@ -437,6 +504,8 @@ const SearchView = () => {
|
|||||||
color: var(--text-normal);
|
color: var(--text-normal);
|
||||||
font-size: var(--font-ui-medium);
|
font-size: var(--font-ui-medium);
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
|
user-select: text;
|
||||||
|
cursor: text;
|
||||||
}
|
}
|
||||||
|
|
||||||
.obsidian-markdown-content h4,
|
.obsidian-markdown-content h4,
|
||||||
|
|||||||
@ -161,8 +161,22 @@ export function openMarkdownFile(
|
|||||||
filePath: string,
|
filePath: string,
|
||||||
startLine?: number,
|
startLine?: number,
|
||||||
) {
|
) {
|
||||||
|
console.debug('🔄 [openMarkdownFile] 开始打开文件:', {
|
||||||
|
filePath,
|
||||||
|
startLine
|
||||||
|
})
|
||||||
|
|
||||||
const file = app.vault.getFileByPath(filePath)
|
const file = app.vault.getFileByPath(filePath)
|
||||||
if (!file) return
|
if (!file) {
|
||||||
|
console.error('❌ [openMarkdownFile] 文件不存在:', filePath)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
console.debug('✅ [openMarkdownFile] 找到文件:', {
|
||||||
|
path: file.path,
|
||||||
|
name: file.name,
|
||||||
|
extension: file.extension
|
||||||
|
})
|
||||||
|
|
||||||
const existingLeaf = app.workspace
|
const existingLeaf = app.workspace
|
||||||
.getLeavesOfType('markdown')
|
.getLeavesOfType('markdown')
|
||||||
@ -172,16 +186,29 @@ export function openMarkdownFile(
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (existingLeaf) {
|
if (existingLeaf) {
|
||||||
|
console.debug('🔄 [openMarkdownFile] 找到已存在的标签,切换到该标签')
|
||||||
app.workspace.setActiveLeaf(existingLeaf, { focus: true })
|
app.workspace.setActiveLeaf(existingLeaf, { focus: true })
|
||||||
|
|
||||||
if (startLine && existingLeaf.view instanceof MarkdownView) {
|
if (startLine && existingLeaf.view instanceof MarkdownView) {
|
||||||
existingLeaf.view.setEphemeralState({ line: startLine - 1 }) // -1 because line is 0-indexed
|
console.debug('🔄 [openMarkdownFile] 设置行号:', startLine - 1)
|
||||||
|
try {
|
||||||
|
existingLeaf.view.setEphemeralState({ line: startLine - 1 }) // -1 because line is 0-indexed
|
||||||
|
console.debug('✅ [openMarkdownFile] 成功设置行号')
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ [openMarkdownFile] 设置行号失败:', error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const leaf = app.workspace.getLeaf('tab')
|
console.debug('🔄 [openMarkdownFile] 创建新标签打开文件')
|
||||||
leaf.openFile(file, {
|
try {
|
||||||
eState: startLine ? { line: startLine - 1 } : undefined, // -1 because line is 0-indexed
|
const leaf = app.workspace.getLeaf('tab')
|
||||||
})
|
leaf.openFile(file, {
|
||||||
|
eState: startLine ? { line: startLine - 1 } : undefined, // -1 because line is 0-indexed
|
||||||
|
})
|
||||||
|
console.debug('✅ [openMarkdownFile] 成功在新标签中打开文件')
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ [openMarkdownFile] 在新标签中打开文件失败:', error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user