119 lines
2.8 KiB
Go
119 lines
2.8 KiB
Go
package lsp
|
|
|
|
import (
|
|
"path/filepath"
|
|
|
|
"ollie/util"
|
|
)
|
|
|
|
// Adapter describes an LSP server for a specific language.
|
|
type Adapter struct {
|
|
Name string
|
|
Extensions []string
|
|
RootMarkers []string
|
|
Cmd []string
|
|
InitOptions map[string]any
|
|
}
|
|
|
|
// WorkspaceRoot finds the project root for a file using this adapter's markers.
|
|
func (a *Adapter) WorkspaceRoot(file, fallback string) string {
|
|
return FindRoot(file, a.RootMarkers, fallback)
|
|
}
|
|
|
|
// Adapters is the registry of known LSP adapters.
|
|
var Adapters = []*Adapter{
|
|
{
|
|
Name: "gopls",
|
|
Extensions: []string{".go"},
|
|
RootMarkers: []string{"go.work", "go.mod"},
|
|
Cmd: []string{"gopls", "serve"},
|
|
InitOptions: map[string]any{
|
|
"usePlaceholders": true,
|
|
"staticcheck": true,
|
|
"gofumpt": true,
|
|
},
|
|
},
|
|
{
|
|
Name: "clangd",
|
|
Extensions: []string{".c", ".h", ".cc", ".cpp", ".cxx", ".hpp", ".hxx"},
|
|
RootMarkers: []string{"compile_commands.json", "CMakeLists.txt", ".clangd", "Makefile"},
|
|
Cmd: []string{"clangd", "--background-index"},
|
|
InitOptions: nil,
|
|
},
|
|
{
|
|
Name: "intelephense",
|
|
Extensions: []string{".php"},
|
|
RootMarkers: []string{"composer.json", ".git"},
|
|
Cmd: []string{"intelephense", "--stdio"},
|
|
InitOptions: nil,
|
|
},
|
|
}
|
|
|
|
// extMap builds on first call.
|
|
var extMap map[string]*Adapter
|
|
|
|
func buildExtMap() {
|
|
extMap = make(map[string]*Adapter, 16)
|
|
for _, a := range Adapters {
|
|
for _, ext := range a.Extensions {
|
|
extMap[ext] = a
|
|
}
|
|
}
|
|
}
|
|
|
|
// Detect returns the adapter for a file path based on extension, or nil.
|
|
func Detect(filepath string) *Adapter {
|
|
if extMap == nil {
|
|
buildExtMap()
|
|
}
|
|
ext := filepathExt(filepath)
|
|
return extMap[ext]
|
|
}
|
|
|
|
func filepathExt(path string) string {
|
|
return filepath.Ext(path)
|
|
}
|
|
|
|
// FileURI converts an absolute path to a file:// URI.
|
|
func FileURI(path string) string {
|
|
abs, err := filepath.Abs(path)
|
|
if err != nil {
|
|
abs = path
|
|
}
|
|
return "file://" + abs
|
|
}
|
|
|
|
// URIToPath converts a file:// URI to a local path.
|
|
func URIToPath(uri string) string {
|
|
const prefix = "file://"
|
|
if len(uri) > len(prefix) && uri[:len(prefix)] == prefix {
|
|
return uri[len(prefix):]
|
|
}
|
|
return uri
|
|
}
|
|
|
|
// LanguageID returns the LSP language identifier for a file extension.
|
|
func LanguageID(path string) string {
|
|
ext := filepath.Ext(path)
|
|
m := map[string]string{
|
|
".go": "go", ".c": "c", ".h": "c", ".cc": "cpp", ".cpp": "cpp",
|
|
".cxx": "cpp", ".hpp": "cpp", ".hxx": "cpp", ".php": "php",
|
|
".py": "python", ".js": "javascript", ".ts": "typescript",
|
|
".rs": "rust", ".java": "java", ".rb": "ruby",
|
|
}
|
|
if id, ok := m[ext]; ok {
|
|
return id
|
|
}
|
|
return "plaintext"
|
|
}
|
|
|
|
// SockPath returns the path to the bridge Unix socket.
|
|
func SockPath() string {
|
|
return filepath.Join(util.RuntimeDir(), "ollie-lsp.sock")
|
|
}
|
|
|
|
// PidPath returns the path to the bridge PID file.
|
|
func PidPath() string {
|
|
return SockPath() + ".pid"
|
|
}
|