diff --git a/bundle/regal/lsp/completion/providers/booleans/booleans.rego b/bundle/regal/lsp/completion/providers/booleans/booleans.rego new file mode 100644 index 00000000..9a11c4dd --- /dev/null +++ b/bundle/regal/lsp/completion/providers/booleans/booleans.rego @@ -0,0 +1,39 @@ +package regal.lsp.completion.providers.booleans + +import rego.v1 + +import data.regal.lsp.completion.kind +import data.regal.lsp.completion.location + +parsed_current_file := data.workspace.parsed[input.regal.file.uri] + +items contains item if { + position := location.to_position(input.regal.context.location) + + line := input.regal.file.lines[position.line] + line != "" + + words := regex.split(`\s+`, line) + + words_on_line := count(words) + + previous_word := words[words_on_line - 2] + + previous_word in {"==", ":="} + + word := location.word_at(line, input.regal.context.location.col) + + some b in ["true", "false"] + + startswith(b, word.text) + + item := { + "label": b, + "kind": kind.constant, + "detail": "boolean value", + "textEdit": { + "range": location.word_range(word, position), + "newText": b, + }, + } +} diff --git a/bundle/regal/lsp/completion/providers/booleans/booleans_test.rego b/bundle/regal/lsp/completion/providers/booleans/booleans_test.rego new file mode 100644 index 00000000..bda269d2 --- /dev/null +++ b/bundle/regal/lsp/completion/providers/booleans/booleans_test.rego @@ -0,0 +1,116 @@ +package regal.lsp.completion.providers.booleans_test + +import rego.v1 + +import data.regal.lsp.completion.providers.booleans as provider +import data.regal.lsp.completion.providers.test_utils as utils + +test_suggested_in_head if { + workspace := {"file:///p.rego": `package policy + +import rego.v1 + +allow := f`} + + regal_module := {"regal": { + "file": { + "name": "p.rego", + "lines": split(workspace["file:///p.rego"], "\n"), + }, + "context": {"location": { + "row": 5, + "col": 10, + }}, + }} + + items := provider.items with input as regal_module with data.workspace.parsed as utils.parsed_modules(workspace) + + count(items) == 1 + + some item in items + + item.label == "false" +} + +test_suggested_in_body if { + workspace := {"file:///p.rego": `package policy + +import rego.v1 + +allow if { + foo := t +}`} + + regal_module := {"regal": { + "file": { + "name": "p.rego", + "lines": split(workspace["file:///p.rego"], "\n"), + }, + "context": {"location": { + "row": 6, + "col": 10, + }}, + }} + + items := provider.items with input as regal_module with data.workspace.parsed as utils.parsed_modules(workspace) + + count(items) == 1 + + some item in items + + item.label == "true" +} + +test_suggested_after_equals if { + workspace := {"file:///p.rego": `package policy + +import rego.v1 + +allow if { + foo == t +}`} + + regal_module := {"regal": { + "file": { + "name": "p.rego", + "lines": split(workspace["file:///p.rego"], "\n"), + }, + "context": {"location": { + "row": 6, + "col": 10, + }}, + }} + + items := provider.items with input as regal_module with data.workspace.parsed as utils.parsed_modules(workspace) + + count(items) == 1 + + some item in items + + item.label == "true" +} + +test_not_suggested_at_start if { + workspace := {"file:///p.rego": `package policy + +import rego.v1 + +allow if { + t +}`} + + regal_module := {"regal": { + "file": { + "name": "p.rego", + "lines": split(workspace["file:///p.rego"], "\n"), + }, + "context": {"location": { + "row": 6, + "col": 3, + }}, + }} + + items := provider.items with input as regal_module with data.workspace.parsed as utils.parsed_modules(workspace) + + count(items) == 0 +}