Skip to content

Commit

Permalink
Merge pull request #2612 from obsidian-tasks-group/reduce-cyclic-deps
Browse files Browse the repository at this point in the history
refactor: Reduce cyclic dependencies in src/
  • Loading branch information
claremacrae committed Jan 23, 2024
2 parents ce5eed5 + d334f6b commit e65dd75
Show file tree
Hide file tree
Showing 39 changed files with 163 additions and 131 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ yarn-error.log

# Code analysis output files
/circular-deps.png
/circular-deps.txt
#/circular-deps.txt

# approval test files
*.received.*
Expand Down
15 changes: 15 additions & 0 deletions circular-deps.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Processed 152 files (995ms) (16 warnings)

1) Config/Settings.ts > Suggestor/Suggestor.ts
2) Task/Task.ts > Config/Settings.ts > Suggestor/Suggestor.ts
3) Task/Task.ts > Config/Settings.ts > Suggestor/Suggestor.ts > TaskSerializer/DefaultTaskSerializer.ts
4) Task/Task.ts > Config/Settings.ts > TaskSerializer/DataviewTaskSerializer.ts
5) Task/Task.ts > Task/DateFallback.ts
6) Task/Task.ts > Task/Urgency.ts
7) Task/Task.ts > lib/LogTasksHelper.ts
8) Query/Query.ts > Query/Explain/Explainer.ts
9) Query/FilterParser.ts > Query/Filter/BooleanField.ts
10) main.ts > Config/SettingsTab.ts
11) Obsidian/Cache.ts > Obsidian/TasksEvents.ts
12) main.ts > Renderer/QueryRenderer.ts

4 changes: 3 additions & 1 deletion src/Commands/CreateOrEditTaskParser.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { Status } from '../Statuses/Status';
import { Priority, Task, TaskRegularExpressions } from '../Task/Task';
import { Task } from '../Task/Task';
import { DateFallback } from '../Task/DateFallback';
import { StatusRegistry } from '../Statuses/StatusRegistry';
import { TaskLocation } from '../Task/TaskLocation';
import { getSettings } from '../Config/Settings';
import { GlobalFilter } from '../Config/GlobalFilter';
import { Priority } from '../Task/Priority';
import { TaskRegularExpressions } from '../Task/TaskRegularExpressions';

function getDefaultCreatedDate() {
const { setCreatedDate } = getSettings();
Expand Down
3 changes: 2 additions & 1 deletion src/Commands/ToggleDone.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Editor, type EditorPosition, type MarkdownFileInfo, MarkdownView } from 'obsidian';
import { StatusRegistry } from '../Statuses/StatusRegistry';

import { Task, TaskRegularExpressions } from '../Task/Task';
import { Task } from '../Task/Task';
import { TaskLocation } from '../Task/TaskLocation';
import { TaskRegularExpressions } from '../Task/TaskRegularExpressions';

