📦 Turbo Golo
3f4b5b9 parent: f7107e3 added
.memory/handoffs/2026-09-29-ssh-remote-editing.md +16 -0 | new file mode 100644 | ||
| @@ -0,0 +1,16 @@ | ||
| 1 | +# Handoff — 2026-09-29 — `-ssh` remote editing | |
| 2 | + | |
| 3 | +## State | |
| 4 | + | |
| 5 | +`turbo-golo -ssh user@machine[:dir]` is wired and tested under a `go.work` pointing at `../turbo-core`, which holds the uncommitted `fsys`/`remote` packages. Docs EN+FR done. | |
| 6 | + | |
| 7 | +## Next steps | |
| 8 | + | |
| 9 | +1. Once turbo-core v1.0.5 is published: remove the workspace, `go get rickub.com/turbo-editors/turbo-core@v1.0.5 && go mod tidy && GOWORK=off make check` — the two `TestTheTagScript*` tests must then pass. | |
| 10 | +2. Run the quality gate (needs `qlty`). | |
| 11 | +3. Try `turbo-golo -ssh turbo-demo:workspace` against `../demo-remote-machine` (its README has the `~/.ssh/config` block). Only Python is installed there, so this editor's tools menu will find no toolchain — the files, tree and terminal are what to check. | |
| 12 | + | |
| 13 | +## Watch out for | |
| 14 | + | |
| 15 | +- `parseFlags` now calls `parseArguments(flag.CommandLine, os.Args[1:])`; add new flags inside `parseArguments`, on `flags`, not on the `flag` package. | |
| 16 | +- Over ssh no language server starts, by design (`session == nil` guard in `edit`). | |
| new file mode 100644 | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | +# Handoff — 2026-09-29 — `-ssh` remote editing | ||
| 2 | + | ||
| 3 | +## State | ||
| 4 | + | ||
| 5 | +`turbo-golo -ssh user@machine[:dir]` is wired and tested under a `go.work` pointing at `../turbo-core`, which holds the uncommitted `fsys`/`remote` packages. Docs EN+FR done. | ||
| 6 | + | ||
| 7 | +## Next steps | ||
| 8 | + | ||
| 9 | +1. Once turbo-core v1.0.5 is published: remove the workspace, `go get rickub.com/turbo-editors/turbo-core@v1.0.5 && go mod tidy && GOWORK=off make check` — the two `TestTheTagScript*` tests must then pass. | ||
| 10 | +2. Run the quality gate (needs `qlty`). | ||
| 11 | +3. Try `turbo-golo -ssh turbo-demo:workspace` against `../demo-remote-machine` (its README has the `~/.ssh/config` block). Only Python is installed there, so this editor's tools menu will find no toolchain — the files, tree and terminal are what to check. | ||
| 12 | + | ||
| 13 | +## Watch out for | ||
| 14 | + | ||
| 15 | +- `parseFlags` now calls `parseArguments(flag.CommandLine, os.Args[1:])`; add new flags inside `parseArguments`, on `flags`, not on the `flag` package. | ||
| 16 | +- Over ssh no language server starts, by design (`session == nil` guard in `edit`). | ||
modified
.memory/history.md +8 -0 | @@ -102,3 +102,11 @@ One dated entry per session, appended at the end. Never rewritten. | ||
| 102 | 102 | |
| 103 | 103 | - **Changed here** (docs only, EN+FR): `how-to/use-a-terminal.md` gained "Copy from the terminal into a file, and back"; `reference/terminal.md` gained the selection keys, the drag row, a "Copying and pasting" table, private mode 2004, `editor.selection` in the colours, and lost "bracketed paste" from the not-implemented list; `reference/keyboard.md` gained the terminal and mouse rows; `explanation/terminal-windows.md` gained "Copying out and pasting in". Applied from the umbrella session that added the feature to turbo-core, by one anchored script across the six editors. |
| 104 | 104 | - **Not done**: `go.mod` still pins v1.0.3, so the binary built without the workspace does not yet have the feature the docs describe; nothing committed. |
| 105 | + | |
| 106 | +## 2026-09-29 — `-ssh` / `--ssh`: edit another machine's files (ticket #33) | |
| 107 | + | |
| 108 | +- **Asked** (umbrella session): `turbo-python -ssh user@machine`, then all six editors; the work is turbo-core's (`fsys`, `remote`, `app.UseRemote` — its history has the design and the rejected alternatives). | |
| 109 | +- **Changes here**: `main.go` (see summary), new `ssh_test.go`, docs EN+FR (`reference/cli.md`, `how-to/edit-a-remote-machine.md`, indexes), `README.md`, `docs/diagrams/packages.drawio`. Applied from one script across the six editors, anchored and asserting each anchor. | |
| 110 | +- **Tests**: `ssh_test.go` — `-ssh` and `--ssh` and `--ssh=` read the same; files after the flag stay files; no flag keeps `fsys` local; `-oProxyCommand=evil` refused with `remote.ErrBadTarget` before anything runs; project settings read from an in-memory `fsys`. Green under the workspace; the two `TestTheTagScript*` tests fail until turbo-core v1.0.5 is re-pinned. | |
| 111 | +- **Quality**: gate not run (no `qlty` in the sandbox). `gofmt`, `go vet` clean. | |
| 112 | +- **Not done**: not committed; `go.mod` not re-pinned (no v1.0.5 yet). | |
| @@ -102,3 +102,11 @@ One dated entry per session, appended at the end. Never rewritten. | |||
| 102 | 102 | ||
| 103 | - **Changed here** (docs only, EN+FR): `how-to/use-a-terminal.md` gained "Copy from the terminal into a file, and back"; `reference/terminal.md` gained the selection keys, the drag row, a "Copying and pasting" table, private mode 2004, `editor.selection` in the colours, and lost "bracketed paste" from the not-implemented list; `reference/keyboard.md` gained the terminal and mouse rows; `explanation/terminal-windows.md` gained "Copying out and pasting in". Applied from the umbrella session that added the feature to turbo-core, by one anchored script across the six editors. | 103 | - **Changed here** (docs only, EN+FR): `how-to/use-a-terminal.md` gained "Copy from the terminal into a file, and back"; `reference/terminal.md` gained the selection keys, the drag row, a "Copying and pasting" table, private mode 2004, `editor.selection` in the colours, and lost "bracketed paste" from the not-implemented list; `reference/keyboard.md` gained the terminal and mouse rows; `explanation/terminal-windows.md` gained "Copying out and pasting in". Applied from the umbrella session that added the feature to turbo-core, by one anchored script across the six editors. |
| 104 | - **Not done**: `go.mod` still pins v1.0.3, so the binary built without the workspace does not yet have the feature the docs describe; nothing committed. | 104 | - **Not done**: `go.mod` still pins v1.0.3, so the binary built without the workspace does not yet have the feature the docs describe; nothing committed. |
| 105 | + | ||
| 106 | +## 2026-09-29 — `-ssh` / `--ssh`: edit another machine's files (ticket #33) | ||
| 107 | + | ||
| 108 | +- **Asked** (umbrella session): `turbo-python -ssh user@machine`, then all six editors; the work is turbo-core's (`fsys`, `remote`, `app.UseRemote` — its history has the design and the rejected alternatives). | ||
| 109 | +- **Changes here**: `main.go` (see summary), new `ssh_test.go`, docs EN+FR (`reference/cli.md`, `how-to/edit-a-remote-machine.md`, indexes), `README.md`, `docs/diagrams/packages.drawio`. Applied from one script across the six editors, anchored and asserting each anchor. | ||
| 110 | +- **Tests**: `ssh_test.go` — `-ssh` and `--ssh` and `--ssh=` read the same; files after the flag stay files; no flag keeps `fsys` local; `-oProxyCommand=evil` refused with `remote.ErrBadTarget` before anything runs; project settings read from an in-memory `fsys`. Green under the workspace; the two `TestTheTagScript*` tests fail until turbo-core v1.0.5 is re-pinned. | ||
| 111 | +- **Quality**: gate not run (no `qlty` in the sandbox). `gofmt`, `go vet` clean. | ||
| 112 | +- **Not done**: not committed; `go.mod` not re-pinned (no v1.0.5 yet). | ||
modified
.memory/summary.md +6 -0 | @@ -113,3 +113,9 @@ go list -f '{{.Dir}}' rickub.com/turbo-editors/turbo-core/app # must NOT be un | ||
| 113 | 113 | |
| 114 | 114 | - Docs and the snippets template already describe **turbo-core v1.0.4's AsciiDoc** (ninth built-in language) while `go.mod` still pins v1.0.3; the suite passes either way. Re-pin when v1.0.4 is tagged. |
| 115 | 115 | |
| 116 | +## State as of 2026-09-29 | |
| 117 | + | |
| 118 | +- **`-ssh user@machine[:dir]` / `--ssh` is wired** (ticket #33), on top of turbo-core's new `fsys` and `remote` (unreleased — see turbo-core's memory). `main.go`: `ssh` option, `parseFlags` now a wrapper over `parseArguments(*flag.FlagSet, args)` so tests can drive it, `connectRemote` (before `newScreen`: `remote.Open`, then `fsys.Use(session.FS())`), `editor.UseRemote(session)`, no `StartLanguageServer` over ssh, `loadProjectSettings` reads `fsys.Getwd()`. `ssh_test.go`: 5 tests. Not run interactively in this editor; the same `main.go` wiring was driven end to end in turbo-python, and this editor's `ssh_test.go` covers the flag, the refusal of a bad target, and the settings read through `fsys`. | |
| 119 | +- **Builds only under `go.work`** until turbo-core v1.0.5 is published and re-pinned: `go.mod` still pins v1.0.4, which has no `fsys`/`remote`. Under the workspace `go test ./...` is green **except `TestTheTagScriptTagsAndPushesForReal` and `TestTheTagScriptRefusesATagItAlreadyPublished`**, which copy the module and build with `GOWORK=off` against the published v1.0.4 — expected, same situation as `-load-config` on 2026-09-20. | |
| 120 | +- **Docs** (EN+FR): `reference/cli.md` (flag, files, exit status, examples, seven error rows), new `how-to/edit-a-remote-machine.md`, both indexes, `README.md` (feature bullet, command line). `docs/diagrams/packages.drawio` gained `fsys` and `remote` boxes and `main →` arrows (its diagram test demanded them). | |
| 121 | +- **Quality gate not run** — `qlty` is absent from this sandbox. | |
| @@ -113,3 +113,9 @@ go list -f '{{.Dir}}' rickub.com/turbo-editors/turbo-core/app # must NOT be un | |||
| 113 | 113 | ||
| 114 | - Docs and the snippets template already describe **turbo-core v1.0.4's AsciiDoc** (ninth built-in language) while `go.mod` still pins v1.0.3; the suite passes either way. Re-pin when v1.0.4 is tagged. | 114 | - Docs and the snippets template already describe **turbo-core v1.0.4's AsciiDoc** (ninth built-in language) while `go.mod` still pins v1.0.3; the suite passes either way. Re-pin when v1.0.4 is tagged. |
| 115 | 115 | ||
| 116 | +## State as of 2026-09-29 | ||
| 117 | + | ||
| 118 | +- **`-ssh user@machine[:dir]` / `--ssh` is wired** (ticket #33), on top of turbo-core's new `fsys` and `remote` (unreleased — see turbo-core's memory). `main.go`: `ssh` option, `parseFlags` now a wrapper over `parseArguments(*flag.FlagSet, args)` so tests can drive it, `connectRemote` (before `newScreen`: `remote.Open`, then `fsys.Use(session.FS())`), `editor.UseRemote(session)`, no `StartLanguageServer` over ssh, `loadProjectSettings` reads `fsys.Getwd()`. `ssh_test.go`: 5 tests. Not run interactively in this editor; the same `main.go` wiring was driven end to end in turbo-python, and this editor's `ssh_test.go` covers the flag, the refusal of a bad target, and the settings read through `fsys`. | ||
| 119 | +- **Builds only under `go.work`** until turbo-core v1.0.5 is published and re-pinned: `go.mod` still pins v1.0.4, which has no `fsys`/`remote`. Under the workspace `go test ./...` is green **except `TestTheTagScriptTagsAndPushesForReal` and `TestTheTagScriptRefusesATagItAlreadyPublished`**, which copy the module and build with `GOWORK=off` against the published v1.0.4 — expected, same situation as `-load-config` on 2026-09-20. | ||
| 120 | +- **Docs** (EN+FR): `reference/cli.md` (flag, files, exit status, examples, seven error rows), new `how-to/edit-a-remote-machine.md`, both indexes, `README.md` (feature bullet, command line). `docs/diagrams/packages.drawio` gained `fsys` and `remote` boxes and `main →` arrows (its diagram test demanded them). | ||
| 121 | +- **Quality gate not run** — `qlty` is absent from this sandbox. | ||
modified
README.md +2 -0 | @@ -52,6 +52,7 @@ The [tutorial](docs/en/tutorials/getting-started.md) walks through a first sessi | ||
| 52 | 52 | - **Completion, hover, go-to-definition, references, symbols and diagnostics** from `golo lsp`, entirely optional. The server is the interpreter, looked for on `PATH` and in `/usr/local/bin`, where GoloScript's installer puts it. It does not answer type definitions, and the editor says so rather than pretending |
| 53 | 53 | - **Terminal windows** — `F8` opens a real shell in a window, with its own VT/ANSI emulator, scrollback and job control (Linux, macOS and Windows) |
| 54 | 54 | - **Project tree** — `F9` shows the project's files in a window; walk it with the arrows and press Enter to open one |
| 55 | +- **Editing another machine** — `turbo-golo -ssh user@machine[:dir]` opens a project on a server, a VM or a container over your own ssh — its `~/.ssh/config`, keys, agent or password — so the files, the tree, the terminal windows and the Golo menu are that machine's. One login, before the screen is taken; no language server over there yet | |
| 55 | 56 | - **Snippets** — a `Snippets` menu built from `.turbo-golo/snippets.toml`, grouped into submenus and filtered by the file you are in; the chosen text is inserted at the cursor and re-indented to match |
| 56 | 57 | - **The GoloScript toolchain a menu away** — `Alt-G` runs the script, the tests, the debugger, the REPL, `golo new`, `gogolo build` and `wagolo build` from `.turbo-golo/tools.toml`, each showing its output where the tool asked: a popup that fills in as it goes, a terminal window, or an editing window to search. Golo has no manifest, so six of the eight commands ask which file they are for before they run — and a tool naming a `menu` of its own gets that menu on the bar |
| 57 | 58 | - **Editing** with word movement, block indent, a shared clipboard, and undo that merges a run of typing into one step |
| @@ -72,6 +73,7 @@ The [tutorial](docs/en/tutorials/getting-started.md) walks through a first sessi | ||
| 72 | 73 | ```bash |
| 73 | 74 | turbo-golo [-theme name] [-no-lsp] [file...] |
| 74 | 75 | turbo-golo -list-themes |
| 76 | +turbo-golo -ssh user@machine[:directory] [file...] | |
| 75 | 77 | ``` |
| 76 | 78 | |
| 77 | 79 | ## Documentation |
| @@ -52,6 +52,7 @@ The [tutorial](docs/en/tutorials/getting-started.md) walks through a first sessi | |||
| 52 | - **Completion, hover, go-to-definition, references, symbols and diagnostics** from `golo lsp`, entirely optional. The server is the interpreter, looked for on `PATH` and in `/usr/local/bin`, where GoloScript's installer puts it. It does not answer type definitions, and the editor says so rather than pretending | 52 | - **Completion, hover, go-to-definition, references, symbols and diagnostics** from `golo lsp`, entirely optional. The server is the interpreter, looked for on `PATH` and in `/usr/local/bin`, where GoloScript's installer puts it. It does not answer type definitions, and the editor says so rather than pretending |
| 53 | - **Terminal windows** — `F8` opens a real shell in a window, with its own VT/ANSI emulator, scrollback and job control (Linux, macOS and Windows) | 53 | - **Terminal windows** — `F8` opens a real shell in a window, with its own VT/ANSI emulator, scrollback and job control (Linux, macOS and Windows) |
| 54 | - **Project tree** — `F9` shows the project's files in a window; walk it with the arrows and press Enter to open one | 54 | - **Project tree** — `F9` shows the project's files in a window; walk it with the arrows and press Enter to open one |
| 55 | +- **Editing another machine** — `turbo-golo -ssh user@machine[:dir]` opens a project on a server, a VM or a container over your own ssh — its `~/.ssh/config`, keys, agent or password — so the files, the tree, the terminal windows and the Golo menu are that machine's. One login, before the screen is taken; no language server over there yet | ||
| 55 | - **Snippets** — a `Snippets` menu built from `.turbo-golo/snippets.toml`, grouped into submenus and filtered by the file you are in; the chosen text is inserted at the cursor and re-indented to match | 56 | - **Snippets** — a `Snippets` menu built from `.turbo-golo/snippets.toml`, grouped into submenus and filtered by the file you are in; the chosen text is inserted at the cursor and re-indented to match |
| 56 | - **The GoloScript toolchain a menu away** — `Alt-G` runs the script, the tests, the debugger, the REPL, `golo new`, `gogolo build` and `wagolo build` from `.turbo-golo/tools.toml`, each showing its output where the tool asked: a popup that fills in as it goes, a terminal window, or an editing window to search. Golo has no manifest, so six of the eight commands ask which file they are for before they run — and a tool naming a `menu` of its own gets that menu on the bar | 57 | - **The GoloScript toolchain a menu away** — `Alt-G` runs the script, the tests, the debugger, the REPL, `golo new`, `gogolo build` and `wagolo build` from `.turbo-golo/tools.toml`, each showing its output where the tool asked: a popup that fills in as it goes, a terminal window, or an editing window to search. Golo has no manifest, so six of the eight commands ask which file they are for before they run — and a tool naming a `menu` of its own gets that menu on the bar |
| 57 | - **Editing** with word movement, block indent, a shared clipboard, and undo that merges a run of typing into one step | 58 | - **Editing** with word movement, block indent, a shared clipboard, and undo that merges a run of typing into one step |
| @@ -72,6 +73,7 @@ The [tutorial](docs/en/tutorials/getting-started.md) walks through a first sessi | |||
| 72 | ```bash | 73 | ```bash |
| 73 | turbo-golo [-theme name] [-no-lsp] [file...] | 74 | turbo-golo [-theme name] [-no-lsp] [file...] |
| 74 | turbo-golo -list-themes | 75 | turbo-golo -list-themes |
| 76 | +turbo-golo -ssh user@machine[:directory] [file...] | ||
| 75 | ``` | 77 | ``` |
| 76 | 78 | ||
| 77 | ## Documentation | 79 | ## Documentation |
modified
docs/diagrams/packages.drawio +4 -0 | @@ -24,6 +24,10 @@ | ||
| 24 | 24 | <mxCell id="e18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;endFill=1;strokeColor=#6c8ebf;" edge="1" parent="1" source="2" target="8"><mxGeometry relative="1" as="geometry"/></mxCell> |
| 25 | 25 | <mxCell id="e19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;endFill=1;strokeColor=#6c8ebf;" edge="1" parent="1" source="2" target="9"><mxGeometry relative="1" as="geometry"/></mxCell> |
| 26 | 26 | <mxCell id="e20" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;endFill=1;strokeColor=#6c8ebf;" edge="1" parent="1" source="2" target="20"><mxGeometry relative="1" as="geometry"/></mxCell> |
| 27 | + <mxCell id="ssh-fsys" value="<b>fsys</b><br/><font style='font-size:9px'>turbo-core</font>" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;fontSize=11;" vertex="1" parent="1"><mxGeometry x="329" y="390" width="190" height="54" as="geometry"/></mxCell> | |
| 28 | + <mxCell id="e-main-fsys" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;endFill=1;strokeColor=#6c8ebf;" edge="1" parent="1" source="2" target="ssh-fsys"><mxGeometry relative="1" as="geometry"/></mxCell> | |
| 29 | + <mxCell id="ssh-remote" value="<b>remote</b><br/><font style='font-size:9px'>turbo-core</font>" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;fontSize=11;" vertex="1" parent="1"><mxGeometry x="541" y="390" width="190" height="54" as="geometry"/></mxCell> | |
| 30 | + <mxCell id="e-main-remote" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;endFill=1;strokeColor=#6c8ebf;" edge="1" parent="1" source="2" target="ssh-remote"><mxGeometry relative="1" as="geometry"/></mxCell> | |
| 27 | 31 | </root> |
| 28 | 32 | </mxGraphModel> |
| 29 | 33 | </diagram> |
| @@ -24,6 +24,10 @@ | |||
| 24 | <mxCell id="e18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;endFill=1;strokeColor=#6c8ebf;" edge="1" parent="1" source="2" target="8"><mxGeometry relative="1" as="geometry"/></mxCell> | 24 | <mxCell id="e18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;endFill=1;strokeColor=#6c8ebf;" edge="1" parent="1" source="2" target="8"><mxGeometry relative="1" as="geometry"/></mxCell> |
| 25 | <mxCell id="e19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;endFill=1;strokeColor=#6c8ebf;" edge="1" parent="1" source="2" target="9"><mxGeometry relative="1" as="geometry"/></mxCell> | 25 | <mxCell id="e19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;endFill=1;strokeColor=#6c8ebf;" edge="1" parent="1" source="2" target="9"><mxGeometry relative="1" as="geometry"/></mxCell> |
| 26 | <mxCell id="e20" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;endFill=1;strokeColor=#6c8ebf;" edge="1" parent="1" source="2" target="20"><mxGeometry relative="1" as="geometry"/></mxCell> | 26 | <mxCell id="e20" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;endFill=1;strokeColor=#6c8ebf;" edge="1" parent="1" source="2" target="20"><mxGeometry relative="1" as="geometry"/></mxCell> |
| 27 | + <mxCell id="ssh-fsys" value="<b>fsys</b><br/><font style='font-size:9px'>turbo-core</font>" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;fontSize=11;" vertex="1" parent="1"><mxGeometry x="329" y="390" width="190" height="54" as="geometry"/></mxCell> | ||
| 28 | + <mxCell id="e-main-fsys" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;endFill=1;strokeColor=#6c8ebf;" edge="1" parent="1" source="2" target="ssh-fsys"><mxGeometry relative="1" as="geometry"/></mxCell> | ||
| 29 | + <mxCell id="ssh-remote" value="<b>remote</b><br/><font style='font-size:9px'>turbo-core</font>" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;fontSize=11;" vertex="1" parent="1"><mxGeometry x="541" y="390" width="190" height="54" as="geometry"/></mxCell> | ||
| 30 | + <mxCell id="e-main-remote" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;endArrow=block;endFill=1;strokeColor=#6c8ebf;" edge="1" parent="1" source="2" target="ssh-remote"><mxGeometry relative="1" as="geometry"/></mxCell> | ||
| 27 | </root> | 31 | </root> |
| 28 | </mxGraphModel> | 32 | </mxGraphModel> |
| 29 | </diagram> | 33 | </diagram> |
modified
docs/en/README.md +1 -0 | @@ -28,6 +28,7 @@ This documentation follows the [Diátaxis](https://diataxis.fr) method. Four kin | ||
| 28 | 28 | - [How to run shell commands without leaving the editor](how-to/use-a-terminal.md) |
| 29 | 29 | - [How to give a project its own settings](how-to/configure-a-project.md) |
| 30 | 30 | - [How to browse a project and open files from a tree](how-to/browse-a-project.md) |
| 31 | +- [How to edit the files of a remote machine over ssh](how-to/edit-a-remote-machine.md) | |
| 31 | 32 | - [How to insert snippets from a menu](how-to/use-snippets.md) |
| 32 | 33 | - [How to run Golo commands from the editor](how-to/run-golo-commands.md) |
| 33 | 34 | - [How to make a release](how-to/make-a-release.md) |
| @@ -28,6 +28,7 @@ This documentation follows the [Diátaxis](https://diataxis.fr) method. Four kin | |||
| 28 | - [How to run shell commands without leaving the editor](how-to/use-a-terminal.md) | 28 | - [How to run shell commands without leaving the editor](how-to/use-a-terminal.md) |
| 29 | - [How to give a project its own settings](how-to/configure-a-project.md) | 29 | - [How to give a project its own settings](how-to/configure-a-project.md) |
| 30 | - [How to browse a project and open files from a tree](how-to/browse-a-project.md) | 30 | - [How to browse a project and open files from a tree](how-to/browse-a-project.md) |
| 31 | +- [How to edit the files of a remote machine over ssh](how-to/edit-a-remote-machine.md) | ||
| 31 | - [How to insert snippets from a menu](how-to/use-snippets.md) | 32 | - [How to insert snippets from a menu](how-to/use-snippets.md) |
| 32 | - [How to run Golo commands from the editor](how-to/run-golo-commands.md) | 33 | - [How to run Golo commands from the editor](how-to/run-golo-commands.md) |
| 33 | - [How to make a release](how-to/make-a-release.md) | 34 | - [How to make a release](how-to/make-a-release.md) |
added
docs/en/how-to/edit-a-remote-machine.md +55 -0 | new file mode 100644 | ||
| @@ -0,0 +1,55 @@ | ||
| 1 | +# How to edit the files of a remote machine over ssh | |
| 2 | + | |
| 3 | +This guide opens a project that lives on another machine — a server, a VM, a container — in Turbo Golo, so that its files, its project tree, its terminal windows and its Golo menu are that machine's. It assumes you can already `ssh` into the machine. | |
| 4 | + | |
| 5 | +## Steps | |
| 6 | + | |
| 7 | +1. Check that plain ssh works, from the terminal you will start the editor in: | |
| 8 | + | |
| 9 | + ```bash | |
| 10 | + ssh bob@build-box true | |
| 11 | + ``` | |
| 12 | + | |
| 13 | + Answer any question it asks — a new host key, a password — here first: it is the same ssh the editor runs. | |
| 14 | + | |
| 15 | +2. Start the editor with the machine and the directory: | |
| 16 | + | |
| 17 | + ```bash | |
| 18 | + turbo-golo -ssh bob@build-box:/srv/app | |
| 19 | + ``` | |
| 20 | + | |
| 21 | + It prints `Connecting to bob@build-box:/srv/app…`. If ssh needs a password or a key's passphrase it asks now, on the terminal, once. The editor then opens, and the status bar ends with `⇄ bob@build-box`. | |
| 22 | + | |
| 23 | +3. Work as usual. `F3` opens the remote files, `F9` shows the remote tree, `F2` saves to the remote machine, `F8` opens a shell there in the project directory, and the Golo menu runs `.turbo-golo/tools.toml` there, with `/bin/sh`, in the project directory. | |
| 24 | + | |
| 25 | +4. Leave with `Alt-X`. The connection is closed with the editor. | |
| 26 | + | |
| 27 | +## Variants | |
| 28 | + | |
| 29 | +- **Another directory.** `bob@build-box` alone opens bob's home; `bob@build-box:app` and `bob@build-box:~/app` open `~/app`; `bob@build-box:/srv/app` an absolute path. | |
| 30 | +- **Files to open at once.** Name them after the target, relative to the remote directory: `turbo-golo -ssh bob@build-box:/srv/app main.py`. | |
| 31 | +- **Two dashes.** `--ssh` is the same flag as `-ssh`, and `--ssh=bob@build-box` works too. | |
| 32 | +- **A port, a key, a jump host.** The target has no port syntax, as with scp. Give the machine a `Host` block in `~/.ssh/config` and use its name: | |
| 33 | + | |
| 34 | + ``` | |
| 35 | + Host build-box | |
| 36 | + HostName 192.0.2.10 | |
| 37 | + Port 2222 | |
| 38 | + User bob | |
| 39 | + IdentityFile ~/.ssh/id_build | |
| 40 | + ``` | |
| 41 | + | |
| 42 | + then `turbo-golo -ssh build-box:/srv/app`. | |
| 43 | +- **A password rather than a key.** Nothing to do: ssh asks for it before the editor opens. To force it when you have keys loaded, add `PubkeyAuthentication no` to that host's block. | |
| 44 | +- **Trying it without a server.** `turbo-editors/demo-remote-machine` is a Docker Compose machine accepting a key and a password; its README gives the exact commands. | |
| 45 | + | |
| 46 | +## What is not available over ssh | |
| 47 | + | |
| 48 | +- **Completion and diagnostics.** No language server is started — `golo lsp` would have to run on the remote machine. The status bar says `LSP: off`. | |
| 49 | +- **Agent windows.** The Agent menu says they are not available over ssh. | |
| 50 | +- **Windows** as the machine you run the editor on: its ssh has no ControlMaster. | |
| 51 | + | |
| 52 | +## See also | |
| 53 | + | |
| 54 | +- The flag and its errors: [command line](../reference/cli.md) | |
| 55 | +- The terminal windows it opens: [terminal](../reference/terminal.md) | |
| new file mode 100644 | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | +# How to edit the files of a remote machine over ssh | ||
| 2 | + | ||
| 3 | +This guide opens a project that lives on another machine — a server, a VM, a container — in Turbo Golo, so that its files, its project tree, its terminal windows and its Golo menu are that machine's. It assumes you can already `ssh` into the machine. | ||
| 4 | + | ||
| 5 | +## Steps | ||
| 6 | + | ||
| 7 | +1. Check that plain ssh works, from the terminal you will start the editor in: | ||
| 8 | + | ||
| 9 | + ```bash | ||
| 10 | + ssh bob@build-box true | ||
| 11 | + ``` | ||
| 12 | + | ||
| 13 | + Answer any question it asks — a new host key, a password — here first: it is the same ssh the editor runs. | ||
| 14 | + | ||
| 15 | +2. Start the editor with the machine and the directory: | ||
| 16 | + | ||
| 17 | + ```bash | ||
| 18 | + turbo-golo -ssh bob@build-box:/srv/app | ||
| 19 | + ``` | ||
| 20 | + | ||
| 21 | + It prints `Connecting to bob@build-box:/srv/app…`. If ssh needs a password or a key's passphrase it asks now, on the terminal, once. The editor then opens, and the status bar ends with `⇄ bob@build-box`. | ||
| 22 | + | ||
| 23 | +3. Work as usual. `F3` opens the remote files, `F9` shows the remote tree, `F2` saves to the remote machine, `F8` opens a shell there in the project directory, and the Golo menu runs `.turbo-golo/tools.toml` there, with `/bin/sh`, in the project directory. | ||
| 24 | + | ||
| 25 | +4. Leave with `Alt-X`. The connection is closed with the editor. | ||
| 26 | + | ||
| 27 | +## Variants | ||
| 28 | + | ||
| 29 | +- **Another directory.** `bob@build-box` alone opens bob's home; `bob@build-box:app` and `bob@build-box:~/app` open `~/app`; `bob@build-box:/srv/app` an absolute path. | ||
| 30 | +- **Files to open at once.** Name them after the target, relative to the remote directory: `turbo-golo -ssh bob@build-box:/srv/app main.py`. | ||
| 31 | +- **Two dashes.** `--ssh` is the same flag as `-ssh`, and `--ssh=bob@build-box` works too. | ||
| 32 | +- **A port, a key, a jump host.** The target has no port syntax, as with scp. Give the machine a `Host` block in `~/.ssh/config` and use its name: | ||
| 33 | + | ||
| 34 | + ``` | ||
| 35 | + Host build-box | ||
| 36 | + HostName 192.0.2.10 | ||
| 37 | + Port 2222 | ||
| 38 | + User bob | ||
| 39 | + IdentityFile ~/.ssh/id_build | ||
| 40 | + ``` | ||
| 41 | + | ||
| 42 | + then `turbo-golo -ssh build-box:/srv/app`. | ||
| 43 | +- **A password rather than a key.** Nothing to do: ssh asks for it before the editor opens. To force it when you have keys loaded, add `PubkeyAuthentication no` to that host's block. | ||
| 44 | +- **Trying it without a server.** `turbo-editors/demo-remote-machine` is a Docker Compose machine accepting a key and a password; its README gives the exact commands. | ||
| 45 | + | ||
| 46 | +## What is not available over ssh | ||
| 47 | + | ||
| 48 | +- **Completion and diagnostics.** No language server is started — `golo lsp` would have to run on the remote machine. The status bar says `LSP: off`. | ||
| 49 | +- **Agent windows.** The Agent menu says they are not available over ssh. | ||
| 50 | +- **Windows** as the machine you run the editor on: its ssh has no ControlMaster. | ||
| 51 | + | ||
| 52 | +## See also | ||
| 53 | + | ||
| 54 | +- The flag and its errors: [command line](../reference/cli.md) | ||
| 55 | +- The terminal windows it opens: [terminal](../reference/terminal.md) | ||
modified
docs/en/reference/cli.md +13 -1 | @@ -19,6 +19,7 @@ Each `file` is opened in its own window. A file that does not exist yet is opene | ||
| 19 | 19 | | `-no-lsp` | bool | `false` | Do not start a language server. Colouring and editing are unaffected. | |
| 20 | 20 | | `-version` | bool | `false` | Print `Turbo Golo <version>` on one line, with the commit and build date when the build recorded them, and exit. See [the version number](versioning.md). | |
| 21 | 21 | | `-load-config <url>` | string | none | Copy the `.turbo-golo` directory found at a repository URL — rickub, GitHub, GitLab or Codeberg, the URL of the directory as the browser shows it — into the working directory, print what arrived, and exit. Needs `git`. Refuses when `./.turbo-golo` already exists. The editor is not started. | |
| 22 | +| `-ssh <target>`, `--ssh <target>` | string | none | Edit the files of another machine over ssh. `<target>` is `[user@]host[:directory]`, as scp writes it; no directory means the remote home, a relative one is relative to it. Before the screen is taken, prints `Connecting to <target>…` and runs `ssh`, which asks on the terminal for a password or passphrase if it needs one. The project is then that directory: its files, tree, `.turbo-golo/` files, terminal windows and tools are the remote machine's. No language server is started, and agent windows are unavailable. Needs OpenSSH's `ssh` on `PATH`, on Linux or macOS. See [edit a remote machine](../how-to/edit-a-remote-machine.md). | | |
| 22 | 23 | | `-h`, `-help` | bool | `false` | Print the flag list and exit. | |
| 23 | 24 | |
| 24 | 25 | ## Environment |
| @@ -37,6 +38,8 @@ Each `file` is opened in its own window. A file that does not exist yet is opene | ||
| 37 | 38 | | --- | --- | |
| 38 | 39 | | `$TURBO_GOLO_THEME_DIR/*.toml` | User themes, when the variable is set. | |
| 39 | 40 | | `./.turbo-golo/settings.toml` | This project's settings, read at start-up and again when saved from the editor. See [project settings](project-settings.md). | |
| 41 | +| `<directory>/.turbo-golo/*.toml` on the remote machine | Under `-ssh`: the project's settings, snippets and tools, read and written over SFTP. | | |
| 42 | +| `~/.ssh/config` | Under `-ssh`: read by `ssh` — `Host` aliases, `Port`, `User`, `IdentityFile`, `ProxyJump`. | | |
| 40 | 43 | | `./.turbo-golo/` (written) | Created by `-load-config` from a repository's copy, when the project has none yet. | |
| 41 | 44 | | `./.turbo-golo/snippets.toml` | This project's snippets, read each time the Snippets menu opens. See [snippets](snippets.md). | |
| 42 | 45 | | `./.turbo-golo/tools.toml` | This project's tools, read each time the Golo menu opens. See [Golo tools](golo-tools.md). | |
| @@ -51,7 +54,7 @@ There is no project marker file. The language server is started in the directory | ||
| 51 | 54 | | Status | Meaning | |
| 52 | 55 | | --- | --- | |
| 53 | 56 | | `0` | The editor exited normally, or an informational flag was used. | |
| 54 | -| `1` | The terminal could not be opened or initialised. The reason is printed to standard error. | | |
| 57 | +| `1` | The terminal could not be opened or initialised, or the `-ssh` connection failed. The reason is printed to standard error. | | |
| 55 | 58 | |
| 56 | 59 | ## Make targets |
| 57 | 60 | |
| @@ -83,6 +86,8 @@ turbo-golo -theme turbo-dark main.golo # a different theme | ||
| 83 | 86 | turbo-golo -no-lsp main.golo # no language server |
| 84 | 87 | turbo-golo -list-themes # what themes exist |
| 85 | 88 | turbo-golo -load-config https://rickub.com/turbo-editors/configs/tree/main/golang-init # start from a shared configuration |
| 89 | +turbo-golo -ssh bob@build-box:/srv/app # the files of another machine, over ssh | |
| 90 | +turbo-golo --ssh demo main.py # a Host alias from ~/.ssh/config, opening main.py there | |
| 86 | 91 | ``` |
| 87 | 92 | |
| 88 | 93 | ## Installer |
| @@ -114,3 +119,10 @@ turbo-golo -load-config https://rickub.com/turbo-editors/configs/tree/main/golan | ||
| 114 | 119 | | `turbo-golo: configrepo: git is not installed` | `-load-config` needs the `git` command on `PATH`. | |
| 115 | 120 | | `turbo-golo: configrepo: no configuration directory at that path: …` | The repository was found but holds no `.turbo-golo` where the URL points. | |
| 116 | 121 | | `turbo-golo: configrepo: no repository answered: …` | No clone address for that URL answered; the URL, the network, or a private repository. | |
| 122 | +| `turbo-golo: "<arg>": not a remote target; expected user@machine or user@machine:/path` | The `-ssh` argument is empty, starts with `-`, or holds a space or `/` in the host or user. Nothing was run. | | |
| 123 | +| `turbo-golo: no ssh command found on PATH …` | `-ssh` needs the `ssh` command. | | |
| 124 | +| `turbo-golo: editing over ssh needs OpenSSH's ControlMaster, …` | `-ssh` on Windows. | | |
| 125 | +| `turbo-golo: ssh <destination>: exit status 255` | The login failed — wrong password, unknown host, refused key. ssh has printed why just above. | | |
| 126 | +| `turbo-golo: finding <dir> on the remote machine: …` | The directory after the colon does not exist there. | | |
| 127 | +| `turbo-golo: <dir> on the remote machine is not a directory: …` | The path after the colon names a file. | | |
| 128 | +| `turbo-golo: opening the file channel to <destination>: …` | The server does not offer the `sftp` subsystem. | | |
| @@ -19,6 +19,7 @@ Each `file` is opened in its own window. A file that does not exist yet is opene | |||
| 19 | | `-no-lsp` | bool | `false` | Do not start a language server. Colouring and editing are unaffected. | | 19 | | `-no-lsp` | bool | `false` | Do not start a language server. Colouring and editing are unaffected. | |
| 20 | | `-version` | bool | `false` | Print `Turbo Golo <version>` on one line, with the commit and build date when the build recorded them, and exit. See [the version number](versioning.md). | | 20 | | `-version` | bool | `false` | Print `Turbo Golo <version>` on one line, with the commit and build date when the build recorded them, and exit. See [the version number](versioning.md). | |
| 21 | | `-load-config <url>` | string | none | Copy the `.turbo-golo` directory found at a repository URL — rickub, GitHub, GitLab or Codeberg, the URL of the directory as the browser shows it — into the working directory, print what arrived, and exit. Needs `git`. Refuses when `./.turbo-golo` already exists. The editor is not started. | | 21 | | `-load-config <url>` | string | none | Copy the `.turbo-golo` directory found at a repository URL — rickub, GitHub, GitLab or Codeberg, the URL of the directory as the browser shows it — into the working directory, print what arrived, and exit. Needs `git`. Refuses when `./.turbo-golo` already exists. The editor is not started. | |
| 22 | +| `-ssh <target>`, `--ssh <target>` | string | none | Edit the files of another machine over ssh. `<target>` is `[user@]host[:directory]`, as scp writes it; no directory means the remote home, a relative one is relative to it. Before the screen is taken, prints `Connecting to <target>…` and runs `ssh`, which asks on the terminal for a password or passphrase if it needs one. The project is then that directory: its files, tree, `.turbo-golo/` files, terminal windows and tools are the remote machine's. No language server is started, and agent windows are unavailable. Needs OpenSSH's `ssh` on `PATH`, on Linux or macOS. See [edit a remote machine](../how-to/edit-a-remote-machine.md). | | ||
| 22 | | `-h`, `-help` | bool | `false` | Print the flag list and exit. | | 23 | | `-h`, `-help` | bool | `false` | Print the flag list and exit. | |
| 23 | 24 | ||
| 24 | ## Environment | 25 | ## Environment |
| @@ -37,6 +38,8 @@ Each `file` is opened in its own window. A file that does not exist yet is opene | |||
| 37 | | --- | --- | | 38 | | --- | --- | |
| 38 | | `$TURBO_GOLO_THEME_DIR/*.toml` | User themes, when the variable is set. | | 39 | | `$TURBO_GOLO_THEME_DIR/*.toml` | User themes, when the variable is set. | |
| 39 | | `./.turbo-golo/settings.toml` | This project's settings, read at start-up and again when saved from the editor. See [project settings](project-settings.md). | | 40 | | `./.turbo-golo/settings.toml` | This project's settings, read at start-up and again when saved from the editor. See [project settings](project-settings.md). | |
| 41 | +| `<directory>/.turbo-golo/*.toml` on the remote machine | Under `-ssh`: the project's settings, snippets and tools, read and written over SFTP. | | ||
| 42 | +| `~/.ssh/config` | Under `-ssh`: read by `ssh` — `Host` aliases, `Port`, `User`, `IdentityFile`, `ProxyJump`. | | ||
| 40 | | `./.turbo-golo/` (written) | Created by `-load-config` from a repository's copy, when the project has none yet. | | 43 | | `./.turbo-golo/` (written) | Created by `-load-config` from a repository's copy, when the project has none yet. | |
| 41 | | `./.turbo-golo/snippets.toml` | This project's snippets, read each time the Snippets menu opens. See [snippets](snippets.md). | | 44 | | `./.turbo-golo/snippets.toml` | This project's snippets, read each time the Snippets menu opens. See [snippets](snippets.md). | |
| 42 | | `./.turbo-golo/tools.toml` | This project's tools, read each time the Golo menu opens. See [Golo tools](golo-tools.md). | | 45 | | `./.turbo-golo/tools.toml` | This project's tools, read each time the Golo menu opens. See [Golo tools](golo-tools.md). | |
| @@ -51,7 +54,7 @@ There is no project marker file. The language server is started in the directory | |||
| 51 | | Status | Meaning | | 54 | | Status | Meaning | |
| 52 | | --- | --- | | 55 | | --- | --- | |
| 53 | | `0` | The editor exited normally, or an informational flag was used. | | 56 | | `0` | The editor exited normally, or an informational flag was used. | |
| 54 | -| `1` | The terminal could not be opened or initialised. The reason is printed to standard error. | | 57 | +| `1` | The terminal could not be opened or initialised, or the `-ssh` connection failed. The reason is printed to standard error. | |
| 55 | 58 | ||
| 56 | ## Make targets | 59 | ## Make targets |
| 57 | 60 | ||
| @@ -83,6 +86,8 @@ turbo-golo -theme turbo-dark main.golo # a different theme | |||
| 83 | turbo-golo -no-lsp main.golo # no language server | 86 | turbo-golo -no-lsp main.golo # no language server |
| 84 | turbo-golo -list-themes # what themes exist | 87 | turbo-golo -list-themes # what themes exist |
| 85 | turbo-golo -load-config https://rickub.com/turbo-editors/configs/tree/main/golang-init # start from a shared configuration | 88 | turbo-golo -load-config https://rickub.com/turbo-editors/configs/tree/main/golang-init # start from a shared configuration |
| 89 | +turbo-golo -ssh bob@build-box:/srv/app # the files of another machine, over ssh | ||
| 90 | +turbo-golo --ssh demo main.py # a Host alias from ~/.ssh/config, opening main.py there | ||
| 86 | ``` | 91 | ``` |
| 87 | 92 | ||
| 88 | ## Installer | 93 | ## Installer |
| @@ -114,3 +119,10 @@ turbo-golo -load-config https://rickub.com/turbo-editors/configs/tree/main/golan | |||
| 114 | | `turbo-golo: configrepo: git is not installed` | `-load-config` needs the `git` command on `PATH`. | | 119 | | `turbo-golo: configrepo: git is not installed` | `-load-config` needs the `git` command on `PATH`. | |
| 115 | | `turbo-golo: configrepo: no configuration directory at that path: …` | The repository was found but holds no `.turbo-golo` where the URL points. | | 120 | | `turbo-golo: configrepo: no configuration directory at that path: …` | The repository was found but holds no `.turbo-golo` where the URL points. | |
| 116 | | `turbo-golo: configrepo: no repository answered: …` | No clone address for that URL answered; the URL, the network, or a private repository. | | 121 | | `turbo-golo: configrepo: no repository answered: …` | No clone address for that URL answered; the URL, the network, or a private repository. | |
| 122 | +| `turbo-golo: "<arg>": not a remote target; expected user@machine or user@machine:/path` | The `-ssh` argument is empty, starts with `-`, or holds a space or `/` in the host or user. Nothing was run. | | ||
| 123 | +| `turbo-golo: no ssh command found on PATH …` | `-ssh` needs the `ssh` command. | | ||
| 124 | +| `turbo-golo: editing over ssh needs OpenSSH's ControlMaster, …` | `-ssh` on Windows. | | ||
| 125 | +| `turbo-golo: ssh <destination>: exit status 255` | The login failed — wrong password, unknown host, refused key. ssh has printed why just above. | | ||
| 126 | +| `turbo-golo: finding <dir> on the remote machine: …` | The directory after the colon does not exist there. | | ||
| 127 | +| `turbo-golo: <dir> on the remote machine is not a directory: …` | The path after the colon names a file. | | ||
| 128 | +| `turbo-golo: opening the file channel to <destination>: …` | The server does not offer the `sftp` subsystem. | | ||
modified
docs/fr/README.md +1 -0 | @@ -30,6 +30,7 @@ Cette documentation suit la méthode [Diátaxis](https://diataxis.fr). Quatre ty | ||
| 30 | 30 | - [Lancer des commandes shell sans quitter l'éditeur](how-to/use-a-terminal.md) |
| 31 | 31 | - [Donner ses propres réglages à un projet](how-to/configure-a-project.md) |
| 32 | 32 | - [Parcourir un projet et ouvrir des fichiers depuis un arbre](how-to/browse-a-project.md) |
| 33 | +- [Éditer les fichiers d'une machine distante via ssh](how-to/edit-a-remote-machine.md) | |
| 33 | 34 | - [Insérer des snippets depuis un menu](how-to/use-snippets.md) |
| 34 | 35 | - [Lancer les commandes golo depuis l'éditeur](how-to/run-golo-commands.md) |
| 35 | 36 | - [Faire une release](how-to/make-a-release.md) |
| @@ -30,6 +30,7 @@ Cette documentation suit la méthode [Diátaxis](https://diataxis.fr). Quatre ty | |||
| 30 | - [Lancer des commandes shell sans quitter l'éditeur](how-to/use-a-terminal.md) | 30 | - [Lancer des commandes shell sans quitter l'éditeur](how-to/use-a-terminal.md) |
| 31 | - [Donner ses propres réglages à un projet](how-to/configure-a-project.md) | 31 | - [Donner ses propres réglages à un projet](how-to/configure-a-project.md) |
| 32 | - [Parcourir un projet et ouvrir des fichiers depuis un arbre](how-to/browse-a-project.md) | 32 | - [Parcourir un projet et ouvrir des fichiers depuis un arbre](how-to/browse-a-project.md) |
| 33 | +- [Éditer les fichiers d'une machine distante via ssh](how-to/edit-a-remote-machine.md) | ||
| 33 | - [Insérer des snippets depuis un menu](how-to/use-snippets.md) | 34 | - [Insérer des snippets depuis un menu](how-to/use-snippets.md) |
| 34 | - [Lancer les commandes golo depuis l'éditeur](how-to/run-golo-commands.md) | 35 | - [Lancer les commandes golo depuis l'éditeur](how-to/run-golo-commands.md) |
| 35 | - [Faire une release](how-to/make-a-release.md) | 36 | - [Faire une release](how-to/make-a-release.md) |
added
docs/fr/how-to/edit-a-remote-machine.md +55 -0 | new file mode 100644 | ||
| @@ -0,0 +1,55 @@ | ||
| 1 | +# Éditer les fichiers d'une machine distante via ssh | |
| 2 | + | |
| 3 | +Ce guide ouvre dans Turbo Golo un projet qui vit sur une autre machine — un serveur, une VM, un conteneur — de sorte que ses fichiers, son arborescence, ses fenêtres terminal et son menu Golo soient ceux de cette machine. Il suppose que vous savez déjà vous connecter à la machine avec `ssh`. | |
| 4 | + | |
| 5 | +## Étapes | |
| 6 | + | |
| 7 | +1. Vérifiez que ssh fonctionne tout seul, depuis le terminal où vous lancerez l'éditeur : | |
| 8 | + | |
| 9 | + ```bash | |
| 10 | + ssh bob@build-box true | |
| 11 | + ``` | |
| 12 | + | |
| 13 | + Répondez ici d'abord à toute question qu'il pose — nouvelle clé d'hôte, mot de passe : c'est le même ssh que lance l'éditeur. | |
| 14 | + | |
| 15 | +2. Lancez l'éditeur avec la machine et le répertoire : | |
| 16 | + | |
| 17 | + ```bash | |
| 18 | + turbo-golo -ssh bob@build-box:/srv/app | |
| 19 | + ``` | |
| 20 | + | |
| 21 | + Il affiche `Connecting to bob@build-box:/srv/app…`. Si ssh a besoin d'un mot de passe ou de la passphrase d'une clé, il la demande maintenant, sur le terminal, une seule fois. L'éditeur s'ouvre ensuite, et la barre d'état se termine par `⇄ bob@build-box`. | |
| 22 | + | |
| 23 | +3. Travaillez comme d'habitude. `F3` ouvre les fichiers distants, `F9` montre l'arborescence distante, `F2` enregistre sur la machine distante, `F8` y ouvre un shell dans le répertoire du projet, et le menu Golo y lance `.turbo-golo/tools.toml`, avec `/bin/sh`, dans le répertoire du projet. | |
| 24 | + | |
| 25 | +4. Quittez avec `Alt-X`. La connexion se ferme avec l'éditeur. | |
| 26 | + | |
| 27 | +## Variantes | |
| 28 | + | |
| 29 | +- **Un autre répertoire.** `bob@build-box` seul ouvre le home de bob ; `bob@build-box:app` et `bob@build-box:~/app` ouvrent `~/app` ; `bob@build-box:/srv/app` un chemin absolu. | |
| 30 | +- **Des fichiers à ouvrir d'emblée.** Nommez-les après la cible, relativement au répertoire distant : `turbo-golo -ssh bob@build-box:/srv/app main.py`. | |
| 31 | +- **Deux tirets.** `--ssh` est la même option que `-ssh`, et `--ssh=bob@build-box` fonctionne aussi. | |
| 32 | +- **Un port, une clé, un rebond.** La cible n'a pas de syntaxe de port, comme avec scp. Donnez à la machine un bloc `Host` dans `~/.ssh/config` et utilisez son nom : | |
| 33 | + | |
| 34 | + ``` | |
| 35 | + Host build-box | |
| 36 | + HostName 192.0.2.10 | |
| 37 | + Port 2222 | |
| 38 | + User bob | |
| 39 | + IdentityFile ~/.ssh/id_build | |
| 40 | + ``` | |
| 41 | + | |
| 42 | + puis `turbo-golo -ssh build-box:/srv/app`. | |
| 43 | +- **Un mot de passe plutôt qu'une clé.** Rien à faire : ssh le demande avant l'ouverture de l'éditeur. Pour l'imposer alors que des clés sont chargées, ajoutez `PubkeyAuthentication no` au bloc de cet hôte. | |
| 44 | +- **Essayer sans serveur.** `turbo-editors/demo-remote-machine` est une machine Docker Compose qui accepte une clé et un mot de passe ; son README donne les commandes exactes. | |
| 45 | + | |
| 46 | +## Ce qui n'est pas disponible via ssh | |
| 47 | + | |
| 48 | +- **La complétion et les diagnostics.** Aucun serveur de langage n'est lancé — `golo lsp` devrait tourner sur la machine distante. La barre d'état indique `LSP: off`. | |
| 49 | +- **Les fenêtres d'agent.** Le menu Agent indique qu'elles ne sont pas disponibles via ssh. | |
| 50 | +- **Windows** comme machine où tourne l'éditeur : son ssh n'a pas de ControlMaster. | |
| 51 | + | |
| 52 | +## Voir aussi | |
| 53 | + | |
| 54 | +- L'option et ses erreurs : [ligne de commande](../reference/cli.md) | |
| 55 | +- Les fenêtres terminal qu'il ouvre : [terminal](../reference/terminal.md) | |
| new file mode 100644 | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | +# Éditer les fichiers d'une machine distante via ssh | ||
| 2 | + | ||
| 3 | +Ce guide ouvre dans Turbo Golo un projet qui vit sur une autre machine — un serveur, une VM, un conteneur — de sorte que ses fichiers, son arborescence, ses fenêtres terminal et son menu Golo soient ceux de cette machine. Il suppose que vous savez déjà vous connecter à la machine avec `ssh`. | ||
| 4 | + | ||
| 5 | +## Étapes | ||
| 6 | + | ||
| 7 | +1. Vérifiez que ssh fonctionne tout seul, depuis le terminal où vous lancerez l'éditeur : | ||
| 8 | + | ||
| 9 | + ```bash | ||
| 10 | + ssh bob@build-box true | ||
| 11 | + ``` | ||
| 12 | + | ||
| 13 | + Répondez ici d'abord à toute question qu'il pose — nouvelle clé d'hôte, mot de passe : c'est le même ssh que lance l'éditeur. | ||
| 14 | + | ||
| 15 | +2. Lancez l'éditeur avec la machine et le répertoire : | ||
| 16 | + | ||
| 17 | + ```bash | ||
| 18 | + turbo-golo -ssh bob@build-box:/srv/app | ||
| 19 | + ``` | ||
| 20 | + | ||
| 21 | + Il affiche `Connecting to bob@build-box:/srv/app…`. Si ssh a besoin d'un mot de passe ou de la passphrase d'une clé, il la demande maintenant, sur le terminal, une seule fois. L'éditeur s'ouvre ensuite, et la barre d'état se termine par `⇄ bob@build-box`. | ||
| 22 | + | ||
| 23 | +3. Travaillez comme d'habitude. `F3` ouvre les fichiers distants, `F9` montre l'arborescence distante, `F2` enregistre sur la machine distante, `F8` y ouvre un shell dans le répertoire du projet, et le menu Golo y lance `.turbo-golo/tools.toml`, avec `/bin/sh`, dans le répertoire du projet. | ||
| 24 | + | ||
| 25 | +4. Quittez avec `Alt-X`. La connexion se ferme avec l'éditeur. | ||
| 26 | + | ||
| 27 | +## Variantes | ||
| 28 | + | ||
| 29 | +- **Un autre répertoire.** `bob@build-box` seul ouvre le home de bob ; `bob@build-box:app` et `bob@build-box:~/app` ouvrent `~/app` ; `bob@build-box:/srv/app` un chemin absolu. | ||
| 30 | +- **Des fichiers à ouvrir d'emblée.** Nommez-les après la cible, relativement au répertoire distant : `turbo-golo -ssh bob@build-box:/srv/app main.py`. | ||
| 31 | +- **Deux tirets.** `--ssh` est la même option que `-ssh`, et `--ssh=bob@build-box` fonctionne aussi. | ||
| 32 | +- **Un port, une clé, un rebond.** La cible n'a pas de syntaxe de port, comme avec scp. Donnez à la machine un bloc `Host` dans `~/.ssh/config` et utilisez son nom : | ||
| 33 | + | ||
| 34 | + ``` | ||
| 35 | + Host build-box | ||
| 36 | + HostName 192.0.2.10 | ||
| 37 | + Port 2222 | ||
| 38 | + User bob | ||
| 39 | + IdentityFile ~/.ssh/id_build | ||
| 40 | + ``` | ||
| 41 | + | ||
| 42 | + puis `turbo-golo -ssh build-box:/srv/app`. | ||
| 43 | +- **Un mot de passe plutôt qu'une clé.** Rien à faire : ssh le demande avant l'ouverture de l'éditeur. Pour l'imposer alors que des clés sont chargées, ajoutez `PubkeyAuthentication no` au bloc de cet hôte. | ||
| 44 | +- **Essayer sans serveur.** `turbo-editors/demo-remote-machine` est une machine Docker Compose qui accepte une clé et un mot de passe ; son README donne les commandes exactes. | ||
| 45 | + | ||
| 46 | +## Ce qui n'est pas disponible via ssh | ||
| 47 | + | ||
| 48 | +- **La complétion et les diagnostics.** Aucun serveur de langage n'est lancé — `golo lsp` devrait tourner sur la machine distante. La barre d'état indique `LSP: off`. | ||
| 49 | +- **Les fenêtres d'agent.** Le menu Agent indique qu'elles ne sont pas disponibles via ssh. | ||
| 50 | +- **Windows** comme machine où tourne l'éditeur : son ssh n'a pas de ControlMaster. | ||
| 51 | + | ||
| 52 | +## Voir aussi | ||
| 53 | + | ||
| 54 | +- L'option et ses erreurs : [ligne de commande](../reference/cli.md) | ||
| 55 | +- Les fenêtres terminal qu'il ouvre : [terminal](../reference/terminal.md) | ||
modified
docs/fr/reference/cli.md +13 -1 | @@ -19,6 +19,7 @@ Chaque `fichier` est ouvert dans sa propre fenêtre. Un fichier qui n'existe pas | ||
| 19 | 19 | | `-no-lsp` | booléen | `false` | Ne démarre pas de serveur de langage. La coloration et l'édition sont inchangées. | |
| 20 | 20 | | `-version` | booléen | `false` | Affiche `Turbo Golo <version>` sur une ligne, avec le commit et la date de build quand le build les a enregistrés, puis quitte. Voir [le numéro de version](versioning.md). | |
| 21 | 21 | | `-load-config <url>` | chaîne | aucune | Copie le répertoire `.turbo-golo` trouvé à l'URL d'un dépôt — rickub, GitHub, GitLab ou Codeberg, l'URL du dossier telle que le navigateur l'affiche — dans le répertoire courant, affiche ce qui est arrivé, et quitte. Nécessite `git`. Refuse si `./.turbo-golo` existe déjà. L'éditeur n'est pas lancé. | |
| 22 | +| `-ssh <cible>`, `--ssh <cible>` | chaîne | aucune | Édite les fichiers d'une autre machine via ssh. `<cible>` s'écrit `[user@]hôte[:répertoire]`, comme avec scp ; sans répertoire, c'est le home distant, et un répertoire relatif est relatif à lui. Avant de prendre l'écran, affiche `Connecting to <cible>…` et lance `ssh`, qui demande sur le terminal un mot de passe ou une passphrase s'il en a besoin. Le projet est alors ce répertoire : ses fichiers, son arborescence, ses fichiers `.turbo-golo/`, les fenêtres terminal et les outils sont ceux de la machine distante. Aucun serveur de langage n'est lancé, et les fenêtres d'agent sont indisponibles. Nécessite le `ssh` d'OpenSSH dans le `PATH`, sous Linux ou macOS. Voir [éditer une machine distante](../how-to/edit-a-remote-machine.md). | | |
| 22 | 23 | | `-h`, `-help` | booléen | `false` | Affiche la liste des options et quitte. | |
| 23 | 24 | |
| 24 | 25 | ## Environnement |
| @@ -37,6 +38,8 @@ Chaque `fichier` est ouvert dans sa propre fenêtre. Un fichier qui n'existe pas | ||
| 37 | 38 | | Chemin | Rôle | |
| 38 | 39 | | --- | --- | |
| 39 | 40 | | `./.turbo-golo/settings.toml` | Les réglages de ce projet, lus au démarrage puis à chaque enregistrement. Voir [réglages de projet](project-settings.md). | |
| 41 | +| `<répertoire>/.turbo-golo/*.toml` sur la machine distante | Avec `-ssh` : les réglages, extraits et outils du projet, lus et écrits en SFTP. | | |
| 42 | +| `~/.ssh/config` | Avec `-ssh` : lu par `ssh` — alias `Host`, `Port`, `User`, `IdentityFile`, `ProxyJump`. | | |
| 40 | 43 | | `./.turbo-golo/` (écrit) | Créé par `-load-config` à partir de la copie d'un dépôt, quand le projet n'en a pas encore. | |
| 41 | 44 | | `./.turbo-golo/snippets.toml` | Les snippets de ce projet. Voir [snippets](snippets.md). | |
| 42 | 45 | | `./.turbo-golo/tools.toml` | Les outils du menu Golo. Voir [outils Golo](golo-tools.md). | |
| @@ -53,7 +56,7 @@ Le serveur de langage reçoit comme racine le dossier du premier fichier nommé | ||
| 53 | 56 | | Code | Signification | |
| 54 | 57 | | --- | --- | |
| 55 | 58 | | `0` | L'éditeur s'est terminé normalement, ou une option d'information a été utilisée. | |
| 56 | -| `1` | Le terminal n'a pas pu être ouvert ou initialisé. La raison est écrite sur la sortie d'erreur. | | |
| 59 | +| `1` | Le terminal n'a pas pu être ouvert ou initialisé, ou la connexion `-ssh` a échoué. La raison est écrite sur la sortie d'erreur. | | |
| 57 | 60 | |
| 58 | 61 | ## Cibles make |
| 59 | 62 | |
| @@ -85,6 +88,8 @@ turbo-golo -theme turbo-dark main.golo # un autre thème | ||
| 85 | 88 | turbo-golo -no-lsp main.golo # sans serveur de langage |
| 86 | 89 | turbo-golo -list-themes # quels thèmes existent |
| 87 | 90 | turbo-golo -load-config https://rickub.com/turbo-editors/configs/tree/main/golang-init # partir d'une configuration partagée |
| 91 | +turbo-golo -ssh bob@build-box:/srv/app # les fichiers d'une autre machine, via ssh | |
| 92 | +turbo-golo --ssh demo main.py # un alias Host de ~/.ssh/config, en y ouvrant main.py | |
| 88 | 93 | ``` |
| 89 | 94 | |
| 90 | 95 | ## Installateur |
| @@ -115,3 +120,10 @@ turbo-golo -load-config https://rickub.com/turbo-editors/configs/tree/main/golan | ||
| 115 | 120 | | `turbo-golo: configrepo: git is not installed` | `-load-config` a besoin de la commande `git` dans le `PATH`. | |
| 116 | 121 | | `turbo-golo: configrepo: no configuration directory at that path: …` | Le dépôt existe mais ne contient pas de `.turbo-golo` là où l'URL pointe. | |
| 117 | 122 | | `turbo-golo: configrepo: no repository answered: …` | Aucune adresse de clone pour cette URL n'a répondu : l'URL, le réseau, ou un dépôt privé. | |
| 123 | +| `turbo-golo: "<arg>": not a remote target; expected user@machine or user@machine:/path` | L'argument de `-ssh` est vide, commence par `-`, ou contient une espace ou un `/` dans l'hôte ou l'utilisateur. Rien n'a été lancé. | | |
| 124 | +| `turbo-golo: no ssh command found on PATH …` | `-ssh` a besoin de la commande `ssh`. | | |
| 125 | +| `turbo-golo: editing over ssh needs OpenSSH's ControlMaster, …` | `-ssh` sous Windows. | | |
| 126 | +| `turbo-golo: ssh <destination>: exit status 255` | La connexion a échoué — mauvais mot de passe, hôte inconnu, clé refusée. ssh a écrit pourquoi juste au-dessus. | | |
| 127 | +| `turbo-golo: finding <dir> on the remote machine: …` | Le répertoire après les deux-points n'existe pas là-bas. | | |
| 128 | +| `turbo-golo: <dir> on the remote machine is not a directory: …` | Le chemin après les deux-points désigne un fichier. | | |
| 129 | +| `turbo-golo: opening the file channel to <destination>: …` | Le serveur ne propose pas le sous-système `sftp`. | | |
| @@ -19,6 +19,7 @@ Chaque `fichier` est ouvert dans sa propre fenêtre. Un fichier qui n'existe pas | |||
| 19 | | `-no-lsp` | booléen | `false` | Ne démarre pas de serveur de langage. La coloration et l'édition sont inchangées. | | 19 | | `-no-lsp` | booléen | `false` | Ne démarre pas de serveur de langage. La coloration et l'édition sont inchangées. | |
| 20 | | `-version` | booléen | `false` | Affiche `Turbo Golo <version>` sur une ligne, avec le commit et la date de build quand le build les a enregistrés, puis quitte. Voir [le numéro de version](versioning.md). | | 20 | | `-version` | booléen | `false` | Affiche `Turbo Golo <version>` sur une ligne, avec le commit et la date de build quand le build les a enregistrés, puis quitte. Voir [le numéro de version](versioning.md). | |
| 21 | | `-load-config <url>` | chaîne | aucune | Copie le répertoire `.turbo-golo` trouvé à l'URL d'un dépôt — rickub, GitHub, GitLab ou Codeberg, l'URL du dossier telle que le navigateur l'affiche — dans le répertoire courant, affiche ce qui est arrivé, et quitte. Nécessite `git`. Refuse si `./.turbo-golo` existe déjà. L'éditeur n'est pas lancé. | | 21 | | `-load-config <url>` | chaîne | aucune | Copie le répertoire `.turbo-golo` trouvé à l'URL d'un dépôt — rickub, GitHub, GitLab ou Codeberg, l'URL du dossier telle que le navigateur l'affiche — dans le répertoire courant, affiche ce qui est arrivé, et quitte. Nécessite `git`. Refuse si `./.turbo-golo` existe déjà. L'éditeur n'est pas lancé. | |
| 22 | +| `-ssh <cible>`, `--ssh <cible>` | chaîne | aucune | Édite les fichiers d'une autre machine via ssh. `<cible>` s'écrit `[user@]hôte[:répertoire]`, comme avec scp ; sans répertoire, c'est le home distant, et un répertoire relatif est relatif à lui. Avant de prendre l'écran, affiche `Connecting to <cible>…` et lance `ssh`, qui demande sur le terminal un mot de passe ou une passphrase s'il en a besoin. Le projet est alors ce répertoire : ses fichiers, son arborescence, ses fichiers `.turbo-golo/`, les fenêtres terminal et les outils sont ceux de la machine distante. Aucun serveur de langage n'est lancé, et les fenêtres d'agent sont indisponibles. Nécessite le `ssh` d'OpenSSH dans le `PATH`, sous Linux ou macOS. Voir [éditer une machine distante](../how-to/edit-a-remote-machine.md). | | ||
| 22 | | `-h`, `-help` | booléen | `false` | Affiche la liste des options et quitte. | | 23 | | `-h`, `-help` | booléen | `false` | Affiche la liste des options et quitte. | |
| 23 | 24 | ||
| 24 | ## Environnement | 25 | ## Environnement |
| @@ -37,6 +38,8 @@ Chaque `fichier` est ouvert dans sa propre fenêtre. Un fichier qui n'existe pas | |||
| 37 | | Chemin | Rôle | | 38 | | Chemin | Rôle | |
| 38 | | --- | --- | | 39 | | --- | --- | |
| 39 | | `./.turbo-golo/settings.toml` | Les réglages de ce projet, lus au démarrage puis à chaque enregistrement. Voir [réglages de projet](project-settings.md). | | 40 | | `./.turbo-golo/settings.toml` | Les réglages de ce projet, lus au démarrage puis à chaque enregistrement. Voir [réglages de projet](project-settings.md). | |
| 41 | +| `<répertoire>/.turbo-golo/*.toml` sur la machine distante | Avec `-ssh` : les réglages, extraits et outils du projet, lus et écrits en SFTP. | | ||
| 42 | +| `~/.ssh/config` | Avec `-ssh` : lu par `ssh` — alias `Host`, `Port`, `User`, `IdentityFile`, `ProxyJump`. | | ||
| 40 | | `./.turbo-golo/` (écrit) | Créé par `-load-config` à partir de la copie d'un dépôt, quand le projet n'en a pas encore. | | 43 | | `./.turbo-golo/` (écrit) | Créé par `-load-config` à partir de la copie d'un dépôt, quand le projet n'en a pas encore. | |
| 41 | | `./.turbo-golo/snippets.toml` | Les snippets de ce projet. Voir [snippets](snippets.md). | | 44 | | `./.turbo-golo/snippets.toml` | Les snippets de ce projet. Voir [snippets](snippets.md). | |
| 42 | | `./.turbo-golo/tools.toml` | Les outils du menu Golo. Voir [outils Golo](golo-tools.md). | | 45 | | `./.turbo-golo/tools.toml` | Les outils du menu Golo. Voir [outils Golo](golo-tools.md). | |
| @@ -53,7 +56,7 @@ Le serveur de langage reçoit comme racine le dossier du premier fichier nommé | |||
| 53 | | Code | Signification | | 56 | | Code | Signification | |
| 54 | | --- | --- | | 57 | | --- | --- | |
| 55 | | `0` | L'éditeur s'est terminé normalement, ou une option d'information a été utilisée. | | 58 | | `0` | L'éditeur s'est terminé normalement, ou une option d'information a été utilisée. | |
| 56 | -| `1` | Le terminal n'a pas pu être ouvert ou initialisé. La raison est écrite sur la sortie d'erreur. | | 59 | +| `1` | Le terminal n'a pas pu être ouvert ou initialisé, ou la connexion `-ssh` a échoué. La raison est écrite sur la sortie d'erreur. | |
| 57 | 60 | ||
| 58 | ## Cibles make | 61 | ## Cibles make |
| 59 | 62 | ||
| @@ -85,6 +88,8 @@ turbo-golo -theme turbo-dark main.golo # un autre thème | |||
| 85 | turbo-golo -no-lsp main.golo # sans serveur de langage | 88 | turbo-golo -no-lsp main.golo # sans serveur de langage |
| 86 | turbo-golo -list-themes # quels thèmes existent | 89 | turbo-golo -list-themes # quels thèmes existent |
| 87 | turbo-golo -load-config https://rickub.com/turbo-editors/configs/tree/main/golang-init # partir d'une configuration partagée | 90 | turbo-golo -load-config https://rickub.com/turbo-editors/configs/tree/main/golang-init # partir d'une configuration partagée |
| 91 | +turbo-golo -ssh bob@build-box:/srv/app # les fichiers d'une autre machine, via ssh | ||
| 92 | +turbo-golo --ssh demo main.py # un alias Host de ~/.ssh/config, en y ouvrant main.py | ||
| 88 | ``` | 93 | ``` |
| 89 | 94 | ||
| 90 | ## Installateur | 95 | ## Installateur |
| @@ -115,3 +120,10 @@ turbo-golo -load-config https://rickub.com/turbo-editors/configs/tree/main/golan | |||
| 115 | | `turbo-golo: configrepo: git is not installed` | `-load-config` a besoin de la commande `git` dans le `PATH`. | | 120 | | `turbo-golo: configrepo: git is not installed` | `-load-config` a besoin de la commande `git` dans le `PATH`. | |
| 116 | | `turbo-golo: configrepo: no configuration directory at that path: …` | Le dépôt existe mais ne contient pas de `.turbo-golo` là où l'URL pointe. | | 121 | | `turbo-golo: configrepo: no configuration directory at that path: …` | Le dépôt existe mais ne contient pas de `.turbo-golo` là où l'URL pointe. | |
| 117 | | `turbo-golo: configrepo: no repository answered: …` | Aucune adresse de clone pour cette URL n'a répondu : l'URL, le réseau, ou un dépôt privé. | | 122 | | `turbo-golo: configrepo: no repository answered: …` | Aucune adresse de clone pour cette URL n'a répondu : l'URL, le réseau, ou un dépôt privé. | |
| 123 | +| `turbo-golo: "<arg>": not a remote target; expected user@machine or user@machine:/path` | L'argument de `-ssh` est vide, commence par `-`, ou contient une espace ou un `/` dans l'hôte ou l'utilisateur. Rien n'a été lancé. | | ||
| 124 | +| `turbo-golo: no ssh command found on PATH …` | `-ssh` a besoin de la commande `ssh`. | | ||
| 125 | +| `turbo-golo: editing over ssh needs OpenSSH's ControlMaster, …` | `-ssh` sous Windows. | | ||
| 126 | +| `turbo-golo: ssh <destination>: exit status 255` | La connexion a échoué — mauvais mot de passe, hôte inconnu, clé refusée. ssh a écrit pourquoi juste au-dessus. | | ||
| 127 | +| `turbo-golo: finding <dir> on the remote machine: …` | Le répertoire après les deux-points n'existe pas là-bas. | | ||
| 128 | +| `turbo-golo: <dir> on the remote machine is not a directory: …` | Le chemin après les deux-points désigne un fichier. | | ||
| 129 | +| `turbo-golo: opening the file channel to <destination>: …` | Le serveur ne propose pas le sous-système `sftp`. | | ||
modified
go.mod +7 -4 | @@ -4,17 +4,20 @@ go 1.26.1 | ||
| 4 | 4 | |
| 5 | 5 | require ( |
| 6 | 6 | github.com/gdamore/tcell/v2 v2.13.10 |
| 7 | - rickub.com/turbo-editors/turbo-core v1.0.4 | |
| 7 | + rickub.com/turbo-editors/turbo-core v1.0.5 | |
| 8 | 8 | ) |
| 9 | 9 | |
| 10 | 10 | require ( |
| 11 | 11 | github.com/BurntSushi/toml v1.6.0 // indirect |
| 12 | 12 | github.com/gdamore/encoding v1.0.1 // indirect |
| 13 | + github.com/kr/fs v0.1.0 // indirect | |
| 13 | 14 | github.com/lucasb-eyer/go-colorful v1.3.0 // indirect |
| 15 | + github.com/pkg/sftp v1.13.11 // indirect | |
| 14 | 16 | github.com/rivo/uniseg v0.4.7 // indirect |
| 15 | - golang.org/x/sys v0.38.0 // indirect | |
| 16 | - golang.org/x/term v0.37.0 // indirect | |
| 17 | - golang.org/x/text v0.31.0 // indirect | |
| 17 | + golang.org/x/crypto v0.54.0 // indirect | |
| 18 | + golang.org/x/sys v0.47.0 // indirect | |
| 19 | + golang.org/x/term v0.45.0 // indirect | |
| 20 | + golang.org/x/text v0.40.0 // indirect | |
| 18 | 21 | ) |
| 19 | 22 | |
| 20 | 23 | // turbo-core is developed alongside the editors that use it. Point this at the |
| @@ -4,17 +4,20 @@ go 1.26.1 | |||
| 4 | 4 | ||
| 5 | require ( | 5 | require ( |
| 6 | github.com/gdamore/tcell/v2 v2.13.10 | 6 | github.com/gdamore/tcell/v2 v2.13.10 |
| 7 | - rickub.com/turbo-editors/turbo-core v1.0.4 | 7 | + rickub.com/turbo-editors/turbo-core v1.0.5 |
| 8 | ) | 8 | ) |
| 9 | 9 | ||
| 10 | require ( | 10 | require ( |
| 11 | github.com/BurntSushi/toml v1.6.0 // indirect | 11 | github.com/BurntSushi/toml v1.6.0 // indirect |
| 12 | github.com/gdamore/encoding v1.0.1 // indirect | 12 | github.com/gdamore/encoding v1.0.1 // indirect |
| 13 | + github.com/kr/fs v0.1.0 // indirect | ||
| 13 | github.com/lucasb-eyer/go-colorful v1.3.0 // indirect | 14 | github.com/lucasb-eyer/go-colorful v1.3.0 // indirect |
| 15 | + github.com/pkg/sftp v1.13.11 // indirect | ||
| 14 | github.com/rivo/uniseg v0.4.7 // indirect | 16 | github.com/rivo/uniseg v0.4.7 // indirect |
| 15 | - golang.org/x/sys v0.38.0 // indirect | 17 | + golang.org/x/crypto v0.54.0 // indirect |
| 16 | - golang.org/x/term v0.37.0 // indirect | 18 | + golang.org/x/sys v0.47.0 // indirect |
| 17 | - golang.org/x/text v0.31.0 // indirect | 19 | + golang.org/x/term v0.45.0 // indirect |
| 20 | + golang.org/x/text v0.40.0 // indirect | ||
| 18 | ) | 21 | ) |
| 19 | 22 | ||
| 20 | // turbo-core is developed alongside the editors that use it. Point this at the | 23 | // turbo-core is developed alongside the editors that use it. Point this at the |
modified
go.sum +22 -8 | @@ -1,16 +1,28 @@ | ||
| 1 | 1 | github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= |
| 2 | 2 | github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= |
| 3 | +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | |
| 4 | +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | |
| 3 | 5 | github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw= |
| 4 | 6 | github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo= |
| 5 | 7 | github.com/gdamore/tcell/v2 v2.13.10 h1:Afs3JKt83HnhuUKdZ3MnxUgOqQRWftj5JyDqv1LLynA= |
| 6 | 8 | github.com/gdamore/tcell/v2 v2.13.10/go.mod h1:+Wfe208WDdB7INEtCsNrAN6O2m+wsTPk1RAovjaILlo= |
| 9 | +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= | |
| 10 | +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= | |
| 7 | 11 | github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= |
| 8 | 12 | github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= |
| 13 | +github.com/pkg/sftp v1.13.11 h1:0N92SLTB8JqASJB14ZLHHzFnBV8mG9zw4K7jghEFWuE= | |
| 14 | +github.com/pkg/sftp v1.13.11/go.mod h1:uNkH9roSXglNJqM+glJJi+TQXQUm0fXFWqCFmT8hsN0= | |
| 15 | +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | |
| 16 | +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | |
| 9 | 17 | github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= |
| 10 | 18 | github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= |
| 19 | +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= | |
| 20 | +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= | |
| 11 | 21 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= |
| 12 | 22 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= |
| 13 | 23 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= |
| 24 | +golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= | |
| 25 | +golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= | |
| 14 | 26 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= |
| 15 | 27 | golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= |
| 16 | 28 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= |
| @@ -26,24 +38,26 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc | ||
| 26 | 38 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
| 27 | 39 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
| 28 | 40 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
| 29 | -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= | |
| 30 | -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= | |
| 41 | +golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= | |
| 42 | +golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= | |
| 31 | 43 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= |
| 32 | 44 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= |
| 33 | 45 | golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= |
| 34 | -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= | |
| 35 | -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= | |
| 46 | +golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= | |
| 47 | +golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= | |
| 36 | 48 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= |
| 37 | 49 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= |
| 38 | 50 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= |
| 39 | 51 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= |
| 40 | 52 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= |
| 41 | -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= | |
| 42 | -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= | |
| 53 | +golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= | |
| 54 | +golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= | |
| 43 | 55 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= |
| 44 | 56 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= |
| 45 | 57 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= |
| 46 | 58 | golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= |
| 47 | 59 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
| 48 | -rickub.com/turbo-editors/turbo-core v1.0.4 h1:oxySn9S6aEoHC1HPrarkxCnW5fTcPPXym7dMjSLRKaY= | |
| 49 | -rickub.com/turbo-editors/turbo-core v1.0.4/go.mod h1:rmfIY5gsFEo3sC5IIJFapwsGvdKG6NjrD7ACmnNTKq8= | |
| 60 | +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | |
| 61 | +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | |
| 62 | +rickub.com/turbo-editors/turbo-core v1.0.5 h1:1CDKkW+xJpmNM8ab7KSMorXgYMsX5BTGaz0JgkxSO3E= | |
| 63 | +rickub.com/turbo-editors/turbo-core v1.0.5/go.mod h1:M+f/mLHiWhqQCIRr88JSPJ6nxY2ALkEhDUuTkXi79dM= | |
| @@ -1,16 +1,28 @@ | |||
| 1 | github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= | 1 | github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= |
| 2 | github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= | 2 | github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= |
| 3 | +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
| 4 | +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
| 3 | github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw= | 5 | github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw= |
| 4 | github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo= | 6 | github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo= |
| 5 | github.com/gdamore/tcell/v2 v2.13.10 h1:Afs3JKt83HnhuUKdZ3MnxUgOqQRWftj5JyDqv1LLynA= | 7 | github.com/gdamore/tcell/v2 v2.13.10 h1:Afs3JKt83HnhuUKdZ3MnxUgOqQRWftj5JyDqv1LLynA= |
| 6 | github.com/gdamore/tcell/v2 v2.13.10/go.mod h1:+Wfe208WDdB7INEtCsNrAN6O2m+wsTPk1RAovjaILlo= | 8 | github.com/gdamore/tcell/v2 v2.13.10/go.mod h1:+Wfe208WDdB7INEtCsNrAN6O2m+wsTPk1RAovjaILlo= |
| 9 | +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= | ||
| 10 | +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= | ||
| 7 | github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= | 11 | github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= |
| 8 | github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= | 12 | github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= |
| 13 | +github.com/pkg/sftp v1.13.11 h1:0N92SLTB8JqASJB14ZLHHzFnBV8mG9zw4K7jghEFWuE= | ||
| 14 | +github.com/pkg/sftp v1.13.11/go.mod h1:uNkH9roSXglNJqM+glJJi+TQXQUm0fXFWqCFmT8hsN0= | ||
| 15 | +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
| 16 | +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
| 9 | github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= | 17 | github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= |
| 10 | github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= | 18 | github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= |
| 19 | +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= | ||
| 20 | +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= | ||
| 11 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= | 21 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= |
| 12 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | 22 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= |
| 13 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= | 23 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= |
| 24 | +golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= | ||
| 25 | +golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= | ||
| 14 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= | 26 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= |
| 15 | golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= | 27 | golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= |
| 16 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | 28 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= |
| @@ -26,24 +38,26 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc | |||
| 26 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | 38 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
| 27 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | 39 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
| 28 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | 40 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
| 29 | -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= | 41 | +golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= |
| 30 | -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= | 42 | +golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= |
| 31 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | 43 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= |
| 32 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= | 44 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= |
| 33 | golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= | 45 | golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= |
| 34 | -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= | 46 | +golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= |
| 35 | -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= | 47 | +golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= |
| 36 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | 48 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= |
| 37 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | 49 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= |
| 38 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= | 50 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= |
| 39 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= | 51 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= |
| 40 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= | 52 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= |
| 41 | -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= | 53 | +golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= |
| 42 | -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= | 54 | +golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= |
| 43 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | 55 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= |
| 44 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | 56 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= |
| 45 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= | 57 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= |
| 46 | golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= | 58 | golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= |
| 47 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | 59 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
| 48 | -rickub.com/turbo-editors/turbo-core v1.0.4 h1:oxySn9S6aEoHC1HPrarkxCnW5fTcPPXym7dMjSLRKaY= | 60 | +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= |
| 49 | -rickub.com/turbo-editors/turbo-core v1.0.4/go.mod h1:rmfIY5gsFEo3sC5IIJFapwsGvdKG6NjrD7ACmnNTKq8= | 61 | +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
| 62 | +rickub.com/turbo-editors/turbo-core v1.0.5 h1:1CDKkW+xJpmNM8ab7KSMorXgYMsX5BTGaz0JgkxSO3E= | ||
| 63 | +rickub.com/turbo-editors/turbo-core v1.0.5/go.mod h1:M+f/mLHiWhqQCIRr88JSPJ6nxY2ALkEhDUuTkXi79dM= | ||
modified
main.go +55 -15 | @@ -16,6 +16,7 @@ | ||
| 16 | 16 | // -list-themes print the available themes and exit |
| 17 | 17 | // -no-lsp do not start a language server |
| 18 | 18 | // -version print the version and exit |
| 19 | +// -ssh user@machine[:dir] edit the files of another machine, over ssh (--ssh works too) | |
| 19 | 20 | // -load-config url copy the .turbo-golo directory found at a repository URL into the working directory and exit |
| 20 | 21 | package main |
| 21 | 22 | |
| @@ -31,7 +32,9 @@ import ( | ||
| 31 | 32 | |
| 32 | 33 | "rickub.com/turbo-editors/turbo-core/app" |
| 33 | 34 | "rickub.com/turbo-editors/turbo-core/configrepo" |
| 35 | + "rickub.com/turbo-editors/turbo-core/fsys" | |
| 34 | 36 | "rickub.com/turbo-editors/turbo-core/profile" |
| 37 | + "rickub.com/turbo-editors/turbo-core/remote" | |
| 35 | 38 | "rickub.com/turbo-editors/turbo-core/settings" |
| 36 | 39 | "rickub.com/turbo-editors/turbo-core/theme" |
| 37 | 40 | "rickub.com/turbo-editors/turbo-core/version" |
| @@ -51,26 +54,32 @@ type options struct { | ||
| 51 | 54 | theme string |
| 52 | 55 | listThemes bool |
| 53 | 56 | loadConfig string |
| 57 | + ssh string | |
| 54 | 58 | noLSP bool |
| 55 | 59 | version bool |
| 56 | 60 | files []string |
| 57 | 61 | } |
| 58 | 62 | |
| 59 | 63 | // parseFlags reads the command line. |
| 60 | -func parseFlags() options { | |
| 64 | +func parseFlags() options { return parseArguments(flag.CommandLine, os.Args[1:]) } | |
| 65 | + | |
| 66 | +// parseArguments reads arguments with flags. Go's flag package accepts every | |
| 67 | +// flag with one dash or two, which is why -ssh and --ssh are the same flag. | |
| 68 | +func parseArguments(flags *flag.FlagSet, arguments []string) options { | |
| 61 | 69 | var opts options |
| 62 | 70 | |
| 63 | 71 | // The default is empty rather than the theme's name so that "was -theme |
| 64 | 72 | // given?" can still be answered afterwards, which is what lets the project |
| 65 | 73 | // settings fill it in without overriding an explicit choice. |
| 66 | - flag.StringVar(&opts.theme, "theme", "", "colour theme to start with (default from the project, else "+theme.DefaultName+")") | |
| 67 | - flag.BoolVar(&opts.listThemes, "list-themes", false, "print the available themes and exit") | |
| 68 | - flag.BoolVar(&opts.noLSP, "no-lsp", false, "do not start a language server") | |
| 69 | - flag.BoolVar(&opts.version, "version", false, "print the version and exit") | |
| 70 | - flag.StringVar(&opts.loadConfig, "load-config", "", "copy the .turbo-golo directory found at this repository URL into the working directory, then exit") | |
| 71 | - flag.Parse() | |
| 72 | - | |
| 73 | - opts.files = flag.Args() | |
| 74 | + flags.StringVar(&opts.theme, "theme", "", "colour theme to start with (default from the project, else "+theme.DefaultName+")") | |
| 75 | + flags.BoolVar(&opts.listThemes, "list-themes", false, "print the available themes and exit") | |
| 76 | + flags.BoolVar(&opts.noLSP, "no-lsp", false, "do not start a language server") | |
| 77 | + flags.BoolVar(&opts.version, "version", false, "print the version and exit") | |
| 78 | + flags.StringVar(&opts.loadConfig, "load-config", "", "copy the .turbo-golo directory found at this repository URL into the working directory, then exit") | |
| 79 | + flags.StringVar(&opts.ssh, "ssh", "", "edit the files of another machine over ssh: user@machine[:directory]") | |
| 80 | + _ = flags.Parse(arguments) // a FlagSet that exits on error never returns one | |
| 81 | + | |
| 82 | + opts.files = flags.Args() | |
| 74 | 83 | return opts |
| 75 | 84 | } |
| 76 | 85 | |
| @@ -147,6 +156,15 @@ func describeLoad(result configrepo.Result) string { | ||
| 147 | 156 | |
| 148 | 157 | // edit opens the terminal and runs the editor until the user leaves. |
| 149 | 158 | func edit(opts options, p profile.Profile) error { |
| 159 | + // Before the screen is taken: ssh may have a password to ask for. | |
| 160 | + session, err := connectRemote(opts.ssh) | |
| 161 | + if err != nil { | |
| 162 | + return err | |
| 163 | + } | |
| 164 | + if session != nil { | |
| 165 | + defer session.Close() | |
| 166 | + } | |
| 167 | + | |
| 150 | 168 | project, projectSettings := loadProjectSettings(p) |
| 151 | 169 | |
| 152 | 170 | screen, err := newScreen() |
| @@ -161,11 +179,16 @@ func edit(opts options, p profile.Profile) error { | ||
| 161 | 179 | if settings.Exists(p, project) { |
| 162 | 180 | editor.UseSettings(projectSettings, settings.Path(p, project)) |
| 163 | 181 | } |
| 182 | + if session != nil { | |
| 183 | + editor.UseRemote(session) | |
| 184 | + } | |
| 164 | 185 | openFiles(editor, opts.files) |
| 165 | 186 | |
| 166 | 187 | ctx, cancel := context.WithCancel(context.Background()) |
| 167 | 188 | defer cancel() |
| 168 | - if !opts.noLSP { | |
| 189 | + // The language servers this editor finds are on this machine, and the | |
| 190 | + // files they would be asked about are not: over ssh there is none. | |
| 191 | + if !opts.noLSP && session == nil { | |
| 169 | 192 | editor.StartLanguageServer(ctx, app.ProjectRoot(p, opts.files)) |
| 170 | 193 | } |
| 171 | 194 | defer editor.Language().Stop(context.Background()) |
| @@ -173,16 +196,33 @@ func edit(opts options, p profile.Profile) error { | ||
| 173 | 196 | return editor.Run() |
| 174 | 197 | } |
| 175 | 198 | |
| 199 | +// connectRemote logs in to the machine -ssh names and points every file the | |
| 200 | +// editor reads and writes at it, so that the settings, the tree, the Open | |
| 201 | +// dialog and each window see that machine's files. It returns nil, and | |
| 202 | +// changes nothing, when -ssh was not given. | |
| 203 | +func connectRemote(target string) (*remote.Session, error) { | |
| 204 | + if target == "" { | |
| 205 | + return nil, nil | |
| 206 | + } | |
| 207 | + session, err := remote.Open(context.Background(), target) | |
| 208 | + if err != nil { | |
| 209 | + return nil, err | |
| 210 | + } | |
| 211 | + fsys.Use(session.FS()) | |
| 212 | + return session, nil | |
| 213 | +} | |
| 214 | + | |
| 176 | 215 | // loadProjectSettings reads .turbo-golo/settings.toml from the working |
| 177 | 216 | // directory, and returns that directory along with what it found. |
| 178 | 217 | // |
| 179 | 218 | // The working directory alone is looked in, with no walk up towards the root: |
| 180 | -// "the project" is where you started the editor, which is a rule you can hold | |
| 181 | -// in your head. A file that is there but unreadable is reported on standard | |
| 182 | -// error and then ignored — a broken settings file must not stop the editor | |
| 183 | -// opening, because the editor is how you would fix it. | |
| 219 | +// "the project" is where you started the editor — or the directory given to | |
| 220 | +// -ssh — which is a rule you can hold in your head. A file that is there but | |
| 221 | +// unreadable is reported on standard error and then ignored — a broken | |
| 222 | +// settings file must not stop the editor opening, because the editor is how | |
| 223 | +// you would fix it. | |
| 184 | 224 | func loadProjectSettings(p profile.Profile) (string, settings.Settings) { |
| 185 | - project, err := os.Getwd() | |
| 225 | + project, err := fsys.Getwd() | |
| 186 | 226 | if err != nil { |
| 187 | 227 | project = "." |
| 188 | 228 | } |
| @@ -16,6 +16,7 @@ | |||
| 16 | // -list-themes print the available themes and exit | 16 | // -list-themes print the available themes and exit |
| 17 | // -no-lsp do not start a language server | 17 | // -no-lsp do not start a language server |
| 18 | // -version print the version and exit | 18 | // -version print the version and exit |
| 19 | +// -ssh user@machine[:dir] edit the files of another machine, over ssh (--ssh works too) | ||
| 19 | // -load-config url copy the .turbo-golo directory found at a repository URL into the working directory and exit | 20 | // -load-config url copy the .turbo-golo directory found at a repository URL into the working directory and exit |
| 20 | package main | 21 | package main |
| 21 | 22 | ||
| @@ -31,7 +32,9 @@ import ( | |||
| 31 | 32 | ||
| 32 | "rickub.com/turbo-editors/turbo-core/app" | 33 | "rickub.com/turbo-editors/turbo-core/app" |
| 33 | "rickub.com/turbo-editors/turbo-core/configrepo" | 34 | "rickub.com/turbo-editors/turbo-core/configrepo" |
| 35 | + "rickub.com/turbo-editors/turbo-core/fsys" | ||
| 34 | "rickub.com/turbo-editors/turbo-core/profile" | 36 | "rickub.com/turbo-editors/turbo-core/profile" |
| 37 | + "rickub.com/turbo-editors/turbo-core/remote" | ||
| 35 | "rickub.com/turbo-editors/turbo-core/settings" | 38 | "rickub.com/turbo-editors/turbo-core/settings" |
| 36 | "rickub.com/turbo-editors/turbo-core/theme" | 39 | "rickub.com/turbo-editors/turbo-core/theme" |
| 37 | "rickub.com/turbo-editors/turbo-core/version" | 40 | "rickub.com/turbo-editors/turbo-core/version" |
| @@ -51,26 +54,32 @@ type options struct { | |||
| 51 | theme string | 54 | theme string |
| 52 | listThemes bool | 55 | listThemes bool |
| 53 | loadConfig string | 56 | loadConfig string |
| 57 | + ssh string | ||
| 54 | noLSP bool | 58 | noLSP bool |
| 55 | version bool | 59 | version bool |
| 56 | files []string | 60 | files []string |
| 57 | } | 61 | } |
| 58 | 62 | ||
| 59 | // parseFlags reads the command line. | 63 | // parseFlags reads the command line. |
| 60 | -func parseFlags() options { | 64 | +func parseFlags() options { return parseArguments(flag.CommandLine, os.Args[1:]) } |
| 65 | + | ||
| 66 | +// parseArguments reads arguments with flags. Go's flag package accepts every | ||
| 67 | +// flag with one dash or two, which is why -ssh and --ssh are the same flag. | ||
| 68 | +func parseArguments(flags *flag.FlagSet, arguments []string) options { | ||
| 61 | var opts options | 69 | var opts options |
| 62 | 70 | ||
| 63 | // The default is empty rather than the theme's name so that "was -theme | 71 | // The default is empty rather than the theme's name so that "was -theme |
| 64 | // given?" can still be answered afterwards, which is what lets the project | 72 | // given?" can still be answered afterwards, which is what lets the project |
| 65 | // settings fill it in without overriding an explicit choice. | 73 | // settings fill it in without overriding an explicit choice. |
| 66 | - flag.StringVar(&opts.theme, "theme", "", "colour theme to start with (default from the project, else "+theme.DefaultName+")") | 74 | + flags.StringVar(&opts.theme, "theme", "", "colour theme to start with (default from the project, else "+theme.DefaultName+")") |
| 67 | - flag.BoolVar(&opts.listThemes, "list-themes", false, "print the available themes and exit") | 75 | + flags.BoolVar(&opts.listThemes, "list-themes", false, "print the available themes and exit") |
| 68 | - flag.BoolVar(&opts.noLSP, "no-lsp", false, "do not start a language server") | 76 | + flags.BoolVar(&opts.noLSP, "no-lsp", false, "do not start a language server") |
| 69 | - flag.BoolVar(&opts.version, "version", false, "print the version and exit") | 77 | + flags.BoolVar(&opts.version, "version", false, "print the version and exit") |
| 70 | - flag.StringVar(&opts.loadConfig, "load-config", "", "copy the .turbo-golo directory found at this repository URL into the working directory, then exit") | 78 | + flags.StringVar(&opts.loadConfig, "load-config", "", "copy the .turbo-golo directory found at this repository URL into the working directory, then exit") |
| 71 | - flag.Parse() | 79 | + flags.StringVar(&opts.ssh, "ssh", "", "edit the files of another machine over ssh: user@machine[:directory]") |
| 72 | - | 80 | + _ = flags.Parse(arguments) // a FlagSet that exits on error never returns one |
| 73 | - opts.files = flag.Args() | 81 | + |
| 82 | + opts.files = flags.Args() | ||
| 74 | return opts | 83 | return opts |
| 75 | } | 84 | } |
| 76 | 85 | ||
| @@ -147,6 +156,15 @@ func describeLoad(result configrepo.Result) string { | |||
| 147 | 156 | ||
| 148 | // edit opens the terminal and runs the editor until the user leaves. | 157 | // edit opens the terminal and runs the editor until the user leaves. |
| 149 | func edit(opts options, p profile.Profile) error { | 158 | func edit(opts options, p profile.Profile) error { |
| 159 | + // Before the screen is taken: ssh may have a password to ask for. | ||
| 160 | + session, err := connectRemote(opts.ssh) | ||
| 161 | + if err != nil { | ||
| 162 | + return err | ||
| 163 | + } | ||
| 164 | + if session != nil { | ||
| 165 | + defer session.Close() | ||
| 166 | + } | ||
| 167 | + | ||
| 150 | project, projectSettings := loadProjectSettings(p) | 168 | project, projectSettings := loadProjectSettings(p) |
| 151 | 169 | ||
| 152 | screen, err := newScreen() | 170 | screen, err := newScreen() |
| @@ -161,11 +179,16 @@ func edit(opts options, p profile.Profile) error { | |||
| 161 | if settings.Exists(p, project) { | 179 | if settings.Exists(p, project) { |
| 162 | editor.UseSettings(projectSettings, settings.Path(p, project)) | 180 | editor.UseSettings(projectSettings, settings.Path(p, project)) |
| 163 | } | 181 | } |
| 182 | + if session != nil { | ||
| 183 | + editor.UseRemote(session) | ||
| 184 | + } | ||
| 164 | openFiles(editor, opts.files) | 185 | openFiles(editor, opts.files) |
| 165 | 186 | ||
| 166 | ctx, cancel := context.WithCancel(context.Background()) | 187 | ctx, cancel := context.WithCancel(context.Background()) |
| 167 | defer cancel() | 188 | defer cancel() |
| 168 | - if !opts.noLSP { | 189 | + // The language servers this editor finds are on this machine, and the |
| 190 | + // files they would be asked about are not: over ssh there is none. | ||
| 191 | + if !opts.noLSP && session == nil { | ||
| 169 | editor.StartLanguageServer(ctx, app.ProjectRoot(p, opts.files)) | 192 | editor.StartLanguageServer(ctx, app.ProjectRoot(p, opts.files)) |
| 170 | } | 193 | } |
| 171 | defer editor.Language().Stop(context.Background()) | 194 | defer editor.Language().Stop(context.Background()) |
| @@ -173,16 +196,33 @@ func edit(opts options, p profile.Profile) error { | |||
| 173 | return editor.Run() | 196 | return editor.Run() |
| 174 | } | 197 | } |
| 175 | 198 | ||
| 199 | +// connectRemote logs in to the machine -ssh names and points every file the | ||
| 200 | +// editor reads and writes at it, so that the settings, the tree, the Open | ||
| 201 | +// dialog and each window see that machine's files. It returns nil, and | ||
| 202 | +// changes nothing, when -ssh was not given. | ||
| 203 | +func connectRemote(target string) (*remote.Session, error) { | ||
| 204 | + if target == "" { | ||
| 205 | + return nil, nil | ||
| 206 | + } | ||
| 207 | + session, err := remote.Open(context.Background(), target) | ||
| 208 | + if err != nil { | ||
| 209 | + return nil, err | ||
| 210 | + } | ||
| 211 | + fsys.Use(session.FS()) | ||
| 212 | + return session, nil | ||
| 213 | +} | ||
| 214 | + | ||
| 176 | // loadProjectSettings reads .turbo-golo/settings.toml from the working | 215 | // loadProjectSettings reads .turbo-golo/settings.toml from the working |
| 177 | // directory, and returns that directory along with what it found. | 216 | // directory, and returns that directory along with what it found. |
| 178 | // | 217 | // |
| 179 | // The working directory alone is looked in, with no walk up towards the root: | 218 | // The working directory alone is looked in, with no walk up towards the root: |
| 180 | -// "the project" is where you started the editor, which is a rule you can hold | 219 | +// "the project" is where you started the editor — or the directory given to |
| 181 | -// in your head. A file that is there but unreadable is reported on standard | 220 | +// -ssh — which is a rule you can hold in your head. A file that is there but |
| 182 | -// error and then ignored — a broken settings file must not stop the editor | 221 | +// unreadable is reported on standard error and then ignored — a broken |
| 183 | -// opening, because the editor is how you would fix it. | 222 | +// settings file must not stop the editor opening, because the editor is how |
| 223 | +// you would fix it. | ||
| 184 | func loadProjectSettings(p profile.Profile) (string, settings.Settings) { | 224 | func loadProjectSettings(p profile.Profile) (string, settings.Settings) { |
| 185 | - project, err := os.Getwd() | 225 | + project, err := fsys.Getwd() |
| 186 | if err != nil { | 226 | if err != nil { |
| 187 | project = "." | 227 | project = "." |
| 188 | } | 228 | } |
modified
release.env +1 -1 | @@ -6,5 +6,5 @@ | ||
| 6 | 6 | # |
| 7 | 7 | # ./02-build-releases.sh v1.0.0 to build the binaries by hand and see what |
| 8 | 8 | # the CI will publish, without publishing anything |
| 9 | -TAG="v1.0.4" | |
| 9 | +TAG="v1.0.5" | |
| 10 | 10 | ABOUT="Turbo Golo" |
| @@ -6,5 +6,5 @@ | |||
| 6 | # | 6 | # |
| 7 | # ./02-build-releases.sh v1.0.0 to build the binaries by hand and see what | 7 | # ./02-build-releases.sh v1.0.0 to build the binaries by hand and see what |
| 8 | # the CI will publish, without publishing anything | 8 | # the CI will publish, without publishing anything |
| 9 | -TAG="v1.0.4" | 9 | +TAG="v1.0.5" |
| 10 | ABOUT="Turbo Golo" | 10 | ABOUT="Turbo Golo" |
added
ssh_test.go +81 -0 | new file mode 100644 | ||
| @@ -0,0 +1,81 @@ | ||
| 1 | +package main | |
| 2 | + | |
| 3 | +import ( | |
| 4 | + "errors" | |
| 5 | + "flag" | |
| 6 | + "io" | |
| 7 | + "testing" | |
| 8 | + | |
| 9 | + "rickub.com/turbo-editors/turbo-core/fsys" | |
| 10 | + "rickub.com/turbo-editors/turbo-core/fsys/fsystest" | |
| 11 | + "rickub.com/turbo-editors/turbo-core/remote" | |
| 12 | + "rickub.com/turbo-editors/turbo-core/settings" | |
| 13 | + | |
| 14 | + "rickub.com/turbo-editors/turbo-golo/internal/gololang" | |
| 15 | +) | |
| 16 | + | |
| 17 | +// parse reads a command line the way main does, into a flag set of its own. | |
| 18 | +func parse(t *testing.T, arguments ...string) options { | |
| 19 | + t.Helper() | |
| 20 | + flags := flag.NewFlagSet("turbo-golo", flag.ContinueOnError) | |
| 21 | + flags.SetOutput(io.Discard) | |
| 22 | + return parseArguments(flags, arguments) | |
| 23 | +} | |
| 24 | + | |
| 25 | +func TestTheSSHFlagIsReadWithOneDashOrTwo(t *testing.T) { | |
| 26 | + cases := []struct { | |
| 27 | + arguments []string | |
| 28 | + want string | |
| 29 | + }{ | |
| 30 | + {[]string{"-ssh", "bob@machine"}, "bob@machine"}, | |
| 31 | + {[]string{"--ssh", "bob@machine:/srv/app"}, "bob@machine:/srv/app"}, | |
| 32 | + {[]string{"--ssh=demo:workspace"}, "demo:workspace"}, | |
| 33 | + } | |
| 34 | + for _, c := range cases { | |
| 35 | + if got := parse(t, c.arguments...).ssh; got != c.want { | |
| 36 | + t.Errorf("%v: ssh = %q, want %q", c.arguments, got, c.want) | |
| 37 | + } | |
| 38 | + } | |
| 39 | +} | |
| 40 | + | |
| 41 | +func TestFilesAfterTheSSHFlagAreStillFiles(t *testing.T) { | |
| 42 | + opts := parse(t, "-ssh", "bob@machine", "main.x", "other.x") | |
| 43 | + if len(opts.files) != 2 || opts.files[0] != "main.x" { | |
| 44 | + t.Errorf("files = %v, want the two named after the flag", opts.files) | |
| 45 | + } | |
| 46 | +} | |
| 47 | + | |
| 48 | +func TestWithoutSSHTheEditorStaysLocal(t *testing.T) { | |
| 49 | + session, err := connectRemote("") | |
| 50 | + if session != nil || err != nil { | |
| 51 | + t.Errorf("connectRemote(\"\") = %v, %v; want nothing at all", session, err) | |
| 52 | + } | |
| 53 | + if !fsys.IsLocal() { | |
| 54 | + t.Error("the file system is no longer the local disk") | |
| 55 | + } | |
| 56 | +} | |
| 57 | + | |
| 58 | +func TestABadSSHTargetIsRefusedBeforeAnythingIsStarted(t *testing.T) { | |
| 59 | + _, err := connectRemote("-oProxyCommand=evil") | |
| 60 | + if !errors.Is(err, remote.ErrBadTarget) { | |
| 61 | + t.Errorf("err = %v, want remote.ErrBadTarget", err) | |
| 62 | + } | |
| 63 | + if !fsys.IsLocal() { | |
| 64 | + t.Error("a refused target still switched the file system") | |
| 65 | + } | |
| 66 | +} | |
| 67 | + | |
| 68 | +// Under -ssh the project is the remote directory: the settings are read | |
| 69 | +// through fsys, from wherever it points. | |
| 70 | +func TestProjectSettingsAreReadFromTheCurrentFileSystem(t *testing.T) { | |
| 71 | + p := gololang.Profile() | |
| 72 | + memory := fsystest.New("/home/bob/project") | |
| 73 | + previous := fsys.Use(memory) | |
| 74 | + t.Cleanup(func() { fsys.Use(previous) }) | |
| 75 | + memory.AddFile(settings.Path(p, "/home/bob/project"), "[editor]\ntheme = \"turbo-dark\"\n") | |
| 76 | + | |
| 77 | + project, loaded := loadProjectSettings(p) | |
| 78 | + if project != "/home/bob/project" || loaded.Theme != "turbo-dark" { | |
| 79 | + t.Errorf("loadProjectSettings = %q, %+v; want the remote project and its theme", project, loaded) | |
| 80 | + } | |
| 81 | +} | |
| new file mode 100644 | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | +package main | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "errors" | ||
| 5 | + "flag" | ||
| 6 | + "io" | ||
| 7 | + "testing" | ||
| 8 | + | ||
| 9 | + "rickub.com/turbo-editors/turbo-core/fsys" | ||
| 10 | + "rickub.com/turbo-editors/turbo-core/fsys/fsystest" | ||
| 11 | + "rickub.com/turbo-editors/turbo-core/remote" | ||
| 12 | + "rickub.com/turbo-editors/turbo-core/settings" | ||
| 13 | + | ||
| 14 | + "rickub.com/turbo-editors/turbo-golo/internal/gololang" | ||
| 15 | +) | ||
| 16 | + | ||
| 17 | +// parse reads a command line the way main does, into a flag set of its own. | ||
| 18 | +func parse(t *testing.T, arguments ...string) options { | ||
| 19 | + t.Helper() | ||
| 20 | + flags := flag.NewFlagSet("turbo-golo", flag.ContinueOnError) | ||
| 21 | + flags.SetOutput(io.Discard) | ||
| 22 | + return parseArguments(flags, arguments) | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +func TestTheSSHFlagIsReadWithOneDashOrTwo(t *testing.T) { | ||
| 26 | + cases := []struct { | ||
| 27 | + arguments []string | ||
| 28 | + want string | ||
| 29 | + }{ | ||
| 30 | + {[]string{"-ssh", "bob@machine"}, "bob@machine"}, | ||
| 31 | + {[]string{"--ssh", "bob@machine:/srv/app"}, "bob@machine:/srv/app"}, | ||
| 32 | + {[]string{"--ssh=demo:workspace"}, "demo:workspace"}, | ||
| 33 | + } | ||
| 34 | + for _, c := range cases { | ||
| 35 | + if got := parse(t, c.arguments...).ssh; got != c.want { | ||
| 36 | + t.Errorf("%v: ssh = %q, want %q", c.arguments, got, c.want) | ||
| 37 | + } | ||
| 38 | + } | ||
| 39 | +} | ||
| 40 | + | ||
| 41 | +func TestFilesAfterTheSSHFlagAreStillFiles(t *testing.T) { | ||
| 42 | + opts := parse(t, "-ssh", "bob@machine", "main.x", "other.x") | ||
| 43 | + if len(opts.files) != 2 || opts.files[0] != "main.x" { | ||
| 44 | + t.Errorf("files = %v, want the two named after the flag", opts.files) | ||
| 45 | + } | ||
| 46 | +} | ||
| 47 | + | ||
| 48 | +func TestWithoutSSHTheEditorStaysLocal(t *testing.T) { | ||
| 49 | + session, err := connectRemote("") | ||
| 50 | + if session != nil || err != nil { | ||
| 51 | + t.Errorf("connectRemote(\"\") = %v, %v; want nothing at all", session, err) | ||
| 52 | + } | ||
| 53 | + if !fsys.IsLocal() { | ||
| 54 | + t.Error("the file system is no longer the local disk") | ||
| 55 | + } | ||
| 56 | +} | ||
| 57 | + | ||
| 58 | +func TestABadSSHTargetIsRefusedBeforeAnythingIsStarted(t *testing.T) { | ||
| 59 | + _, err := connectRemote("-oProxyCommand=evil") | ||
| 60 | + if !errors.Is(err, remote.ErrBadTarget) { | ||
| 61 | + t.Errorf("err = %v, want remote.ErrBadTarget", err) | ||
| 62 | + } | ||
| 63 | + if !fsys.IsLocal() { | ||
| 64 | + t.Error("a refused target still switched the file system") | ||
| 65 | + } | ||
| 66 | +} | ||
| 67 | + | ||
| 68 | +// Under -ssh the project is the remote directory: the settings are read | ||
| 69 | +// through fsys, from wherever it points. | ||
| 70 | +func TestProjectSettingsAreReadFromTheCurrentFileSystem(t *testing.T) { | ||
| 71 | + p := gololang.Profile() | ||
| 72 | + memory := fsystest.New("/home/bob/project") | ||
| 73 | + previous := fsys.Use(memory) | ||
| 74 | + t.Cleanup(func() { fsys.Use(previous) }) | ||
| 75 | + memory.AddFile(settings.Path(p, "/home/bob/project"), "[editor]\ntheme = \"turbo-dark\"\n") | ||
| 76 | + | ||
| 77 | + project, loaded := loadProjectSettings(p) | ||
| 78 | + if project != "/home/bob/project" || loaded.Theme != "turbo-dark" { | ||
| 79 | + t.Errorf("loadProjectSettings = %q, %+v; want the remote project and its theme", project, loaded) | ||
| 80 | + } | ||
| 81 | +} | ||