npm package: @flatjs/evolve-launch-editor
Description: ## Usage
Latest version: 2.2.2

# @flatjs/evolve-launch-editor

## Usage

1. `flatjs-evolve.config.ts`

```ts

import { createLaunchEditorMiddleware } from '@flatjs/evolve-launch-editor';

export default defineConfig((env) => ({
  projectVirtualPath: '',
  devServer: {
    middlewares: [createLaunchEditorMiddleware({})],
    mockOptions: {
      port: 8000,
      ...
    },
  },

  ...
})
```

2. Custom fetch server api to open the code editor `gotoServerEditor.ts`

```ts filename=gotoServerEditor.ts
const getCodeInfo = (codeInfo) =>
  'codeInfo' in codeInfo ? codeInfo.codeInfo : codeInfo;

// Note if you have an customized `devServer.pageProxy` in `flatjs-evolve.config.ts`
// e.g. `devServer.pageProxy: 'route'`, you should change to `/route/__inspect-open-in-editor`
const launchEditorEndpoint = '/pages/__inspect-open-in-editor';

/**
 * fetch server api to open the code editor
 */
export const gotoServerEditor = (
  codeInfo?,
  options?: {
    editor?;
  }
) => {
  if (!codeInfo) return;
  codeInfo = getCodeInfo(codeInfo);

  const { lineNumber, columnNumber, relativePath, absolutePath } = codeInfo;

  const isRelative = Boolean(relativePath);
  const fileName = isRelative ? relativePath : absolutePath;

  if (!fileName) {
    console.error(
      `[react-dev-inspector] Cannot open editor without source fileName`,
      codeInfo
    );
    return;
  }

  const launchParams = {
    fileName,
    lineNumber,
    colNumber: columnNumber,
    editor: options?.editor,
  };

  const urlParams = new URLSearchParams(
    Object.entries(launchParams).filter(([, value]) => Boolean(value)) as [
      string,
      string,
    ][]
  );

  fetchToServerEditor({
    apiUrl: launchEditorEndpoint,
    urlParams,
  });
};

const fetchToServerEditor = async ({
  apiUrl,
  urlParams,
  fallbackUrl,
}: {
  apiUrl: string;
  urlParams: URLSearchParams;
  fallbackUrl?: string;
}) => {
  const response = await fetch(`${apiUrl}?${urlParams}`);
  // only 404 need to try fallback legacy endpoint
  if (response.status === 404 && fallbackUrl) {
    return await fetch(`${fallbackUrl}?${urlParams}`);
  }
  return response;
};
```

3. Create tsx component named `FileInspector`

```tsx
import { useState } from 'react';
import { Inspector } from 'react-dev-inspector';
import { gotoServerEditor } from './gotoServerEditor';

export const FileInspector = () => {
  const [active, setActive] = useState(false);

  return (
    <Inspector
      active={active}
      onActiveChange={setActive}
      onInspectElement={gotoServerEditor}
    >
      <div className="mx-auto max-w-2xl">
        <div className="text-center">
          <div className="mt-8 flex flex-col items-center justify-center gap-x-6">
            <div className="mb-2 mt-6 text-[min(4.5vw,1rem)] font-light leading-[min(6vw,1.75rem)] text-gray-600 sm:text-lg">
              try shortcuts or click ↓
            </div>

            <button
              className="group flex items-center text-[min(4vw,.875rem)] leading-[min(5vw,1.25rem)] sm:text-base"
              onClick={() => setActive(true)}
            >
              <span>Ctrl + Shift + Command + C</span>
              <span className="ml-1">🍭</span>
            </button>
          </div>
        </div>
      </div>
    </Inspector>
  );
};
```

## Custom editor support

You can use the LAUNCH_EDITOR environment variable to force a specific supported editor

```shell
LAUNCH_EDITOR=code
LAUNCH_EDITOR=code-insiders

```

### Supported editors

| Value           | Editor                                                                 | Linux | Windows | macOS |
| --------------- | ---------------------------------------------------------------------- | :---: | :-----: | :---: |
| `appcode`       | [AppCode](https://www.jetbrains.com/objc/)                             |       |         |   ✓   |
| `atom`          | [Atom](https://atom.io/)                                               |   ✓   |    ✓    |   ✓   |
| `atom-beta`     | [Atom Beta](https://atom.io/beta)                                      |       |         |   ✓   |
| `brackets`      | [Brackets](http://brackets.io/)                                        |   ✓   |    ✓    |   ✓   |
| `clion`         | [Clion](https://www.jetbrains.com/clion/)                              |       |    ✓    |   ✓   |
| `code`          | [Visual Studio Code](https://code.visualstudio.com/)                   |   ✓   |    ✓    |   ✓   |
| `code-insiders` | [Visual Studio Code Insiders](https://code.visualstudio.com/insiders/) |   ✓   |    ✓    |   ✓   |
| `codium`        | [VSCodium](https://github.com/VSCodium/vscodium)                       |   ✓   |    ✓    |   ✓   |
| `emacs`         | [Emacs](https://www.gnu.org/software/emacs/)                           |   ✓   |         |       |
| `idea`          | [IDEA](https://www.jetbrains.com/idea/)                                |   ✓   |    ✓    |   ✓   |
| `notepad++`     | [Notepad++](https://notepad-plus-plus.org/download/v7.5.4.html)        |       |    ✓    |       |
| `pycharm`       | [PyCharm](https://www.jetbrains.com/pycharm/)                          |   ✓   |    ✓    |   ✓   |
| `phpstorm`      | [PhpStorm](https://www.jetbrains.com/phpstorm/)                        |   ✓   |    ✓    |   ✓   |
| `rider`         | [Rider](https://www.jetbrains.com/rider/)                              |   ✓   |    ✓    |   ✓   |
| `rubymine`      | [RubyMine](https://www.jetbrains.com/ruby/)                            |   ✓   |    ✓    |   ✓   |
| `sublime`       | [Sublime Text](https://www.sublimetext.com/)                           |   ✓   |    ✓    |   ✓   |
| `vim`           | [Vim](http://www.vim.org/)                                             |   ✓   |         |       |
| `visualstudio`  | [Visual Studio](https://www.visualstudio.com/vs/)                      |       |         |   ✓   |
| `webstorm`      | [WebStorm](https://www.jetbrains.com/webstorm/)                        |   ✓   |    ✓    |   ✓   |
| `zed`           | [Zed](https://zed.dev/)                                                |       |         |   ✓   |