Skip to content

Commit

Permalink
cuepls: support formatting of CUE files
Browse files Browse the repository at this point in the history
Add support for the formatting of CUE files.

While we are here, create a cuelang package alongside the existing
golang package.

Lots more formatting required in later CLs, but again this is a good
bootstrap.

For #142

Signed-off-by: Paul Jolly <paul@myitcv.io>
Change-Id: I13ab83c1251714182e69d06bb53ed08f94bac709
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1174174
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: CUEcueckoo <cueckoo@gmail.com>
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>
  • Loading branch information
myitcv committed Feb 14, 2024
1 parent 55f965d commit d185263
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 6 deletions.
16 changes: 10 additions & 6 deletions cmd/cuepls/internal/test/integration/base/base_test.go
Expand Up @@ -7,6 +7,7 @@ import (

"cuelang.org/go/internal/golangorgx/gopls/hooks"
. "cuelang.org/go/internal/golangorgx/gopls/test/integration"
"cuelang.org/go/internal/golangorgx/gopls/test/integration/fake"
"github.com/go-quicktest/qt"
)

Expand All @@ -20,14 +21,17 @@ func TestFormatFile(t *testing.T) {
module mod.com
go 1.12
-- foo.go --
package foo
-- foo.cue --
package foo
// this is a test
`
Run(t, files, func(t *testing.T, env *Env) {
env.OpenFile("foo.go")
env.FormatBuffer("foo.go")
got := env.BufferText("foo.go")
want := "package foo\n"
env.OpenFile("foo.cue")
env.EditBuffer("foo.cue", fake.NewEdit(0, 0, 1, 0, "package bar\n"))
env.FormatBuffer("foo.cue")
got := env.BufferText("foo.cue")
want := "package bar\n\n// this is a test\n"
qt.Assert(t, qt.Equals(got, want))
})
}
60 changes: 60 additions & 0 deletions internal/golangorgx/gopls/cuelang/format.go
@@ -0,0 +1,60 @@
// Copyright 2024 The CUE Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package golang defines the LSP features for navigation, analysis,
// and refactoring of Go source code.
package cuelang

import (
"bytes"
"context"

cueformat "cuelang.org/go/cue/format"

"cuelang.org/go/internal/golangorgx/gopls/cache"
"cuelang.org/go/internal/golangorgx/gopls/file"
"cuelang.org/go/internal/golangorgx/gopls/protocol"
"cuelang.org/go/internal/golangorgx/tools/diff"
"cuelang.org/go/internal/golangorgx/tools/event"
)

// FormatCUE formats a CUE file with a given range.
func FormatCUE(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle) ([]protocol.TextEdit, error) {
ctx, done := event.Start(ctx, "source.FormatCUE")
defer done()

// TODO cache the parsed artefacts, which will include the mapper

src, err := fh.Content()
if err != nil {
return nil, err
}
res, err := cueformat.Source(src)
if err != nil {
// TODO fix up the AST like gopls so we can do more with
// partial/incomplete code.
//
// For now return early because there is nothing we can do.
return nil, nil
}

// If the format did nothing, do nothing
if bytes.Equal(src, res) {
return nil, nil
}

mapper := protocol.NewMapper(fh.URI(), src)
edits := diff.Strings(string(src), string(res))
return protocol.EditsFromDiffEdits(mapper, edits)
}
6 changes: 6 additions & 0 deletions internal/golangorgx/gopls/server/format.go
Expand Up @@ -7,6 +7,7 @@ package server
import (
"context"

"cuelang.org/go/internal/golangorgx/gopls/cuelang"
"cuelang.org/go/internal/golangorgx/gopls/file"
"cuelang.org/go/internal/golangorgx/gopls/golang"
"cuelang.org/go/internal/golangorgx/gopls/protocol"
Expand All @@ -27,6 +28,11 @@ func (s *server) Formatting(ctx context.Context, params *protocol.DocumentFormat
switch snapshot.FileKind(fh) {
case file.Go:
return golang.Format(ctx, snapshot, fh)
case file.CUE:
return cuelang.FormatCUE(ctx, snapshot, fh)
default:
// TODO warn that we did not know how to format that file... why was the
// request routed to this LSP?
}
return nil, nil // empty result
}

0 comments on commit d185263

Please sign in to comment.