Update todo buttons
This commit is contained in:
+24
-27
@@ -54,9 +54,8 @@
|
|||||||
// bracketed ([done] [pri] …) to match the app's button aesthetic.
|
// bracketed ([done] [pri] …) to match the app's button aesthetic.
|
||||||
var toolbar = document.createElement('div');
|
var toolbar = document.createElement('div');
|
||||||
toolbar.className = 'row gap-1 todo-toolbar';
|
toolbar.className = 'row gap-1 todo-toolbar';
|
||||||
toolbar.appendChild(toolButton('done', 'Toggle done (x) on this line', actions.done));
|
toolbar.appendChild(toolButton('pri', 'Cycle priority (A → B → C → D → none)', actions.priority));
|
||||||
toolbar.appendChild(toolButton('pri', 'Cycle priority (A → B → C → none)', actions.priority));
|
toolbar.appendChild(toolButton('sort', 'Sort by priority, then context, then text', actions.sort));
|
||||||
toolbar.appendChild(toolButton('date', "Insert today's date at the cursor", actions.date));
|
|
||||||
toolbar.appendChild(toolButton('del', 'Delete this line', actions.del, 'danger'));
|
toolbar.appendChild(toolButton('del', 'Delete this line', actions.del, 'danger'));
|
||||||
|
|
||||||
marker = document.createElement('span');
|
marker = document.createElement('span');
|
||||||
@@ -158,41 +157,39 @@
|
|||||||
|
|
||||||
// --- Toolbar ---------------------------------------------------------
|
// --- Toolbar ---------------------------------------------------------
|
||||||
|
|
||||||
function pad2(n) { return (n < 10 ? '0' : '') + n; }
|
|
||||||
|
|
||||||
// Local ISO date (YYYY-MM-DD), matching the wiki's date convention.
|
|
||||||
function todayISO() {
|
|
||||||
var d = new Date();
|
|
||||||
return d.getFullYear() + '-' + pad2(d.getMonth() + 1) + '-' + pad2(d.getDate());
|
|
||||||
}
|
|
||||||
|
|
||||||
function mainLine(v) { return v.state.doc.lineAt(v.state.selection.main.head); }
|
function mainLine(v) { return v.state.doc.lineAt(v.state.selection.main.head); }
|
||||||
|
|
||||||
// Each action operates on the current line of the CM view. Kept deliberately
|
// Each action operates on the current line of the CM view. Kept deliberately
|
||||||
// simple (string edits at the line start / cursor) — no task parsing, per
|
// simple (string edits at the line start / cursor) — no task parsing, per
|
||||||
// the todo.txt widget's highlighting-only remit.
|
// the todo.txt widget's highlighting-only remit.
|
||||||
var actions = {
|
var actions = {
|
||||||
// Toggle the `x ` done prefix (with completion date). Stripping also
|
// Cycle the leading priority: none → (A) → (B) → (C) → (D) → none.
|
||||||
// removes the optional date that followed it.
|
|
||||||
done: function (v) {
|
|
||||||
var line = mainLine(v);
|
|
||||||
var m = /^x (?:\d{4}-\d{2}-\d{2} )?/.exec(line.text);
|
|
||||||
if (m) {
|
|
||||||
v.dispatch({ changes: { from: line.from, to: line.from + m[0].length } });
|
|
||||||
} else {
|
|
||||||
v.dispatch({ changes: { from: line.from, insert: 'x ' + todayISO() + ' ' } });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// Cycle the leading priority: none → (A) → (B) → (C) → none.
|
|
||||||
priority: function (v) {
|
priority: function (v) {
|
||||||
var line = mainLine(v);
|
var line = mainLine(v);
|
||||||
var m = /^\(([A-Z])\) /.exec(line.text);
|
var m = /^\(([A-Z])\) /.exec(line.text);
|
||||||
var next = !m ? '(A) ' : m[1] === 'A' ? '(B) ' : m[1] === 'B' ? '(C) ' : '';
|
var next = !m ? '(A) ' : m[1] === 'A' ? '(B) ' : m[1] === 'B' ? '(C) '
|
||||||
|
: m[1] === 'C' ? '(D) ' : '';
|
||||||
v.dispatch({ changes: { from: line.from, to: line.from + (m ? m[0].length : 0), insert: next } });
|
v.dispatch({ changes: { from: line.from, to: line.from + (m ? m[0].length : 0), insert: next } });
|
||||||
},
|
},
|
||||||
// Insert today's date at the cursor.
|
// Sort the whole list. A plain case-insensitive line sort yields the
|
||||||
date: function (v) {
|
// desired priority → context → text order for free: "(A) " sorts ahead
|
||||||
v.dispatch(v.state.replaceSelection(todayISO() + ' '));
|
// of everything (the "(" leads), so prioritised lines rise to the top in
|
||||||
|
// A/B/C/D order; the "@context" written right after the priority breaks
|
||||||
|
// ties, and the remaining text breaks those. Completed "x …" lines fall
|
||||||
|
// to the bottom (x sorts late). Blank lines are dropped so they don't
|
||||||
|
// float to the top.
|
||||||
|
sort: function (v) {
|
||||||
|
var doc = v.state.doc.toString();
|
||||||
|
var trailingNL = /\n$/.test(doc);
|
||||||
|
var lines = doc.split('\n').filter(function (l) { return l.trim() !== ''; });
|
||||||
|
lines.sort(function (a, b) {
|
||||||
|
var la = a.toLowerCase(), lb = b.toLowerCase();
|
||||||
|
if (la !== lb) return la < lb ? -1 : 1;
|
||||||
|
return a < b ? -1 : a > b ? 1 : 0;
|
||||||
|
});
|
||||||
|
var out = lines.join('\n') + (trailingNL ? '\n' : '');
|
||||||
|
if (out === doc) return;
|
||||||
|
v.dispatch({ changes: { from: 0, to: v.state.doc.length, insert: out } });
|
||||||
},
|
},
|
||||||
del: function (v) { CM.deleteLine(v); },
|
del: function (v) { CM.deleteLine(v); },
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user