Skip to content

Commit 892439b

Browse files
authored
Add object length limit (#778)
* Add object length limit * Update inspect_env * Preserve the order of names in completion
1 parent 1c643ad commit 892439b

3 files changed

Lines changed: 46 additions & 36 deletions

File tree

R/vsc.R

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ load_settings <- function() {
2020
vsc.show_object_size = workspaceViewer$showObjectSize,
2121
vsc.rstudioapi = session$emulateRStudioAPI,
2222
vsc.str.max.level = session$levelOfObjectDetail,
23+
vsc.object_length_limit = session$objectLengthLimit,
2324
vsc.globalenv = session$watchGlobalEnvironment,
2425
vsc.plot = session$viewers$viewColumn$plot,
2526
vsc.browser = session$viewers$viewColumn$browser,
@@ -133,6 +134,8 @@ inspect_env <- function(env, cache) {
133134
is_promise <- rlang::env_binding_are_lazy(env, all_names)
134135
is_active <- rlang::env_binding_are_active(env, all_names)
135136
show_object_size <- getOption("vsc.show_object_size", FALSE)
137+
object_length_limit <- getOption("vsc.object_length_limit", 2000)
138+
str_max_level <- getOption("vsc.str.max.level", 0)
136139
objs <- lapply(all_names, function(name) {
137140
if (is_promise[[name]]) {
138141
info <- list(
@@ -154,8 +157,7 @@ inspect_env <- function(env, cache) {
154157
info <- list(
155158
class = class(obj),
156159
type = scalar(typeof(obj)),
157-
length = scalar(length(obj)),
158-
str = scalar(trimws(capture_str(obj)))
160+
length = scalar(length(obj))
159161
)
160162

161163
if (show_object_size) {
@@ -171,14 +173,19 @@ inspect_env <- function(env, cache) {
171173
info$size <- scalar(cobj$size)
172174
}
173175

174-
obj_names <- if (is.object(obj)) {
175-
.DollarNames(obj, pattern = "")
176-
} else if (is.recursive(obj)) {
177-
names(obj)
178-
} else NULL
179-
180-
if (length(obj_names)) {
181-
info$names <- obj_names
176+
if (length(obj) > object_length_limit) {
177+
info$str <- scalar(trimws(capture_str(obj, 0)))
178+
} else {
179+
info$str <- scalar(trimws(capture_str(obj, str_max_level)))
180+
obj_names <- if (is.object(obj)) {
181+
.DollarNames(obj, pattern = "")
182+
} else if (is.recursive(obj)) {
183+
names(obj)
184+
} else NULL
185+
186+
if (length(obj_names)) {
187+
info$names <- obj_names
188+
}
182189
}
183190

184191
if (isS4(obj)) {

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,6 +1398,11 @@
13981398
"default": true,
13991399
"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`."
14001400
},
1401+
"r.session.objectLengthLimit": {
1402+
"type": "integer",
1403+
"default": 2000,
1404+
"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`."
1405+
},
14011406
"r.session.levelOfObjectDetail": {
14021407
"type": "string",
14031408
"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`.",

src/completions.ts

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export class LiveCompletionItemProvider implements vscode.CompletionItemProvider
9696
const trigger = completionContext.triggerCharacter;
9797

9898
if (trigger === undefined) {
99-
Object.keys(session.globalenv).map((key) => {
99+
Object.keys(session.globalenv).forEach((key) => {
100100
const obj = session.globalenv[key];
101101
const item = new vscode.CompletionItem(
102102
key,
@@ -114,36 +114,44 @@ export class LiveCompletionItemProvider implements vscode.CompletionItemProvider
114114
const symbol = document.getText(symbolRange);
115115
const doc = new vscode.MarkdownString('Element of `' + symbol + '`');
116116
const obj = session.globalenv[symbol];
117-
let elements: string[];
117+
let names: string[];
118118
if (obj !== undefined) {
119119
if (completionContext.triggerCharacter === '$') {
120-
elements = obj.names;
120+
names = obj.names;
121121
} else if (completionContext.triggerCharacter === '@') {
122-
elements = obj.slots;
122+
names = obj.slots;
123123
}
124124
}
125-
elements.map((key) => {
126-
const item = new vscode.CompletionItem(key, vscode.CompletionItemKind.Field);
127-
item.detail = '[session]';
128-
item.documentation = doc;
129-
items.push(item);
130-
});
125+
126+
if (names) {
127+
items.push(...getCompletionItems(names, vscode.CompletionItemKind.Field, '[session]', doc));
128+
}
131129
}
132130

133131
if (trigger === undefined || trigger === '[' || trigger === ',' || trigger === '"' || trigger === '\'') {
134-
const bracketItems = getBracketCompletionItems(document, position, token);
135-
items.push(...bracketItems);
132+
items.push(...getBracketCompletionItems(document, position, token));
136133
}
137134

138135
if (trigger === undefined || trigger === '(' || trigger === ',') {
139-
const pipelineItems = getPipelineCompletionItems(document, position, token);
140-
items.push(...pipelineItems);
136+
items.push(...getPipelineCompletionItems(document, position, token));
141137
}
142138

143139
return items;
144140
}
145141
}
146142

143+
function getCompletionItems(names: string[], kind: vscode.CompletionItemKind, detail: string, documentation: vscode.MarkdownString): vscode.CompletionItem[] {
144+
const len = names.length.toString().length;
145+
let index = 0;
146+
return names.map((name) => {
147+
const item = new vscode.CompletionItem(name, kind);
148+
item.detail = detail;
149+
item.documentation = documentation;
150+
item.sortText = `0-${index.toString().padStart(len, '0')}`;
151+
index++;
152+
return item;
153+
});
154+
}
147155

148156
function getBracketCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken) {
149157
const items: vscode.CompletionItem[] = [];
@@ -181,12 +189,7 @@ function getBracketCompletionItems(document: vscode.TextDocument, position: vsco
181189
const obj = session.globalenv[symbol];
182190
if (obj !== undefined && obj.names !== undefined) {
183191
const doc = new vscode.MarkdownString('Element of `' + symbol + '`');
184-
obj.names.map((name: string) => {
185-
const item = new vscode.CompletionItem(name, vscode.CompletionItemKind.Field);
186-
item.detail = '[session]';
187-
item.documentation = doc;
188-
items.push(item);
189-
});
192+
items.push(...getCompletionItems(obj.names, vscode.CompletionItemKind.Field, '[session]', doc));
190193
}
191194
}
192195
return items;
@@ -231,12 +234,7 @@ function getPipelineCompletionItems(document: vscode.TextDocument, position: vsc
231234
const obj = session.globalenv[symbol];
232235
if (obj !== undefined && obj.names !== undefined) {
233236
const doc = new vscode.MarkdownString('Element of `' + symbol + '`');
234-
obj.names.map((name: string) => {
235-
const item = new vscode.CompletionItem(name, vscode.CompletionItemKind.Field);
236-
item.detail = '[session]';
237-
item.documentation = doc;
238-
items.push(item);
239-
});
237+
items.push(...getCompletionItems(obj.names, vscode.CompletionItemKind.Field, '[session]', doc));
240238
}
241239
}
242240
return items;

0 commit comments

Comments
 (0)