Skip to content

Commit 6b3c955

Browse files
authored
Merge branch 'krassowski:master' into master
2 parents ce18086 + 1b18dc3 commit 6b3c955

File tree

10 files changed

+75
-15
lines changed

10 files changed

+75
-15
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
## Changelog
22

3+
### `@krassowski/jupyterlab-lsp 3.8.1` (unreleased)
4+
5+
- bug fixes:
6+
- `%Rdevice` magic is now properly overridden and won't be extracted to R code [(#646)]
7+
8+
[#646]: https://github.com/krassowski/jupyterlab-lsp/pull/646
9+
310
### `@krassowski/jupyterlab-lsp 3.8.0` (2021-07-04)
411

512
- improvements:

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ python scripts/lint.py
332332

333333
### Specs
334334

335-
While language servers can be configured by the user using a simple JSON or Python [configuration file](./Configuring.html#language-servers),
335+
While language servers can be configured by the user using a simple JSON or Python [configuration file](./docs/Configuring.ipynb),
336336
it is preferable to provide users with an option that does not require manual configuration. The language server specifications (specs)
337337
wrap the configuration (as would be defined by the user) into a Python class or function that can be either:
338338

@@ -361,7 +361,7 @@ A spec is a Python callable (a function, or a class with `__call__` method) that
361361

362362
The above example is only intended as an illustration and not as an up-to-date guide.
363363
For details on the dictionary contents, see the [schema][] definition and [built-in specs][].
364-
Basic concepts (meaning of the `argv` and `languages` arguments) are also explained in the [configuration files](./Configuring.html#language-servers) documentation.
364+
Basic concepts (meaning of the `argv` and `languages` arguments) are also explained in the [configuration files](./docs/Configuring.ipynb) documentation.
365365

366366
When contributing a specification we recommend to make use of the helper classes and other [utilities][] that take care of the common use-cases:
367367

packages/jupyterlab-lsp/src/transclusions/ipython-rpy2/extractors.spec.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ describe('IPython rpy2 extractors', () => {
3434
});
3535

3636
describe('%R line magic', () => {
37+
it('should not extract parts of non-code commands', () => {
38+
let code = wrap_in_python_lines('%Rdevice svg');
39+
let { cell_code_kept, foreign_document_map } = extract(code);
40+
41+
expect(cell_code_kept).to.equal(code);
42+
expect(foreign_document_map.size).to.equal(0);
43+
});
44+
3745
it('correctly gives ranges in source', () => {
3846
let code = '%R ggplot()';
3947
let { foreign_document_map } = extract(code);

packages/jupyterlab-lsp/src/transclusions/ipython-rpy2/extractors.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ export let foreign_code_extractors: IForeignCodeExtractorsRegistry = {
5353
language: 'r',
5454
// it is very important to not include the space which will be trimmed in the capture group,
5555
// otherwise the offset will be off by one and the R language server will crash
56-
pattern: '(?:^|\n)%R' + rpy2_args_pattern(RPY2_MAX_ARGS) + ' ?(.*)?\n?',
56+
pattern:
57+
'(?:^|\n)%R' + rpy2_args_pattern(RPY2_MAX_ARGS) + '(?: (.*))?(?:\n|$)',
5758
foreign_capture_groups: [RPY2_MAX_ARGS * 2 + 1],
5859
foreign_replacer: create_rpy_code_extractor(true),
5960
extract_arguments: rpy2_args,

packages/jupyterlab-lsp/src/transclusions/ipython-rpy2/overrides.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,23 @@ describe('rpy2 IPython overrides', () => {
3434
let line_magics = new ReversibleOverridesMap(
3535
overrides.filter(override => override.scope == 'line')
3636
);
37+
38+
it('works with other Rdevice', () => {
39+
let line = '%Rdevice svg';
40+
let override = line_magics.override_for(line);
41+
expect(override).to.equal(
42+
'rpy2.ipython.rmagic.RMagics.Rdevice(" svg", "")'
43+
);
44+
let reverse = line_magics.reverse.override_for(override);
45+
expect(reverse).to.equal(line);
46+
});
47+
48+
it('does not overwrite non-rpy2 magics', () => {
49+
let line = '%RestMagic';
50+
let override = line_magics.override_for(line);
51+
expect(override).to.equal(null);
52+
});
53+
3754
it('works with the short form arguments, inputs and outputs', () => {
3855
let line = '%R -i x';
3956
let override = line_magics.override_for(line);

packages/jupyterlab-lsp/src/transclusions/ipython-rpy2/overrides.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,17 @@ export let overrides: IScopedCodeOverride[] = [
1313
{
1414
// support up to 10 arguments
1515
pattern:
16-
LINE_MAGIC_PREFIX + '%R' + rpy2_args_pattern(RPY2_MAX_ARGS) + '(.*)(\n)?',
16+
LINE_MAGIC_PREFIX +
17+
'%R' +
18+
rpy2_args_pattern(RPY2_MAX_ARGS) +
19+
'( .*)?(\n|$)',
1720
replacement: (match, prefix, ...args) => {
1821
let r = parse_r_args(args, -4);
1922
// note: only supports assignment or -o/--output, not both
2023
// TODO assignment like in x = %R 1 should be distinguished from -o
21-
return `${prefix}${r.outputs}rpy2.ipython.rmagic.RMagics.R("${r.content}", "${r.others}"${r.inputs})`;
24+
return `${prefix}${r.outputs}rpy2.ipython.rmagic.RMagics.R("${
25+
r.content || ''
26+
}", "${r.others}"${r.inputs})`;
2227
},
2328
scope: 'line',
2429
reverse: {
@@ -47,5 +52,20 @@ export let overrides: IScopedCodeOverride[] = [
4752
},
4853
scope: 'cell'
4954
}
55+
},
56+
{
57+
pattern: LINE_MAGIC_PREFIX + '%Rdevice( .*)?(\n|$)',
58+
replacement: (match, prefix, ...args) => {
59+
return `${prefix}rpy2.ipython.rmagic.RMagics.Rdevice("${args[0]}", "")`;
60+
},
61+
scope: 'line',
62+
reverse: {
63+
pattern: rpy2_reverse_pattern('"', false, 'Rdevice'),
64+
replacement: (match, ...args) => {
65+
let r = rpy2_reverse_replacement(match, ...args);
66+
return '%Rdevice' + r.input + r.output + r.other + r.contents;
67+
},
68+
scope: 'line'
69+
}
5070
}
5171
];

packages/jupyterlab-lsp/src/transclusions/ipython-rpy2/rpy2.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,17 @@ export function parse_r_args(args: string[], content_position: number) {
4646
};
4747
}
4848

49-
export function rpy2_reverse_pattern(quote = '"', multi_line = false): string {
49+
export function rpy2_reverse_pattern(
50+
quote = '"',
51+
multi_line = false,
52+
magic = 'R'
53+
): string {
5054
return (
5155
'(\\S+)?' +
5256
'(?:, (\\S+))?'.repeat(9) +
53-
'( = )?rpy2\\.ipython\\.rmagic\\.RMagics.R\\(' +
57+
'( = )?rpy2\\.ipython\\.rmagic\\.RMagics.' +
58+
magic +
59+
'\\(' +
5460
quote +
5561
(multi_line ? '([\\s\\S]*)' : '(.*?)') +
5662
quote +

python_packages/jupyter_lsp/jupyter_lsp/specs/utils.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,11 @@ def __call__(self, mgr: LanguageServerManagerAPI) -> KeyedLanguageServerSpecs:
141141
troubleshooting.append(spec["troubleshoot"])
142142
spec["troubleshoot"] = "\n\n".join(troubleshooting)
143143

144+
is_installed = self.is_installed(mgr)
145+
144146
return {
145147
self.key: {
146-
"argv": [mgr.nodejs, node_module, *self.args],
148+
"argv": ([mgr.nodejs, node_module, *self.args] if is_installed else []),
147149
"languages": self.languages,
148150
"version": SPEC_VERSION,
149151
**spec,

requirements/lint.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ dependencies:
1010
- isort
1111
- mypy
1212
- robotframework-lint >=1.1
13-
- robotframework >=4
13+
- robotframework >=4,<4.1
1414
- pytest-tornasync
15-
- pip:
16-
- types-six
15+
- types-six

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2000,7 +2000,7 @@
20002000
"@jupyterlab/application" "^3.0.0"
20012001

20022002
"@krassowski/jupyterlab-lsp@file:packages/jupyterlab-lsp":
2003-
version "3.7.0"
2003+
version "3.8.0"
20042004
dependencies:
20052005
"@krassowski/code-jumpers" "~1.1.0"
20062006
"@krassowski/completion-theme" "~3.1.0"
@@ -14850,9 +14850,9 @@ uri-js@^4.2.2:
1485014850
punycode "^2.1.0"
1485114851

1485214852
urijs@^1.19.1:
14853-
version "1.19.6"
14854-
resolved "https://registry.yarnpkg.com/urijs/-/urijs-1.19.6.tgz#51f8cb17ca16faefb20b9a31ac60f84aa2b7c870"
14855-
integrity sha512-eSXsXZ2jLvGWeLYlQA3Gh36BcjF+0amo92+wHPyN1mdR8Nxf75fuEuYTd9c0a+m/vhCjRK0ESlE9YNLW+E1VEw==
14853+
version "1.19.7"
14854+
resolved "https://registry.yarnpkg.com/urijs/-/urijs-1.19.7.tgz#4f594e59113928fea63c00ce688fb395b1168ab9"
14855+
integrity sha512-Id+IKjdU0Hx+7Zx717jwLPsPeUqz7rAtuVBRLLs+qn+J2nf9NGITWVCxcijgYxBqe83C7sqsQPs6H1pyz3x9gA==
1485614856

1485714857
urix@^0.1.0:
1485814858
version "0.1.0"

0 commit comments

Comments
 (0)