imdone-core 2.0.12 → 2.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.imdoneignore +1 -0
- package/lib/config.js +4 -0
- package/lib/mixins/repo-fs-store.js +2 -8
- package/lib/mixins/repo-watched-fs-store.js +44 -5
- package/lib/repository.js +4 -4
- package/lib/task.js +24 -2
- package/package.json +1 -1
- package/types/card.d.ts +1 -0
- package/types/config.d.ts +1 -0
- package/types/file.d.ts +1 -0
- package/types/task.d.ts +7 -1
package/.imdoneignore
CHANGED
package/lib/config.js
CHANGED
|
@@ -20,11 +20,10 @@ import _ignore from 'ignore'
|
|
|
20
20
|
import { sort } from 'fast-sort'
|
|
21
21
|
import { buildMigrateConfig } from '../migrate-config.js'
|
|
22
22
|
import { loadYAML, dumpYAML } from '../adapters/yaml.js';
|
|
23
|
-
import realFs
|
|
23
|
+
import realFs from 'fs'
|
|
24
24
|
import { preparePathForWriting, readFile, writeFile, stat, lstat, unlink } from '../adapters/file-gateway.js'
|
|
25
25
|
|
|
26
26
|
const {
|
|
27
|
-
CONFIG_FILE,
|
|
28
27
|
CONFIG_FILE_YML,
|
|
29
28
|
ASYNC_LIMIT,
|
|
30
29
|
DEFAULT_IGNORE_PATHS,
|
|
@@ -198,11 +197,6 @@ export function fileSystemStoreMixin(repo, fs = realFs) {
|
|
|
198
197
|
return repo.config
|
|
199
198
|
}
|
|
200
199
|
|
|
201
|
-
// READY Refactor loadConfig to use async/await
|
|
202
|
-
// #esm-migration
|
|
203
|
-
// <!--
|
|
204
|
-
// order:-255
|
|
205
|
-
// -->
|
|
206
200
|
repo.loadConfig = async function (cb) {
|
|
207
201
|
// BACKLOG If a config is bad move it to config.json.bak and save a new one with defaults gh:2 id:9 +enhancement +standup +chore
|
|
208
202
|
// <!--
|
|
@@ -217,7 +211,7 @@ export function fileSystemStoreMixin(repo, fs = realFs) {
|
|
|
217
211
|
}
|
|
218
212
|
|
|
219
213
|
repo.getConfigFile = function () {
|
|
220
|
-
return repo.getFullPath(
|
|
214
|
+
return repo.getFullPath(CONFIG_FILE_YML)
|
|
221
215
|
}
|
|
222
216
|
|
|
223
217
|
repo.getYamlConfig = async function () {
|
|
@@ -18,6 +18,7 @@ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
|
|
|
18
18
|
const _init = repo.init
|
|
19
19
|
let initializing = false
|
|
20
20
|
let refreshing = false
|
|
21
|
+
let watcherPaused = false
|
|
21
22
|
|
|
22
23
|
function ready() {
|
|
23
24
|
return !initializing && !refreshing
|
|
@@ -30,6 +31,30 @@ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
|
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
// Add function to pause the watcher
|
|
35
|
+
repo.pauseWatcher = async function() {
|
|
36
|
+
if (repo.watcher && !watcherPaused) {
|
|
37
|
+
logger.info('Pausing file watcher for:', repo.path)
|
|
38
|
+
await repo.watcher.close()
|
|
39
|
+
watcherPaused = true
|
|
40
|
+
repo.emit('watcher.paused')
|
|
41
|
+
return true
|
|
42
|
+
}
|
|
43
|
+
return false
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Add function to unpause the watcher
|
|
47
|
+
repo.unpauseWatcher = async function() {
|
|
48
|
+
if (watcherPaused) {
|
|
49
|
+
logger.info('Unpausing file watcher for:', repo.path)
|
|
50
|
+
await repo.initWatcher()
|
|
51
|
+
watcherPaused = false
|
|
52
|
+
repo.emit('watcher.resumed')
|
|
53
|
+
return true
|
|
54
|
+
}
|
|
55
|
+
return false
|
|
56
|
+
}
|
|
57
|
+
|
|
33
58
|
// READY Refactor init to async/await
|
|
34
59
|
// #esm-migration #important
|
|
35
60
|
// <!--
|
|
@@ -69,7 +94,10 @@ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
|
|
|
69
94
|
refreshing = true
|
|
70
95
|
try {
|
|
71
96
|
const files = await _refresh.call(repo)
|
|
72
|
-
|
|
97
|
+
// Only initialize watcher if it's not paused
|
|
98
|
+
if (!watcherPaused) {
|
|
99
|
+
await repo.initWatcher()
|
|
100
|
+
}
|
|
73
101
|
refreshing = false
|
|
74
102
|
return files
|
|
75
103
|
} catch (err) {
|
|
@@ -108,6 +136,11 @@ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
|
|
|
108
136
|
// defer:2025-03-18
|
|
109
137
|
// -->
|
|
110
138
|
repo.initWatcher = async () => {
|
|
139
|
+
// Close existing watcher if it exists
|
|
140
|
+
if (repo.watcher) {
|
|
141
|
+
await repo.watcher.close()
|
|
142
|
+
}
|
|
143
|
+
|
|
111
144
|
return new Promise(async (resolve, reject) => {
|
|
112
145
|
logger.log('initializing watcher for:', repo.path)
|
|
113
146
|
repo.watcher = chokidar.watch(repo.path, {
|
|
@@ -118,8 +151,11 @@ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
|
|
|
118
151
|
atomic: true,
|
|
119
152
|
ignoreInitial: true,
|
|
120
153
|
ignored: (file) => {
|
|
121
|
-
|
|
122
|
-
|
|
154
|
+
if (file === repo.path) return false
|
|
155
|
+
const relPath = repo.getRelativePath(file)
|
|
156
|
+
const ignored = !repo.shouldInclude(relPath)
|
|
157
|
+
if (ignored) logger.log('Ignoring file:', relPath)
|
|
158
|
+
|
|
123
159
|
return ignored
|
|
124
160
|
}
|
|
125
161
|
}).on('error', (err) => {
|
|
@@ -163,6 +199,11 @@ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
|
|
|
163
199
|
stat.mtime
|
|
164
200
|
)
|
|
165
201
|
if (!path || stat.isDirectory()) return
|
|
202
|
+
|
|
203
|
+
const relPath = repo.getRelativePath(path)
|
|
204
|
+
if (!initializing && _isImdoneConfig(relPath)) onConfigChange(relPath)
|
|
205
|
+
if (!initializing && _isImdoneIgnore(relPath)) onIgnoreChange(relPath)
|
|
206
|
+
|
|
166
207
|
var file = repo.getFile(path) || path
|
|
167
208
|
const isFile = File.isFile(file)
|
|
168
209
|
// BACKLOG ## Handle the case where the file is not in the repo
|
|
@@ -174,8 +215,6 @@ export function watchedFileSystemStoreMixin(repo, fs = realFs) {
|
|
|
174
215
|
// logger.log("File update already applied. Change ignored.")
|
|
175
216
|
return
|
|
176
217
|
}
|
|
177
|
-
if (_isImdoneConfig(path)) return onConfigChange(path)
|
|
178
|
-
if (_isImdoneIgnore(path)) return onIgnoreChange(path)
|
|
179
218
|
|
|
180
219
|
const ok = await repo.fileOK((file && file.path) || path)
|
|
181
220
|
if (!ok) return
|
package/lib/repository.js
CHANGED
|
@@ -634,12 +634,12 @@ export class Repository extends Emitter {
|
|
|
634
634
|
shouldInclude (relPath) {
|
|
635
635
|
relPath = this.getRelativePath(relPath)
|
|
636
636
|
let include = true
|
|
637
|
-
if (this.config.markdownOnly && relPath) {
|
|
638
|
-
include = File.isMarkdown(relPath)
|
|
639
|
-
}
|
|
640
637
|
if (this.ignore) {
|
|
641
638
|
try {
|
|
642
|
-
include =
|
|
639
|
+
include = relPath && !this.ignore.ignores(relPath)
|
|
640
|
+
if (this.config.markdownOnly && include && relPath) {
|
|
641
|
+
include = File.isMarkdown(relPath)
|
|
642
|
+
}
|
|
643
643
|
} catch (e) {
|
|
644
644
|
logger.error(
|
|
645
645
|
`Failed to check ignore status for dir: [${relPath}] in: [${this.path}]. It will be included.`,
|
package/lib/task.js
CHANGED
|
@@ -188,6 +188,10 @@ export class Task {
|
|
|
188
188
|
getTagPrefix () {
|
|
189
189
|
return this.config?.getTagPrefix()
|
|
190
190
|
}
|
|
191
|
+
|
|
192
|
+
getCommentTagsOnly () {
|
|
193
|
+
return this.config?.getCommentTagsOnly()
|
|
194
|
+
}
|
|
191
195
|
|
|
192
196
|
static addToLastCommentInContent (content, toAdd, newLine) {
|
|
193
197
|
// BACKLOG respect padding of task prefix for list items
|
|
@@ -315,14 +319,16 @@ export class Task {
|
|
|
315
319
|
'gmiu'
|
|
316
320
|
)
|
|
317
321
|
}
|
|
318
|
-
static getTags (text, prefix = '+') {
|
|
322
|
+
static getTags (text, prefix = '+', commentTagsOnly = false) {
|
|
319
323
|
const tags = [];
|
|
320
324
|
const codePositions = Task.getMarkdownCodePositions(text);
|
|
321
325
|
const linkLabelPositions = Task.getMarkdownLinkLabelPositions(text);
|
|
326
|
+
const commentPositions = Task.getCommentPositions(text);
|
|
322
327
|
let result;
|
|
323
328
|
const re = Task.getTagRegexp(prefix);
|
|
324
329
|
|
|
325
330
|
while ((result = re.exec(text)) !== null) {
|
|
331
|
+
if (commentTagsOnly && !Task.isResultInComment(commentPositions, result.index)) continue;
|
|
326
332
|
if (Task.isResultInMarkdownCode(codePositions, result.index)) continue;
|
|
327
333
|
if (Task.isResultInMarkdownLinkLabel(linkLabelPositions, result.index)) continue;
|
|
328
334
|
const tag = result[2];
|
|
@@ -349,6 +355,22 @@ export class Task {
|
|
|
349
355
|
return linkLabelPositions.some(pos => index >= pos.start && index < pos.end);
|
|
350
356
|
};
|
|
351
357
|
|
|
358
|
+
static getCommentPositions (text) {
|
|
359
|
+
const positions = [];
|
|
360
|
+
const re = /<!--[\s\S]*?-->/g;
|
|
361
|
+
let match;
|
|
362
|
+
|
|
363
|
+
while ((match = re.exec(text)) !== null) {
|
|
364
|
+
positions.push({ start: match.index, end: re.lastIndex });
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
return positions;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
static isResultInComment (commentPositions, index) {
|
|
371
|
+
return commentPositions.some(pos => index >= pos.start && index < pos.end);
|
|
372
|
+
}
|
|
373
|
+
|
|
352
374
|
static ContextRegExp = new RegExp(
|
|
353
375
|
`(^|\\s)@([${Task.AnyLanguageGroup}${Task.EmojiGroup}]+)`,
|
|
354
376
|
'gmiu'
|
|
@@ -567,7 +589,7 @@ export class Task {
|
|
|
567
589
|
}
|
|
568
590
|
|
|
569
591
|
parseTodoTxt () {
|
|
570
|
-
this.tags = Task.getTags(this.getRawTextAndDescription(), this.getTagPrefix())
|
|
592
|
+
this.tags = Task.getTags(this.getRawTextAndDescription(), this.getTagPrefix(), this.getCommentTagsOnly())
|
|
571
593
|
this.context = Task.getContext(this.getRawTextAndDescription())
|
|
572
594
|
this.meta = Task.getMetaData(this.config, this)
|
|
573
595
|
}
|
package/package.json
CHANGED
package/types/card.d.ts
CHANGED
|
@@ -158,6 +158,7 @@ export function newCard(task: any, _project: any, dontParse: any): {
|
|
|
158
158
|
expand: boolean;
|
|
159
159
|
};
|
|
160
160
|
getTagPrefix(): any;
|
|
161
|
+
getCommentTagsOnly(): any;
|
|
161
162
|
addToLastCommentInContent(content: any, toAdd: any, newLine: any): string;
|
|
162
163
|
getCheckedData(): {
|
|
163
164
|
pad: number;
|
package/types/config.d.ts
CHANGED
package/types/file.d.ts
CHANGED
package/types/task.d.ts
CHANGED
|
@@ -18,12 +18,17 @@ export class Task {
|
|
|
18
18
|
static AnyLanguageGroup: string;
|
|
19
19
|
static EmojiGroup: string;
|
|
20
20
|
static getTagRegexp(prefix?: string): RegExp;
|
|
21
|
-
static getTags(text: any, prefix?: string): string[];
|
|
21
|
+
static getTags(text: any, prefix?: string, commentTagsOnly?: boolean): string[];
|
|
22
22
|
static getMarkdownLinkLabelPositions(text: any): {
|
|
23
23
|
start: number;
|
|
24
24
|
end: number;
|
|
25
25
|
}[];
|
|
26
26
|
static isResultInMarkdownLinkLabel(linkLabelPositions: any, index: any): any;
|
|
27
|
+
static getCommentPositions(text: any): {
|
|
28
|
+
start: number;
|
|
29
|
+
end: number;
|
|
30
|
+
}[];
|
|
31
|
+
static isResultInComment(commentPositions: any, index: any): any;
|
|
27
32
|
static ContextRegExp: RegExp;
|
|
28
33
|
static getContext(text: any): string[];
|
|
29
34
|
static MetaRegExp: RegExp;
|
|
@@ -124,6 +129,7 @@ export class Task {
|
|
|
124
129
|
expand: boolean;
|
|
125
130
|
};
|
|
126
131
|
getTagPrefix(): any;
|
|
132
|
+
getCommentTagsOnly(): any;
|
|
127
133
|
addToLastCommentInContent(content: any, toAdd: any, newLine: any): string;
|
|
128
134
|
getCheckedData(): {
|
|
129
135
|
pad: number;
|