Use a single shortcut (toggle) to expand and collapse a row

Bike use one shortcut to expand a row and another shortcut to collapse a row.

Instead a single shortcut could be used (such as CMD+. or CMD+0) that toggle expand/collapse.

1 Like

I won’t change the current design, but you can create your own toggle command with AppleScript. I think this should do it:

tell front document of application "Bike"
	if selection row is collapsed then
		expand selection rows
	else if selection row is expanded then
		collapse selection rows
	end if
end tell

Here’s how to use Scripts:

Hi,

Thanks for the tip!

Out of curiosity, why a “toggle open/collapse” is not a better/good UX/Design in your opinion? (if you don’t have the time to answer, feel free to skip ;))

Perhaps instead of changing the current design, only adding a toggle menu and shortcut?

Regards

I don’t have a lot of logic behind decision… but current design is what I “expect” from using other apps. For example in macOS Finder list view expand/collapse is done with separate arrow keys. Same with older outliners like OmniOutliner.

If most apps before Bike used a toggle I would happily use that instead, but few if any of them seem to.

I would rather people use a script if they want a toggle. I’m always battling (and sometimes winning) to keep menu’s and short and clear looking as possible. In this case I don’t think dedicating a new menu item to expand/collapse toggle is worthwhile since

Important Note: I never use the Command-0 and Command-9 shortcuts myself. Instead I always exit to outline mode and use left/right arrow to expand/collapse items. You might find that easier.

2 Likes

Essentially the same as the AppleScript above (just holds back when the row is a leaf) but I found that I was reaching for this today, while trying to get an outline right :slight_smile:

Expand disclosure triangle to view JS source
(() => {
    "use strict";

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

        return either(
            msg => msg
        )(
            methodName => methodName
        )(
            bindLR(
                doc.exists()
                    ? Right(doc.selectionRow)
                    : Left("No documents open in Bike.")
            )(
                row => fmapLR(
                    k => (row[k](), k)
                )(
                    row.containsRows()
                        ? Right(
                            row.expanded()
                                ? "collapse"
                                : "expand"
                        )
                        : Left("Leaf row")
                )
            )
        );
    };

    // --------------------- 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
    });


    // bindLR (>>=) :: Either a ->
    // (a -> Either b) -> Either b
    const bindLR = lr =>
        // Bind operator for the Either option type.
        // If lr has a Left value then lr unchanged,
        // otherwise the function mf applied to the
        // Right value in lr.
        mf => "Left" in lr
            ? lr
            : mf(lr.Right);

    // 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 => "Left" in e
            ? fl(e.Left)
            : fr(e.Right);


    // fmapLR (<$>) :: (b -> c) -> Either a b -> Either a c
    const fmapLR = f =>
        // Either f mapped into the contents of any Right
        // value in e, or e unchanged if is a Left value.
        e => "Left" in e
            ? e
            : Right(f(e.Right));

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

See: Using Scripts - Bike

To test in Script Editor.app set the language selector at top left to JavaScript rather than AppleScript.

You can assign a Bike script to a keyboard shortcut using utilities like Keyboard Maestro and FastScripts.

1 Like