( input: string, entryId: string, )
| 785 | } |
| 786 | |
| 787 | function findLocalMemoryEntryFullSection( |
| 788 | input: string, |
| 789 | entryId: string, |
| 790 | ): { |
| 791 | title: string; |
| 792 | meta?: Record<string, string>; |
| 793 | content: string; |
| 794 | range: LocalMemoryEntryDraftRange; |
| 795 | } | null { |
| 796 | const id = entryId.trim(); |
| 797 | if (!id) return null; |
| 798 | |
| 799 | const lines = input.split(/\r?\n/); |
| 800 | const lineStarts: number[] = []; |
| 801 | let offset = 0; |
| 802 | for (let index = 0; index < lines.length; index += 1) { |
| 803 | lineStarts[index] = offset; |
| 804 | offset += (lines[index] ?? '').length; |
| 805 | if (index < lines.length - 1) |
| 806 | offset += input[offset] === '\r' && input[offset + 1] === '\n' ? 2 : 1; |
| 807 | } |
| 808 | lineStarts[lines.length] = input.length; |
| 809 | |
| 810 | let current: { |
| 811 | title: string; |
| 812 | headingLineIndex: number; |
| 813 | body: string[]; |
| 814 | meta?: Record<string, string>; |
| 815 | } | null = null; |
| 816 | |
| 817 | const matchCurrent = (endLineIndex: number) => { |
| 818 | if (!current) return null; |
| 819 | const currentId = current.meta?.id ?? slugId(current.title); |
| 820 | const proposalId = current.meta?.proposalId; |
| 821 | if (currentId !== id && proposalId !== id) return null; |
| 822 | return { |
| 823 | title: current.title, |
| 824 | meta: current.meta, |
| 825 | content: current.body.join('\n').trim(), |
| 826 | range: { |
| 827 | start: lineStarts[current.headingLineIndex] ?? 0, |
| 828 | end: lineStarts[endLineIndex] ?? input.length, |
| 829 | }, |
| 830 | }; |
| 831 | }; |
| 832 | |
| 833 | for (let index = 0; index < lines.length; index += 1) { |
| 834 | const line = lines[index] ?? ''; |
| 835 | const heading = /^##\s+(.+?)\s*$/.exec(line); |
| 836 | if (heading) { |
| 837 | const matched = matchCurrent(index); |
| 838 | if (matched) return matched; |
| 839 | current = { title: heading[1] ?? '未命名记忆', headingLineIndex: index, body: [] }; |
| 840 | continue; |
| 841 | } |
| 842 | if (!current) continue; |
| 843 | const meta = parseMetaComment(line); |
| 844 | if (meta) { |
no test coverage detected