From 73d4ee9085af3c9f48b748713a6e388fdf5b040e Mon Sep 17 00:00:00 2001 From: Kun Ren Date: Wed, 8 Sep 2021 14:39:46 +0800 Subject: [PATCH 1/3] Add object length limit --- R/vsc.R | 27 +++++++++++++++++---------- package.json | 5 +++++ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/R/vsc.R b/R/vsc.R index 43e0cff83..592ea820c 100644 --- a/R/vsc.R +++ b/R/vsc.R @@ -20,6 +20,7 @@ load_settings <- function() { vsc.show_object_size = workspaceViewer$showObjectSize, vsc.rstudioapi = session$emulateRStudioAPI, vsc.str.max.level = session$levelOfObjectDetail, + vsc.object_length_limit = session$objectLengthLimit, vsc.globalenv = session$watchGlobalEnvironment, vsc.plot = session$viewers$viewColumn$plot, vsc.browser = session$viewers$viewColumn$browser, @@ -154,8 +155,7 @@ inspect_env <- function(env, cache) { info <- list( class = class(obj), type = scalar(typeof(obj)), - length = scalar(length(obj)), - str = scalar(trimws(capture_str(obj))) + length = scalar(length(obj)) ) if (show_object_size) { @@ -171,14 +171,21 @@ inspect_env <- function(env, cache) { info$size <- scalar(cobj$size) } - obj_names <- if (is.object(obj)) { - .DollarNames(obj, pattern = "") - } else if (is.recursive(obj)) { - names(obj) - } else NULL - - if (length(obj_names)) { - info$names <- obj_names + length_limit <- getOption("vsc.object_length_limit", 2000) + if (length(obj) > length_limit) { + info$str <- scalar(trimws(capture_str(obj, 0))) + } else { + max_level <- getOption("vsc.str.max.level", 0) + info$str <- scalar(trimws(capture_str(obj, max_level))) + obj_names <- if (is.object(obj)) { + .DollarNames(obj, pattern = "") + } else if (is.recursive(obj)) { + names(obj) + } else NULL + + if (length(obj_names)) { + info$names <- obj_names + } } if (isS4(obj)) { diff --git a/package.json b/package.json index 483f0c24e..a365b40dc 100644 --- a/package.json +++ b/package.json @@ -1398,6 +1398,11 @@ "default": true, "markdownDescription": "Watch the global environment to provide hover, autocompletions, and workspace viewer information. Changes the option `vsc.globalenv` in R. Requires `#r.sessionWatcher#` to be set to `true`." }, + "r.session.objectLengthLimit": { + "type": "integer", + "default": 2000, + "markdownDescription": "The upper limit of object length to show object details in workspace viewer and provide session symbol completion. Decrease this value if you experience significant delay after executing R commands caused by large global objects with many elements. Changes the option `vsc.object_length_limit` in R. Requires `#r.sessionWatcher#` to be set to `true`." + }, "r.session.levelOfObjectDetail": { "type": "string", "markdownDescription": "How much of the object to show on hover, autocompletion, and in the workspace viewer? Changes the option `vsc.str.max.level` in R. Requires `#r.sessionWatcher#` to be set to `true`.", From 2b6743e571946572ea582df99a3157b7d14c672d Mon Sep 17 00:00:00 2001 From: Kun Ren Date: Wed, 8 Sep 2021 15:59:56 +0800 Subject: [PATCH 2/3] Update inspect_env --- R/vsc.R | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/R/vsc.R b/R/vsc.R index 592ea820c..2e0455b52 100644 --- a/R/vsc.R +++ b/R/vsc.R @@ -134,6 +134,8 @@ inspect_env <- function(env, cache) { is_promise <- rlang::env_binding_are_lazy(env, all_names) is_active <- rlang::env_binding_are_active(env, all_names) show_object_size <- getOption("vsc.show_object_size", FALSE) + object_length_limit <- getOption("vsc.object_length_limit", 2000) + str_max_level <- getOption("vsc.str.max.level", 0) objs <- lapply(all_names, function(name) { if (is_promise[[name]]) { info <- list( @@ -171,12 +173,10 @@ inspect_env <- function(env, cache) { info$size <- scalar(cobj$size) } - length_limit <- getOption("vsc.object_length_limit", 2000) - if (length(obj) > length_limit) { + if (length(obj) > object_length_limit) { info$str <- scalar(trimws(capture_str(obj, 0))) } else { - max_level <- getOption("vsc.str.max.level", 0) - info$str <- scalar(trimws(capture_str(obj, max_level))) + info$str <- scalar(trimws(capture_str(obj, str_max_level))) obj_names <- if (is.object(obj)) { .DollarNames(obj, pattern = "") } else if (is.recursive(obj)) { From 9e8cbb20c989df881ea12c640b6ddce432129d56 Mon Sep 17 00:00:00 2001 From: Kun Ren Date: Thu, 9 Sep 2021 11:54:03 +0800 Subject: [PATCH 3/3] Preserve the order of names in completion --- src/completions.ts | 50 ++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/src/completions.ts b/src/completions.ts index 52b9c743e..34e92f2b4 100644 --- a/src/completions.ts +++ b/src/completions.ts @@ -96,7 +96,7 @@ export class LiveCompletionItemProvider implements vscode.CompletionItemProvider const trigger = completionContext.triggerCharacter; if (trigger === undefined) { - Object.keys(session.globalenv).map((key) => { + Object.keys(session.globalenv).forEach((key) => { const obj = session.globalenv[key]; const item = new vscode.CompletionItem( key, @@ -114,36 +114,44 @@ export class LiveCompletionItemProvider implements vscode.CompletionItemProvider const symbol = document.getText(symbolRange); const doc = new vscode.MarkdownString('Element of `' + symbol + '`'); const obj = session.globalenv[symbol]; - let elements: string[]; + let names: string[]; if (obj !== undefined) { if (completionContext.triggerCharacter === '$') { - elements = obj.names; + names = obj.names; } else if (completionContext.triggerCharacter === '@') { - elements = obj.slots; + names = obj.slots; } } - elements.map((key) => { - const item = new vscode.CompletionItem(key, vscode.CompletionItemKind.Field); - item.detail = '[session]'; - item.documentation = doc; - items.push(item); - }); + + if (names) { + items.push(...getCompletionItems(names, vscode.CompletionItemKind.Field, '[session]', doc)); + } } if (trigger === undefined || trigger === '[' || trigger === ',' || trigger === '"' || trigger === '\'') { - const bracketItems = getBracketCompletionItems(document, position, token); - items.push(...bracketItems); + items.push(...getBracketCompletionItems(document, position, token)); } if (trigger === undefined || trigger === '(' || trigger === ',') { - const pipelineItems = getPipelineCompletionItems(document, position, token); - items.push(...pipelineItems); + items.push(...getPipelineCompletionItems(document, position, token)); } return items; } } +function getCompletionItems(names: string[], kind: vscode.CompletionItemKind, detail: string, documentation: vscode.MarkdownString): vscode.CompletionItem[] { + const len = names.length.toString().length; + let index = 0; + return names.map((name) => { + const item = new vscode.CompletionItem(name, kind); + item.detail = detail; + item.documentation = documentation; + item.sortText = `0-${index.toString().padStart(len, '0')}`; + index++; + return item; + }); +} function getBracketCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken) { const items: vscode.CompletionItem[] = []; @@ -181,12 +189,7 @@ function getBracketCompletionItems(document: vscode.TextDocument, position: vsco const obj = session.globalenv[symbol]; if (obj !== undefined && obj.names !== undefined) { const doc = new vscode.MarkdownString('Element of `' + symbol + '`'); - obj.names.map((name: string) => { - const item = new vscode.CompletionItem(name, vscode.CompletionItemKind.Field); - item.detail = '[session]'; - item.documentation = doc; - items.push(item); - }); + items.push(...getCompletionItems(obj.names, vscode.CompletionItemKind.Field, '[session]', doc)); } } return items; @@ -231,12 +234,7 @@ function getPipelineCompletionItems(document: vscode.TextDocument, position: vsc const obj = session.globalenv[symbol]; if (obj !== undefined && obj.names !== undefined) { const doc = new vscode.MarkdownString('Element of `' + symbol + '`'); - obj.names.map((name: string) => { - const item = new vscode.CompletionItem(name, vscode.CompletionItemKind.Field); - item.detail = '[session]'; - item.documentation = doc; - items.push(item); - }); + items.push(...getCompletionItems(obj.names, vscode.CompletionItemKind.Field, '[session]', doc)); } } return items;