jupyter lab launcher: change soft order of launcher icons

888 views Asked by At

In the Jupyter Lab launcher, I'd like to control the sort order of the launcher icons. Basically, I want the newest versions of Python to show up first, to the left.

Right now, I don't see what determines the sort order. Looking at the kernel.json specs in /usr/local/share/jupyter/kernels/ and ~/.local/share/jupyter/, it doesn't look like the sort order is displayed based on the display_name, language, or kernel.json creation timestamp. The sort order looks kinda arbitrary, but maybe I'm not seeing the pattern that it's using.

It looks like the Jupyter Lab launcher is generated using a React app (https://github.com/jupyterlab/jupyterlab/blob/master/packages/launcher/src/index.tsx#L224), but I'm not sure where it's getting the list of Launchers from (and am not super familiar with React).

Anyone know how to change the sort order of the icons on the Launcher?

1

There are 1 answers

0
Work Chris On

I think you are asking specifically about the order of notebook kernels in the launcher.

The sort order looks kinda arbitrary, but maybe I'm not seeing the pattern that it's using.

It's the "default" (or "native") kernel first, followed by others sorted according to their display_name.

Anyone know how to change the sort order of the icons on the Launcher?

As far as I can see, the only way to control the order of the kernels is to specify display_names for kernels such that their order according to String.localeCompare() matches what you want (combined with excluding the "default"/"native" kernel if it's not the one you want to see first).

Explanation...

The order of icons is controlled first by a rank, then localeCompare() on a label. Here's where the sorting happens, in the launcher extension's index.tsx file you already found:

// Within each category sort by rank
for (const cat in categories) {
  categories[cat] = categories[cat].sort(
    (a: ILauncher.IItemOptions, b: ILauncher.IItemOptions) => {
      return Private.sortCmp(a, b, this._cwd, this._commands);
    }
  );
}

(https://github.com/jupyterlab/jupyterlab/blob/0bec95d5364986eaf19dab4721a98c75f13db40f/packages/launcher/src/index.tsx#L172-L179)

The sort function:

  /**
   * A sort comparison function for a launcher item.
   */
  export function sortCmp(
    a: ILauncher.IItemOptions,
    b: ILauncher.IItemOptions,
    cwd: string,
    commands: CommandRegistry
  ): number {
    // First, compare by rank.
    const r1 = a.rank;
    const r2 = b.rank;
    if (r1 !== r2 && r1 !== undefined && r2 !== undefined) {
      return r1 < r2 ? -1 : 1; // Infinity safe
    }

    // Finally, compare by display name.
    const aLabel = commands.label(a.command, { ...a.args, cwd });
    const bLabel = commands.label(b.command, { ...b.args, cwd });
    return aLabel.localeCompare(bLabel);
  }
}

(https://github.com/jupyterlab/jupyterlab/blob/0bec95d5364986eaf19dab4721a98c75f13db40f/packages/launcher/src/index.tsx#L499-L520)

Unfortunately the rank of kernels is fixed: 0 for the default kernel, and Infinity for others:

for (const name in specs.kernelspecs) {
  const rank = name === specs.default ? 0 : Infinity;

(https://github.com/jupyterlab/jupyterlab/blob/0bec95d5364986eaf19dab4721a98c75f13db40f/packages/notebook-extension/src/index.ts#L770)

If you are trying to control order as above, you might need to consider excluding the default kernel (e.g. Python 3 or similar) as it will always appear first:

class KernelSpecManager(LoggingConfigurable):

    [...]

    ensure_native_kernel = Bool(True, config=True,
        help="""If there is no Python kernelspec registered and the IPython
        kernel is available, ensure it is added to the spec list.
        """
    )

(https://github.com/jupyter/jupyter_client/blob/012cb1948d92c6f329cf1a749fece6c99a2485bf/jupyter_client/kernelspec.py#L122-L125)