Skip to content

Commit

Permalink
Completions
Browse files Browse the repository at this point in the history
  • Loading branch information
wkillerud committed Jan 4, 2025
1 parent b1fd5d7 commit 22d7501
Show file tree
Hide file tree
Showing 6 changed files with 311 additions and 72 deletions.
84 changes: 74 additions & 10 deletions pkgs/sass_language_services/lib/src/css/css_property.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import 'package:lsp_server/lsp_server.dart' as lsp;

import '../utils/sass_lsp_utils.dart';
import 'css_value.dart';
import 'entry_status.dart';
import 'reference.dart';

final re = RegExp(r'([A-Z]+)(\d+)?');
const browserNames = {
"E": "Edge",
"FF": "Firefox",
"S": "Safari",
"C": "Chrome",
"IE": "IE",
"O": "Opera",
};

class CssProperty {
final String name;
final String? description;
Expand All @@ -14,14 +27,65 @@ class CssProperty {
final int? relevance;
final String? atRule;

CssProperty(this.name,
{this.description,
this.browsers,
this.restrictions,
this.status,
this.syntax,
this.values,
this.references,
this.relevance,
this.atRule});
CssProperty(
this.name, {
this.description,
this.browsers,
this.restrictions,
this.status,
this.syntax,
this.values,
this.references,
this.relevance,
this.atRule,
});

lsp.Either2<lsp.MarkupContent, String> getPlaintextDescription() {
var browsersString = browsers?.map<String>((b) {
var matches = re.firstMatch(b);
if (matches != null) {
var browser = matches.group(1);
var version = matches.group(2);
return "${browserNames[browser]} $version";
}
return b;
}).join(', ');

var contents = asPlaintext('''
$description
Syntax: $syntax
$browsersString
''');
return contents;
}

lsp.Either2<lsp.MarkupContent, String> getMarkdownDescription() {
var browsersString = browsers?.map<String>((b) {
var matches = re.firstMatch(b);
if (matches != null) {
var browser = matches.group(1);
var version = matches.group(2);
return "${browserNames[browser]} $version";
}
return b;
}).join(', ');

var referencesString = references
?.map<String>((r) => '[${r.name}](${r.uri.toString()})')
.join('\n');

var contents = asMarkdown('''
$description
Syntax: $syntax
$referencesString
$browsersString
'''
.trim());
return contents;
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
import 'dart:math';

import 'package:lsp_server/lsp_server.dart' as lsp;
import 'package:sass_api/sass_api.dart' as sass;
import 'package:sass_language_services/sass_language_services.dart';
import 'package:sass_language_services/src/css/entry_status.dart';

import '../../utils/sass_lsp_utils.dart';
import '../language_feature.dart';
import '../node_at_offset_visitor.dart';
import './completion_context.dart';
import './completion_list.dart';

final triggerSuggestCommand = lsp.Command(
title: 'Suggest',
command: 'editor.action.triggerSuggest',
);

// Sort string prefixes
const enums = ' ';
const normal = 'e';
const vendorPrefix = 'o';
const term = 'p';
const variable = 'q';

class CompletionFeature extends LanguageFeature {
CompletionFeature({required super.ls});

Expand Down Expand Up @@ -47,7 +63,7 @@ class CompletionFeature extends LanguageFeature {
lineBeforePosition: lineBeforePosition,
);

for (var i = path.length; i >= 0; i--) {
for (var i = path.length - 1; i >= 0; i--) {
var node = path[i];
if (node is sass.Declaration) {
_declarationCompletion(node, context, result);
Expand Down Expand Up @@ -130,12 +146,9 @@ class CompletionFeature extends LanguageFeature {

// From offset, go back until hitting a newline
var i = offset - 1;
var codeUnit = text.codeUnitAt(i);
const lineFeed = 10; // \n
const carriageReturn = 13; // \r
while (codeUnit != lineFeed && codeUnit != carriageReturn) {
var linebreaks = '\n\r'.codeUnits;
while (i >= 0 && !linebreaks.contains(text.codeUnitAt(i))) {
i--;
codeUnit = text.codeUnitAt(i);
}
var lineBeforePosition = text.substring(i + 1, offset);

Expand All @@ -150,8 +163,63 @@ class CompletionFeature extends LanguageFeature {
return (lineBeforePosition, currentWord);
}

void _declarationCompletion(sass.Declaration node, CompletionContext context,
CompletionList result) {}
void _declarationCompletion(
sass.AstNode node, CompletionContext context, CompletionList result) {
for (var property in cssData.properties) {
var range = context.defaultReplaceRange;
var insertText = property.name;
var triggerSuggest = false;

if (node is sass.Declaration) {
range = toRange(node.name.span);
if (!node.span.text.contains(':')) {
insertText += ': ';
triggerSuggest = true;
}
} else {
insertText += ': ';
triggerSuggest = true;
}

var isDeprecated = property.status == EntryStatus.nonstandard ||
property.status == EntryStatus.obsolete;

if (property.restrictions == null) {
triggerSuggest = false;
}

lsp.Command? command;
if (context.configuration.triggerPropertyValueCompletion &&
triggerSuggest) {
command = triggerSuggestCommand;
}

var relevance = 50;
if (property.relevance case var rel?) {
relevance = min(max(rel, 0), 99);
}

var suffix = (255 - relevance).toRadixString(16);
var prefix = insertText.startsWith('-') ? vendorPrefix : normal;
var sortText = '${prefix}_$suffix';

var item = lsp.CompletionItem(
label: property.name,
documentation: supportsMarkdown()
? property.getMarkdownDescription()
: property.getPlaintextDescription(),
tags: isDeprecated ? [lsp.CompletionItemTag.Deprecated] : [],
textEdit: lsp.Either2.t2(
lsp.TextEdit(range: range, newText: insertText),
),
insertTextFormat: lsp.InsertTextFormat.Snippet,
sortText: sortText,
kind: lsp.CompletionItemKind.Property,
command: command,
);
result.items.add(item);
}
}

void _interpolationCompletion(sass.Interpolation node,
CompletionContext context, CompletionList result) {}
Expand All @@ -166,7 +234,9 @@ class CompletionFeature extends LanguageFeature {
CompletionContext context, CompletionList result) {}

void _styleRuleCompletion(
sass.StyleRule node, CompletionContext context, CompletionList result) {}
sass.StyleRule node, CompletionContext context, CompletionList result) {
_declarationCompletion(node, context, result);
}

void _variableDeclarationCompletion(sass.VariableDeclaration node,
CompletionContext context, CompletionList result) {}
Expand Down
Loading

0 comments on commit 22d7501

Please sign in to comment.