Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions lib/puppet-languageserver/manifest/completion_provider.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@ module Manifest
module CompletionProvider
def self.complete(content, line_num, char_num, options = {})
options = {
:tasks_mode => false
:tasks_mode => false,
:context => nil # LSP::CompletionContext object
}.merge(options)
items = []
incomplete = false
is_trigger_char = !options[:context].nil? && options[:context].triggerKind == LSP::CompletionTriggerKind::TRIGGERCHARACTER

result = PuppetLanguageServer::PuppetParserHelper.object_under_cursor(content, line_num, char_num,
:multiple_attempts => true,
:disallowed_classes => [Puppet::Pops::Model::QualifiedName, Puppet::Pops::Model::BlockExpression],
:tasks_mode => options[:tasks_mode])
:multiple_attempts => true,
:disallowed_classes => [Puppet::Pops::Model::QualifiedName, Puppet::Pops::Model::BlockExpression],
:tasks_mode => options[:tasks_mode],
:remove_trigger_char => is_trigger_char)
if result.nil?
# We are in the root of the document.

Expand Down Expand Up @@ -41,8 +44,8 @@ def self.complete(content, line_num, char_num, options = {})
# Complete for `$facts[...`
all_facts { |x| items << x } if expr == 'facts'

when 'Puppet::Pops::Model::HostClassDefinition'
# We are in the root of a `class` statement
when 'Puppet::Pops::Model::HostClassDefinition', 'Puppet::Pops::Model::ResourceTypeDefinition'
# We are in the root of a `class` or `define` statement

# Add keywords
keywords(%w[require contain]) { |x| items << x }
Expand Down
3 changes: 2 additions & 1 deletion lib/puppet-languageserver/message_handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,11 @@ def request_textdocument_completion(_, json_rpc_message)
line_num = json_rpc_message.params['position']['line']
char_num = json_rpc_message.params['position']['character']
content = documents.document(file_uri)
context = json_rpc_message.params['context'].nil? ? nil : LSP::CompletionContext.new(json_rpc_message.params['context'])

case documents.document_type(file_uri)
when :manifest
return PuppetLanguageServer::Manifest::CompletionProvider.complete(content, line_num, char_num, :tasks_mode => PuppetLanguageServer::DocumentStore.plan_file?(file_uri))
return PuppetLanguageServer::Manifest::CompletionProvider.complete(content, line_num, char_num, :context => context, :tasks_mode => PuppetLanguageServer::DocumentStore.plan_file?(file_uri))
else
raise "Unable to provide completion on #{file_uri}"
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ def create_ensurable_property

context "Given a simple valid manifest" do
let(:content) { <<-EOT

class Alice {

user { 'Bob':
Expand All @@ -131,14 +132,19 @@ class Alice {
ensure => 'present',
name => 'name',
}

define delta (
) {

}
EOT
}

describe "When inside the root of the manifest" do
let(:char_num) { 0 }
let(:expected_types) { ['keyword','resource_type','function','resource_class'] }

[0, 8].each do |line_num|
[0, 9].each do |line_num|
it "should return a list of keyword, resource_type, function, resource_class regardless of cursor location (Testing line #{line_num})" do
result = subject.complete(content, line_num, char_num)

Expand All @@ -153,26 +159,30 @@ class Alice {
end
end

describe "When inside the root of a class" do
let(:line_num) { 1 }
let(:char_num) { 0 }
let(:expected_types) { ['keyword','resource_type','resource_class'] }
[
{ :name => 'class', :line_num => 1 },
{ :name => 'defined type', :line_num => 19 },
].each do |testcase|
describe "When inside the root of a #{testcase[:name]}" do
let(:char_num) { 0 }
let(:expected_types) { ['keyword','resource_type','resource_class'] }

it 'should return a list of keyword, resource_type, resource_class' do
result = subject.complete(content, line_num, char_num)
it 'should return a list of keyword, resource_type, resource_class' do
result = subject.complete(content, testcase[:line_num], char_num)

result.items.each do |item|
expect(item).to be_completion_item_with_type(expected_types)
end
result.items.each do |item|
expect(item).to be_completion_item_with_type(expected_types)
end

expected_types.each do |typename|
expect(number_of_completion_item_with_type(result,typename)).to be > 0
expected_types.each do |typename|
expect(number_of_completion_item_with_type(result,typename)).to be > 0
end
end
end
end

describe "When inside the root of a resource" do
let(:line_num) { 11 }
let(:line_num) { 12 }
let(:char_num) { 0 }
let(:expected_types) { ['resource_parameter','resource_property'] }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -488,16 +488,36 @@
let(:file_uri) { MANIFEST_FILENAME }

it 'should call complete method on the Completion Provider' do
expect(PuppetLanguageServer::Manifest::CompletionProvider).to receive(:complete).with(Object,line_num,char_num,{:tasks_mode=>false}).and_return('something')
expect(PuppetLanguageServer::Manifest::CompletionProvider).to receive(:complete).with(Object, line_num, char_num, { :tasks_mode => false, :context => nil }).and_return('something')
subject.request_textdocument_completion(connection_id, request_message)
end

it 'should set tasks_mode option if the file is Puppet plan file' do
expect(PuppetLanguageServer::Manifest::CompletionProvider).to receive(:complete).with(Object,line_num,char_num,{:tasks_mode=>true}).and_return('something')
expect(PuppetLanguageServer::Manifest::CompletionProvider).to receive(:complete).with(Object, line_num, char_num, { :tasks_mode => true, :context => nil }).and_return('something')
allow(PuppetLanguageServer::DocumentStore).to receive(:plan_file?).and_return true
subject.request_textdocument_completion(connection_id, request_message)
end

context 'with a completion context' do
let(:request_params) {{
'textDocument' => {
'uri' => file_uri
},
'position' => {
'line' => line_num,
'character' => char_num,
},
'context' => {
'triggerKind' => 1
}
}}

it 'should pass the context' do
expect(PuppetLanguageServer::Manifest::CompletionProvider).to receive(:complete).with(Object, line_num, char_num, { :tasks_mode => false, :context => LSP::CompletionContext}).and_return('something')
subject.request_textdocument_completion(connection_id, request_message)
end
end

context 'and an error occurs during completion' do
before(:each) do
expect(PuppetLanguageServer::Manifest::CompletionProvider).to receive(:complete).and_raise('MockError')
Expand Down