[Enhancement] Scope word count to currently focused branch

Currently the word count in status bar is always global for the entire document. I think it would make sense to scope the counts to the current focus branch.

I do all my work in a single Bike document – individual tasks and presentations are just bullets in a large hierarchy. The word count of the main document is meaningless to me, but when I focus into an item to work on some presentation it would be useful to know how many words it already has.

1 Like

In the meanwhile, you could experiment with this script, which reports the combined word count of:

  • The selected line,
  • and all of its descendants.
Expand disclosure triangle to view JS source
(() => {
    "use strict";

    // Count of words in all descendants of the selected
    // Bike row. (Including words in the row itself).

    // The result is displayed in a dialog, and copied
    // to the clipboard.


    //  Rob Trew @2023
    // Ver 0.1

    const title = "Words in selected row and its descendants";

    // main :: IO ()
    const main = () => {

        ObjC.import("AppKit");

        const doc = Application("Bike").documents.at(0);

        return either(
            alert(title)
        )(
            report => (
                copyText(report),
                alert(title)(report)
            )
        )(
            doc.exists()
                ? (() => {
                    const
                        selnRow = doc.selectionRow,
                        rows = [
                            selnRow,
                            ...selnRow.entireContents()
                        ]
                        .flatMap(row => {
                            const s = row.name().trim();

                            return 0 < s.length
                                ? [s]
                                : [];
                        }),
                        n = 0 < rows.length
                            ? rows
                            .join("\n")
                            .split(/\s+/u)
                            .length
                            : 0;

                    return 0 < n
                        ? Right(`${n} words in branch:\n\t"${rows[0]}"`)
                        : Left("No words in selected row and descendants.");
                })()
                : Left("No documents open in Bike.")
        );
    };


    // ----------------------- JXA -----------------------

    // alert :: String => String -> IO String
    const alert = title =>
        s => {
            const sa = Object.assign(
                Application("System Events"), {
                    includeStandardAdditions: true
                });

            return (
                sa.activate(),
                sa.displayDialog(s, {
                    withTitle: title,
                    buttons: ["OK"],
                    defaultButton: "OK"
                }),
                s
            );
        };


    // copyText :: String -> IO String
    const copyText = s => {
    // ObjC.import("AppKit");
        const pb = $.NSPasteboard.generalPasteboard;

        return (
            pb.clearContents,
            pb.setStringForType(
                $(s),
                $.NSPasteboardTypeString
            ),
            s
        );
    };

    // --------------------- GENERIC ---------------------

    // Left :: a -> Either a b
    const Left = x => ({
        type: "Either",
        Left: x
    });


    // Right :: b -> Either a b
    const Right = x => ({
        type: "Either",
        Right: x
    });


    // either :: (a -> c) -> (b -> c) -> Either a b -> c
    const either = fl =>
        // Application of the function fl to the
        // contents of any Left value in e, or
        // the application of fr to its Right value.
        fr => e => e.Left ? (
            fl(e.Left)
        ) : fr(e.Right);

    // MAIN ---
    return main();
})();

To test in Script Editor, set the language selector at top left to JavaScript (rather than AppleScript)

See: Using Scripts - Bike

2 Likes

I’ve added this in latest Bike preview release:

3 Likes

Thanks – just checked it and it works great.

And thanks for creating Bike!

1 Like