1+ import type { CachedMetadata , EventRef , HeadingCache , ListItemCache , SectionCache , Workspace } from 'obsidian' ;
12import { MetadataCache , Notice , TAbstractFile , TFile , Vault } from 'obsidian' ;
2- import type { CachedMetadata , EventRef , Workspace } from 'obsidian' ;
3- import type { HeadingCache , ListItemCache , SectionCache } from 'obsidian' ;
43import { Mutex } from 'async-mutex' ;
54import { TasksFile } from '../Scripting/TasksFile' ;
65import { ListItem } from '../Task/ListItem' ;
@@ -9,131 +8,16 @@ import { Task } from '../Task/Task';
98import { DateFallback } from '../DateTime/DateFallback' ;
109import { getSettings } from '../Config/Settings' ;
1110import { Lazy } from '../lib/Lazy' ;
12- import { TaskLocation } from '../Task/TaskLocation' ;
1311import { Logger , logging } from '../lib/logging' ;
1412import type { TasksEvents } from './TasksEvents' ;
13+ import { getTasksFromFileContent2 } from './FileParser' ;
1514
1615export enum State {
1716 Cold = 'Cold' ,
1817 Initializing = 'Initializing' ,
1918 Warm = 'Warm' ,
2019}
2120
22- export function getTasksFromFileContent2 (
23- filePath : string ,
24- fileContent : string ,
25- listItems : ListItemCache [ ] | undefined ,
26- logger : Logger ,
27- fileCache : CachedMetadata ,
28- errorReporter : ( e : any , filePath : string , listItem : ListItemCache , line : string ) => void ,
29- ) {
30- const tasks : Task [ ] = [ ] ;
31- if ( listItems === undefined ) {
32- // When called via Cache, this function would never be called or files without list items.
33- // It is useful for tests to be act gracefully on sample Markdown files with no list items, however.
34- return tasks ;
35- }
36-
37- const tasksFile = new TasksFile ( filePath , fileCache ) ;
38- const fileLines = fileContent . split ( '\n' ) ;
39- const linesInFile = fileLines . length ;
40-
41- // Lazily store date extracted from filename to avoid parsing more than needed
42- // this.logger.debug(`getTasksFromFileContent() reading ${file.path}`);
43- const dateFromFileName = new Lazy ( ( ) => DateFallback . fromPath ( filePath ) ) ;
44-
45- // We want to store section information with every task so
46- // that we can use that when we post process the markdown
47- // rendered lists.
48- let currentSection : SectionCache | null = null ;
49- let sectionIndex = 0 ;
50- const line2ListItem : Map < number , ListItem > = new Map ( ) ;
51- for ( const listItem of listItems ) {
52- const lineNumber = listItem . position . start . line ;
53- if ( lineNumber >= linesInFile ) {
54- /*
55- Obsidian CachedMetadata has told us that there is a task on lineNumber, but there are
56- not that many lines in the file.
57-
58- This was the underlying cause of all the 'Stuck on "Loading Tasks..."' messages,
59- as it resulted in the line 'undefined' being parsed.
60-
61- Somehow the file had been shortened whilst Obsidian was closed, meaning that
62- when Obsidian started up, it got the new file content, but still had the old cached
63- data about locations of list items in the file.
64- */
65- logger . debug (
66- `${ filePath } Obsidian gave us a line number ${ lineNumber } past the end of the file. ${ linesInFile } .` ,
67- ) ;
68- return tasks ;
69- }
70- if ( currentSection === null || currentSection . position . end . line < lineNumber ) {
71- // We went past the current section (or this is the first task).
72- // Find the section that is relevant for this task and the following of the same section.
73- currentSection = Cache . getSection ( lineNumber , fileCache . sections ) ;
74- sectionIndex = 0 ;
75- }
76-
77- if ( currentSection === null ) {
78- // Cannot process a task without a section.
79- continue ;
80- }
81-
82- const line = fileLines [ lineNumber ] ;
83- if ( line === undefined ) {
84- logger . debug ( `${ filePath } : line ${ lineNumber } - ignoring 'undefined' line.` ) ;
85- continue ;
86- }
87-
88- if ( listItem . task !== undefined ) {
89- let task ;
90- try {
91- task = Task . fromLine ( {
92- line,
93- taskLocation : new TaskLocation (
94- tasksFile ,
95- lineNumber ,
96- currentSection . position . start . line ,
97- sectionIndex ,
98- Cache . getPrecedingHeader ( lineNumber , fileCache . headings ) ,
99- ) ,
100- fallbackDate : dateFromFileName . value ,
101- } ) ;
102-
103- if ( task !== null ) {
104- // listItem.parent could be negative if the parent is not found (in other words, it is a root task).
105- // That is not a problem, as we never put a negative number in line2ListItem map, so parent will be null.
106- const parentListItem : ListItem | null = line2ListItem . get ( listItem . parent ) ?? null ;
107- if ( parentListItem !== null ) {
108- task = new Task ( {
109- ...task ,
110- parent : parentListItem ,
111- } ) ;
112- }
113-
114- line2ListItem . set ( lineNumber , task ) ;
115- }
116- } catch ( e ) {
117- errorReporter ( e , filePath , listItem , line ) ;
118- continue ;
119- }
120-
121- if ( task !== null ) {
122- sectionIndex ++ ;
123- tasks . push ( task ) ;
124- }
125- } else {
126- const lineNumber = listItem . position . start . line ;
127-
128- const parentListItem : ListItem | null = line2ListItem . get ( listItem . parent ) ?? null ;
129-
130- line2ListItem . set ( lineNumber , new ListItem ( fileLines [ lineNumber ] , parentListItem ) ) ;
131- }
132- }
133-
134- return tasks ;
135- }
136-
13721export class Cache {
13822 logger = logging . getLogger ( 'tasks.Cache' ) ;
13923
0 commit comments