turbo-editors/turbo-golopublic Fork 0
79b67fdd82d26f23a6b97e39c1f063d475cbbc49
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-golo.git
git clone ssh://git@rickub.com/turbo-editors/turbo-golo.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

gololang.go · 143 lines · 6.2 KBGo Blame HistoryRaw
📦 Turbo Golo d710c1b k33g 22h ago1// Package gololang is everything about Turbo Golo that is about *Golo*: how
2// the editor names itself, which language server it talks to, what a project's
3// starter files say, and how Golo source is coloured.
4//
5// Everything else the editor does lives in turbo-core, which knows nothing
6// about Golo. This package is the whole of the difference between Turbo Golo
7// and Turbo MoonBit, which is what makes a sixth editor a matter of writing one
8// of these rather than forking anything.
9//
10// gololang.Register() // teach the library to colour Golo
11// editor := app.New(screen, name, gololang.Profile())
12package gololang
13
14import (
15 "rickub.com/turbo-editors/turbo-core/profile"
16 "rickub.com/turbo-editors/turbo-core/syntax"
17)
18
19// Name and Slug are what the editor calls itself. The slug is also its binary,
20// its project directory (as .turbo-golo) and the stem of its environment
21// variables (as TURBO_GOLO_…), so it is not free to change.
22const (
23 Name = "Turbo Golo"
24 Slug = "turbo-golo"
25)
26
27// Language is the name Golo is known by: the value LanguageOf returns for a
28// .golo file, and what a snippets file writes in its languages key.
29//
30// It is lower case because every other name in the registry is — "golo"
31// beside "toml" and "dockerfile" — while the language's own spelling, the one
32// a person reads, is Profile().Language.
33const Language syntax.Language = "golo"
34
35// ServerCommand is the language server Turbo Golo talks to, and InstallHint
36// the one place a user gets it from.
37//
38// The server is the interpreter itself: `golo lsp` puts the same binary that
39// runs a script into language-server mode, reusing its lexer, parser and AST.
40// So a machine that can run Golo can complete Golo, and there is nothing
41// separate to install — which is why the hint names the release page that
42// ships the binary rather than a package manager's command.
43//
44// It answers four of the nine questions turbo-core asks — completion, hover,
45// definition and the file's symbols — and publishes diagnostics unasked. It
46// advertises neither references, typeDefinition and implementation, nor
47// workspace/symbol, so those items report nothing found. That is documented
48// rather than worked around, and a test asserts it so a future golo gaining
49// them is noticed.
50const (
51 ServerCommand = "golo"
52 InstallHint = "see https://codeberg.org/TypeUnsafe/golo-script/releases"
53)
54
55// DefaultInstallDir is where GoloScript's own install.sh puts golo, gogolo and
56// wagolo. It is on PATH on almost every machine, and it is searched all the
57// same for the one where it is not: "completion silently does nothing" is what
58// a user sees when the editor cannot find a server they believe they installed.
59const DefaultInstallDir = "/usr/local/bin"
60
61// ServerArgs is what golo is started with.
62//
63// The lsp is not optional: golo with no argument starts its REPL and reads
64// standard input as Golo source, which the editor would see as a server that
65// answers nothing and never dies. It is a function rather than a variable so
66// that no caller can append to the package's own slice.
67func ServerArgs() []string { return []string{"lsp"} }
68
69// Profile returns the editor Turbo Golo is.
70//
71// It is a function rather than a variable for the same reason as in every other
72// editor of this family, even though nothing here reads the environment: a
73// caller that mutates what it gets back — appending to Server.Dirs, say — must
74// not be mutating the package's one copy.
75func Profile() profile.Profile {
76 return profile.Profile{
77 Name: Name,
78 Slug: Slug,
79 // The language's own spelling. Golo is the language; GoloScript is
80 // the implementation whose binary this editor talks to, the way Go is
81 // the language and gc the compiler. This is what the About box and the
82 // status bar read out, so it names the language.
83 Language: "Golo",
84 // G is free: the fixed menus take F, E, S, R, C, O, W, N and H —
85 // which rules out the O of Golo but not its first letter — so the hot
86 // key lands where a reader expects it. The menu is named after the
87 // language and not after golo, gogolo or wagolo, because it holds
88 // whatever the project put in its tools file, and the first tools
89 // file anybody writes outgrows the language's own toolchain.
90 ToolsMenu: "~G~olo",
91 // None, on purpose. Golo has no project manifest — no golo.mod, no
92 // build file — a script is a file and a program is a directory of
93 // them. With nothing to look for, app.ProjectRoot hands the server
94 // the directory of the file being edited, which is also all the
95 // server needs: golo lsp answers about the file it is given and
96 // resolves imports from the modules embedded in the binary, never
97 // from disk. A marker would make the walk look like part of the rule
98 // when there is no rule.
99 RootMarkers: nil,
100 Server: profile.Server{
101 Command: ServerCommand,
102 Args: ServerArgs(),
103 InstallHint: InstallHint,
104 Dirs: ServerDirs(),
105 },
106 Templates: profile.Templates{
107 Settings: settingsTemplate,
108 Snippets: snippetsTemplate,
109 Tools: toolsTemplate,
110 Agents: agentsTemplate,
111 },
112 }
113}
114
115// Register teaches turbo-core to colour Golo.
116//
117// It is called explicitly at start-up rather than from an init function so that
118// "which languages does this editor know?" is answered by reading main, not by
119// working out which packages were imported.
120//
121// A shebang is claimed. A Golo script may open with #!/usr/bin/env golo and be
122// run as a command: # opens a comment in Golo, so the interpreter reads the
123// line as one, and a file with no extension whose first line names golo is
124// Golo and nothing else.
125func Register() {
126 syntax.Register(syntax.Definition{
127 Language: Language,
128 Extensions: []string{".golo"},
129 Shebangs: []string{"golo"},
130 Highlight: Highlight,
131 })
132}
133
134// ServerDirs returns the directories golo is looked for in after PATH.
135//
136// There is one: the directory GoloScript's installer writes into. Golo has no
137// per-user toolchain directory and no environment variable naming one, so
138// there is nothing else to search — and listing a guess would be worse than
139// listing nothing, because a directory the server is never in costs a stat
140// on every start for no answer.
141func ServerDirs() []string {
142 return []string{DefaultInstallDir}
143}