Skip to content

Commit efa56c0

Browse files
authored
Merge pull request #4 from Belar/feat/hyperclick-provider
feat: add hyperclick provider
2 parents 1a9f75e + c1fdd16 commit efa56c0

File tree

6 files changed

+191
-6
lines changed

6 files changed

+191
-6
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ A replacement of the definitions functionality from the original Atom-IDE / Nucl
1919

2020
You can also search for [packages](https://atom.io/packages/search?q=IDE) in Atom.
2121

22+
3. (Optional) Install [hyperclick](https://atom.io/packages/hyperclick) for `cmd/ctrl+click` support
23+
You can set [priority and grammar scope](https://github.com/facebookarchive/hyperclick#details) in extension settings
24+
2225
## Contributing
2326

2427
Please see the [contributing guidelines](CONTRIBUTING.md).

lib/clickProvider.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use babel';
2+
3+
export class ClickProvider {
4+
constructor(options) {
5+
this.clickHandler = options.clickHandler;
6+
7+
this.suggestionForWordHandler = this.suggestionForWordHandler.bind(this);
8+
this.getProvider = this.getProvider.bind(this);
9+
}
10+
11+
suggestionForWordHandler(textEditor, text, range) {
12+
const targetValue = text && text.trim();
13+
if (!targetValue) return;
14+
15+
return {
16+
range,
17+
callback: () => this.clickHandler(),
18+
};
19+
}
20+
21+
getProvider() {
22+
const grammarScopes = atom.config.get(
23+
'atom-ide-definitions.clickGrammarScopes'
24+
);
25+
const priority = atom.config.get('atom-ide-definitions.clickPriority');
26+
27+
return {
28+
priority,
29+
// Assign value only if at least one scope is available. Falsey triggers default behaviour, "apply to all".
30+
grammarScopes:
31+
(grammarScopes && !!grammarScopes[0] && grammarScopes) || null,
32+
getSuggestionForWord: this.suggestionForWordHandler,
33+
};
34+
}
35+
}

lib/main.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
'use babel';
22

33
import { CompositeDisposable } from 'atom';
4+
import { install as installPackageDependencies } from 'atom-package-deps';
45
import goToDefinition from './goToDefinition';
56
import createProviderRegistry from './providerRegistry';
7+
import { ClickProvider } from './clickProvider';
68

79
function package() {
810
const providerRegistry = createProviderRegistry();
11+
const clickProvider = new ClickProvider({
12+
clickHandler: () => goToDefinition(providerRegistry),
13+
});
914
let subscriptions;
1015

1116
function activate() {
@@ -17,6 +22,8 @@ function package() {
1722
goToDefinition(providerRegistry),
1823
})
1924
);
25+
26+
installPackageDependencies('atom-ide-definitions');
2027
}
2128

2229
function deactivate() {
@@ -27,7 +34,12 @@ function package() {
2734
providerRegistry.addProvider(provider);
2835
}
2936

30-
return { activate, deactivate, consumeDefinitionsService };
37+
return {
38+
activate,
39+
deactivate,
40+
consumeDefinitionsService,
41+
getClickProvider: clickProvider.getProvider,
42+
};
3143
}
3244

3345
export default package();

package-lock.json

Lines changed: 37 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,13 @@
88
"atom-ide",
99
"defintion"
1010
],
11-
"activationCommands": {
12-
"atom-workspace": "atom-ide-go-to-definition:go-to-definition"
13-
},
1411
"repository": "https://github.com/atom-ide-community/atom-ide-definitions",
1512
"license": "MIT",
1613
"engines": {
1714
"atom": ">=1.0.0 <2.0.0"
1815
},
1916
"dependencies": {
17+
"atom-package-deps": "^5.0.0",
2018
"atom-languageclient": "^0.9.9"
2119
},
2220
"devDependencies": {
@@ -44,11 +42,40 @@
4442
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
4543
}
4644
},
45+
"package-deps": [
46+
"hyperclick"
47+
],
4748
"consumedServices": {
4849
"definitions": {
4950
"versions": {
5051
"0.1.0": "consumeDefinitionsService"
5152
}
5253
}
54+
},
55+
"providedServices": {
56+
"hyperclick": {
57+
"versions": {
58+
"0.1.0": "getClickProvider"
59+
}
60+
}
61+
},
62+
"configSchema": {
63+
"clickPriority": {
64+
"order": 1,
65+
"title": "Hyperclick Provider Priority",
66+
"description": "Provider priority relative to other providers. For more details see [Hyperclick's provider documentation](https://github.com/facebookarchive/hyperclick#details).",
67+
"type": "number",
68+
"default": 0
69+
},
70+
"clickGrammarScopes": {
71+
"order": 2,
72+
"title": "Hyperclick Grammar Scopes",
73+
"description": "List of scopes to allow action on. For example, `source.js, source.ts, source.go` *Requires reload to take effect.*",
74+
"type": "array",
75+
"default": [],
76+
"items": {
77+
"type": "string"
78+
}
79+
}
5380
}
5481
}

spec/atom-ide-click-spec.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
'use babel';
2+
3+
import { ClickProvider } from '../lib/clickProvider';
4+
5+
// Use the command `window:run-package-specs` (cmd-alt-ctrl-p) to run specs.
6+
//
7+
// To run a specific `it` or `describe` block add an `f` to the front (e.g. `fit`
8+
// or `fdescribe`). Remove the `f` to unfocus the block.
9+
10+
let clickProvider;
11+
const clickHandlers = {
12+
goToDefinitions: () => {},
13+
};
14+
15+
describe('AtomIdeClick', () => {
16+
beforeEach(function() {
17+
spyOn(atom.config, 'get').andCallFake(function(value) {
18+
const config = {
19+
'atom-ide-definitions.clickGrammarScopes': [],
20+
'atom-ide-definitions.clickPriority': 0,
21+
};
22+
return config[value];
23+
});
24+
25+
spyOn(clickHandlers, 'goToDefinitions');
26+
27+
clickProvider = new ClickProvider({
28+
clickHandler: clickHandlers.goToDefinitions,
29+
});
30+
});
31+
32+
it('verify provider result', () => {
33+
const provider = clickProvider.getProvider();
34+
35+
expect(provider.priority).toEqual(0);
36+
expect(provider.grammarScopes).toBeNull();
37+
expect(typeof provider.getSuggestionForWord).toEqual('function');
38+
});
39+
40+
it('verify suggestionForWord result', () => {
41+
const suggestionForWord = clickProvider.suggestionForWordHandler(
42+
'FakeEditor',
43+
'FakeText',
44+
'FakeRange'
45+
);
46+
47+
expect(suggestionForWord.range).toEqual('FakeRange');
48+
expect(typeof suggestionForWord.callback).toEqual('function');
49+
});
50+
51+
it('verify suggestionForWord handler stops if there is no text value', () => {
52+
const suggestionForWord = clickProvider.suggestionForWordHandler(
53+
'FakeEditor',
54+
'',
55+
'FakeRange'
56+
);
57+
58+
expect(suggestionForWord).toBeUndefined();
59+
});
60+
61+
it('verify suggestionForWord callback assignment', () => {
62+
const suggestionForWord = clickProvider.suggestionForWordHandler(
63+
'FakeEditor',
64+
'FakeText',
65+
'FakeRange'
66+
);
67+
68+
expect(typeof suggestionForWord.callback).toEqual('function');
69+
70+
suggestionForWord.callback();
71+
expect(clickHandlers.goToDefinitions).toHaveBeenCalled();
72+
});
73+
});

0 commit comments

Comments
 (0)