export const toggleDone = (checking: boolean, editor: Editor, view: MarkdownView | MarkdownFileInfo) => {
if (checking) {
Expand Down
3 changes: 2 additions & 1 deletion src/Query/Filter/PriorityField.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Priority, Task } from '../../Task/Task';
import type { Task } from '../../Task/Task';
import { Explanation } from '../Explain/Explanation';
import type { Comparator } from '../Sort/Sorter';
import type { GrouperFunction } from '../Group/Grouper';
import { Priority } from '../../Task/Priority';
import { Field } from './Field';
import { Filter } from './Filter';
import { FilterOrErrorMessage } from './FilterOrErrorMessage';
Expand Down
4 changes: 2 additions & 2 deletions src/Renderer/TaskLineRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { replaceTaskWithTasks } from '../Obsidian/File';
import type { TaskLayoutComponent, TaskLayoutOptions } from '../Layout/TaskLayoutOptions';
import type { QueryLayoutOptions } from '../Layout/QueryLayoutOptions';
import type { Task } from '../Task/Task';
import * as taskModule from '../Task/Task';
import { StatusMenu } from '../ui/Menus/StatusMenu';
import { StatusRegistry } from '../Statuses/StatusRegistry';
import { TaskRegularExpressions } from '../Task/TaskRegularExpressions';
import { TaskFieldRenderer } from './TaskFieldRenderer';

/**
Expand Down Expand Up @@ -309,7 +309,7 @@ export class TaskLineRenderer {
}

function toTooltipDate({ signifier, date }: { signifier: string; date: Moment }): string {
return `${signifier} ${date.format(taskModule.TaskRegularExpressions.dateFormat)} (${date.from(
return `${signifier} ${date.format(TaskRegularExpressions.dateFormat)} (${date.from(
window.moment().startOf('day'),
)})`;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Scripting/TasksDate.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { DurationInputArg2, Moment, unitOfTime } from 'moment';
import { Notice } from 'obsidian';
import { TaskRegularExpressions } from '../Task/Task';
import { PropertyCategory } from '../lib/PropertyCategory';
import { TaskRegularExpressions } from '../Task/TaskRegularExpressions';

/**
* TasksDate encapsulates a date, for simplifying the JavaScript expressions users need to
Expand Down
11 changes: 0 additions & 11 deletions src/Statuses/StatusRegistryReport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,3 @@ ${settingsTable}
These are the settings actually used by Tasks.
${mermaidText}`;
}

export function getPrintableSymbol(symbol: string) {
// Do not put backticks around an empty symbol, as the two backticks are rendered
// by Obsidian as ordinary characters and the meaning is unclear.
// Better to just display nothing in this situation.
if (symbol === '') {
return symbol;
}
const result = symbol !== ' ' ? symbol : 'space';
return '`' + result + '`';
}
14 changes: 12 additions & 2 deletions src/Statuses/StatusSettingsReport.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
import { StatusSettings } from '../Config/StatusSettings';
import { MarkdownTable } from '../lib/MarkdownTable';
import type { StatusConfiguration } from './StatusConfiguration';
import { getPrintableSymbol } from './StatusRegistryReport';
import { Status } from './Status';
import { StatusType } from './StatusConfiguration';
import { Status } from './Status';

function getFirstIndex(statusConfigurations: StatusConfiguration[], wantedSymbol: string) {
return statusConfigurations.findIndex((s) => s.symbol === wantedSymbol);
}

export function getPrintableSymbol(symbol: string) {
// Do not put backticks around an empty symbol, as the two backticks are rendered
// by Obsidian as ordinary characters and the meaning is unclear.
// Better to just display nothing in this situation.
if (symbol === '') {
return symbol;
}
const result = symbol !== ' ' ? symbol : 'space';
return '`' + result + '`';
}

function checkIfConventionalType(status: StatusConfiguration, problems: string[]) {
// Check if conventional type is being used:
const conventionalType = Status.getTypeForUnknownSymbol(status.symbol);
Expand Down
3 changes: 2 additions & 1 deletion src/Suggestor/Suggestor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { DateParser } from '../Query/DateParser';
import { doAutocomplete } from '../lib/DateAbbreviations';
import { Recurrence } from '../Task/Recurrence';
import type { DefaultTaskSerializerSymbols } from '../TaskSerializer/DefaultTaskSerializer';
import { Task, TaskRegularExpressions } from '../Task/Task';
import { Task } from '../Task/Task';
import { GlobalFilter } from '../Config/GlobalFilter';
import { TaskRegularExpressions } from '../Task/TaskRegularExpressions';
import type { SuggestInfo, SuggestionBuilder } from '.';

/**
Expand Down
19 changes: 19 additions & 0 deletions src/Task/Priority.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* When sorting, make sure low always comes after none. This way any tasks with low will be below any exiting
* tasks that have no priority which would be the default.
*
* Values can be converted to strings with:
* - {@link priorityNameUsingNone} in {@link PriorityTools}
* - {@link priorityNameUsingNormal} in {@link PriorityTools}
*
* @export
* @enum {number}
*/
export enum Priority {
Highest = '0',
High = '1',
Medium = '2',
None = '3',
Low = '4',
Lowest = '5',
}
86 changes: 2 additions & 84 deletions src/Task/Task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,90 +14,8 @@ import { DateFallback } from './DateFallback';
import { Urgency } from './Urgency';
import type { Recurrence } from './Recurrence';
import type { TaskLocation } from './TaskLocation';

/**
* When sorting, make sure low always comes after none. This way any tasks with low will be below any exiting
* tasks that have no priority which would be the default.
*
* Values can be converted to strings with:
* - {@link priorityNameUsingNone} in {@link PriorityTools}
* - {@link priorityNameUsingNormal} in {@link PriorityTools}
*
* @export
* @enum {number}
*/
export enum Priority {
Highest = '0',
High = '1',
Medium = '2',
None = '3',
Low = '4',
Lowest = '5',
}

export class TaskRegularExpressions {
public static readonly dateFormat = 'YYYY-MM-DD';
public static readonly dateTimeFormat = 'YYYY-MM-DD HH:mm';

// Matches indentation before a list marker (including > for potentially nested blockquotes or Obsidian callouts)
public static readonly indentationRegex = /^([\s\t>]*)/;

// Matches - * and + list markers, or numbered list markers (eg 1.)
public static readonly listMarkerRegex = /([-*+]|[0-9]+\.)/;

// Matches a checkbox and saves the status character inside
public static readonly checkboxRegex = /\[(.)\]/u;

// Matches the rest of the task after the checkbox.
public static readonly afterCheckboxRegex = / *(.*)/u;

// Main regex for parsing a line. It matches the following:
// - Indentation
// - List marker
// - Status character
// - Rest of task after checkbox markdown
// See Task.extractTaskComponents() for abstraction around this regular expression.
// That is private for now, but could be made public in future if needed.
public static readonly taskRegex = new RegExp(
TaskRegularExpressions.indentationRegex.source +
TaskRegularExpressions.listMarkerRegex.source +
' +' +
TaskRegularExpressions.checkboxRegex.source +
TaskRegularExpressions.afterCheckboxRegex.source,
'u',
);

// Used with the "Create or Edit Task" command to parse indentation and status if present
public static readonly nonTaskRegex = new RegExp(
TaskRegularExpressions.indentationRegex.source +
TaskRegularExpressions.listMarkerRegex.source +
'? *(' +
TaskRegularExpressions.checkboxRegex.source +
')?' +
TaskRegularExpressions.afterCheckboxRegex.source,
'u',
);

// Used with "Toggle Done" command to detect a list item that can get a checkbox added to it.
public static readonly listItemRegex = new RegExp(
TaskRegularExpressions.indentationRegex.source + TaskRegularExpressions.listMarkerRegex.source,
);

// Match on block link at end.
public static readonly blockLinkRegex = / \^[a-zA-Z0-9-]+$/u;

// Regex to match all hash tags, basically hash followed by anything but the characters in the negation.
// To ensure URLs are not caught it is looking of beginning of string tag and any
// tag that has a space in front of it. Any # that has a character in front
// of it will be ignored.
// EXAMPLE:
// description: '#dog #car http://www/ddd#ere #house'
// matches: #dog, #car, #house
// MAINTENANCE NOTE:
// If hashTags is modified, please update 'Recognising Tags' in Tags.md in the docs.
public static readonly hashTags = /(^|\s)#[^ !@#$%^&*(),.?":{}|<>]+/g;
public static readonly hashTagsFromEnd = new RegExp(this.hashTags.source + '$');
}
import type { Priority } from './Priority';
import { TaskRegularExpressions } from './TaskRegularExpressions';

/**
* Storage for the task line, broken down in to sections.
Expand Down
63 changes: 63 additions & 0 deletions src/Task/TaskRegularExpressions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
export class TaskRegularExpressions {
public static readonly dateFormat = 'YYYY-MM-DD';
public static readonly dateTimeFormat = 'YYYY-MM-DD HH:mm';

// Matches indentation before a list marker (including > for potentially nested blockquotes or Obsidian callouts)
public static readonly indentationRegex = /^([\s\t>]*)/;

// Matches - * and + list markers, or numbered list markers (eg 1.)
public static readonly listMarkerRegex = /([-*+]|[0-9]+\.)/;

// Matches a checkbox and saves the status character inside
public static readonly checkboxRegex = /\[(.)\]/u;

// Matches the rest of the task after the checkbox.
public static readonly afterCheckboxRegex = / *(.*)/u;

// Main regex for parsing a line. It matches the following:
// - Indentation
// - List marker
// - Status character
// - Rest of task after checkbox markdown
// See Task.extractTaskComponents() for abstraction around this regular expression.
// That is private for now, but could be made public in future if needed.
public static readonly taskRegex = new RegExp(
TaskRegularExpressions.indentationRegex.source +
TaskRegularExpressions.listMarkerRegex.source +
' +' +
TaskRegularExpressions.checkboxRegex.source +
TaskRegularExpressions.afterCheckboxRegex.source,
'u',
);

// Used with the "Create or Edit Task" command to parse indentation and status if present
public static readonly nonTaskRegex = new RegExp(
TaskRegularExpressions.indentationRegex.source +
TaskRegularExpressions.listMarkerRegex.source +
'? *(' +
TaskRegularExpressions.checkboxRegex.source +
')?' +
TaskRegularExpressions.afterCheckboxRegex.source,
'u',
);

// Used with "Toggle Done" command to detect a list item that can get a checkbox added to it.
public static readonly listItemRegex = new RegExp(
TaskRegularExpressions.indentationRegex.source + TaskRegularExpressions.listMarkerRegex.source,
);

// Match on block link at end.
public static readonly blockLinkRegex = / \^[a-zA-Z0-9-]+$/u;

// Regex to match all hash tags, basically hash followed by anything but the characters in the negation.
// To ensure URLs are not caught it is looking of beginning of string tag and any
// tag that has a space in front of it. Any # that has a character in front
// of it will be ignored.
// EXAMPLE:
// description: '#dog #car http://www/ddd#ere #house'
// matches: #dog, #car, #house
// MAINTENANCE NOTE:
// If hashTags is modified, please update 'Recognising Tags' in Tags.md in the docs.
public static readonly hashTags = /(^|\s)#[^ !@#$%^&*(),.?":{}|<>]+/g;
public static readonly hashTagsFromEnd = new RegExp(this.hashTags.source + '$');
}
2 changes: 1 addition & 1 deletion src/TaskSerializer/DataviewTaskSerializer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { TaskLayoutComponent } from '../Layout/TaskLayoutOptions';
import type { Task } from '../Task/Task';
import { Priority } from '../Task/Task';
import { Priority } from '../Task/Priority';
import { DefaultTaskSerializer } from './DefaultTaskSerializer';

/**
Expand Down
4 changes: 3 additions & 1 deletion src/TaskSerializer/DefaultTaskSerializer.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import type { Moment } from 'moment';
import { type TaskLayoutComponent, TaskLayoutOptions } from '../Layout/TaskLayoutOptions';
import { Recurrence } from '../Task/Recurrence';
import { Priority, Task, TaskRegularExpressions } from '../Task/Task';
import { Task } from '../Task/Task';
import { Priority } from '../Task/Priority';
import { TaskRegularExpressions } from '../Task/TaskRegularExpressions';
import type { TaskDetails, TaskSerializer } from '.';

/* Interface describing the symbols that {@link DefaultTaskSerializer}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/PriorityTools.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Priority } from '../Task/Task';
import { Priority } from '../Task/Priority';

export class PriorityTools {
/**
Expand Down
3 changes: 2 additions & 1 deletion src/ui/EditInstructions/PriorityInstructions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Priority, Task } from '../../Task/Task';
import { Task } from '../../Task/Task';
import { PriorityTools } from '../../lib/PriorityTools';
import { Priority } from '../../Task/Priority';
import type { TaskEditingInstruction } from './TaskEditingInstruction';

/**
Expand Down
3 changes: 2 additions & 1 deletion src/ui/EditTask.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
import { getSettings, TASK_FORMATS } from '../Config/Settings';
import { GlobalFilter } from '../Config/GlobalFilter';
import { Status } from '../Statuses/Status';
import { Priority, Task } from '../Task/Task';
import { Task } from '../Task/Task';
import { doAutocomplete } from '../lib/DateAbbreviations';
import { TasksDate } from '../Scripting/TasksDate';
import { addDependencyToParent, ensureTaskHasId, generateUniqueId, removeDependency } from "../Task/TaskDependency";
import { replaceTaskWithTasks } from "../Obsidian/File";
import type { EditableTask } from "./EditableTask";
import Dependency from "./Dependency.svelte";
import { Priority } from '../Task/Priority';
// These exported variables are passed in as props by TaskModal.onOpen():
export let task: Task;
Expand Down
2 changes: 1 addition & 1 deletion tests/Commands/CreateOrEditTaskParser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
*/
import moment from 'moment';
import { resetSettings, updateSettings } from '../../src/Config/Settings';
import { Priority } from '../../src/Task/Task';
import { taskFromLine } from '../../src/Commands/CreateOrEditTaskParser';
import { GlobalFilter } from '../../src/Config/GlobalFilter';
import { Priority } from '../../src/Task/Priority';

window.moment = moment;

Expand Down
3 changes: 2 additions & 1 deletion tests/CustomMatchers/CustomMatchersForTaskSerializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { diff } from 'jest-diff';
import type { MatcherFunction } from 'expect';
import moment from 'moment';
import type { TaskDetails } from '../../src/TaskSerializer';
import { Priority, TaskRegularExpressions } from '../../src/Task/Task';
import { Recurrence } from '../../src/Task/Recurrence';
import { Priority } from '../../src/Task/Priority';
import { TaskRegularExpressions } from '../../src/Task/TaskRegularExpressions';

declare global {
namespace jest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import moment from 'moment';
import { verifyMarkdownForDocs } from '../../TestingTools/VerifyMarkdown';
import { TaskBuilder } from '../../TestingTools/TaskBuilder';
import { Urgency } from '../../../src/Task/Urgency';
import { Priority } from '../../../src/Task/Task';

import { Priority } from '../../../src/Task/Priority';

window.moment = moment;

Expand Down

0 comments on commit e65dd75

Please sign in to comment.