Files
atom/packages/link/lib/link.js
2019-05-31 18:33:56 +02:00

93 lines
2.2 KiB
JavaScript

const url = require('url');
const { shell } = require('electron');
const _ = require('underscore-plus');
const LINK_SCOPE_REGEX = /markup\.underline\.link/;
module.exports = {
activate() {
this.commandDisposable = atom.commands.add(
'atom-text-editor',
'link:open',
() => this.openLink()
);
},
deactivate() {
this.commandDisposable.dispose();
},
openLink() {
const editor = atom.workspace.getActiveTextEditor();
if (editor == null) return;
let link = this.linkUnderCursor(editor);
if (link == null) return;
if (editor.getGrammar().scopeName === 'source.gfm') {
link = this.linkForName(editor, link);
}
const { protocol } = url.parse(link);
if (protocol === 'http:' || protocol === 'https:' || protocol === 'atom:') {
shell.openExternal(link);
}
},
// Get the link under the cursor in the editor
//
// Returns a {String} link or undefined if no link found.
linkUnderCursor(editor) {
const cursorPosition = editor.getCursorBufferPosition();
const link = this.linkAtPosition(editor, cursorPosition);
if (link != null) return link;
// Look for a link to the left of the cursor
if (cursorPosition.column > 0) {
return this.linkAtPosition(editor, cursorPosition.translate([0, -1]));
}
},
// Get the link at the buffer position in the editor.
//
// Returns a {String} link or undefined if no link found.
linkAtPosition(editor, bufferPosition) {
const token = editor.tokenForBufferPosition(bufferPosition);
if (
token &&
token.value &&
token.scopes.some(scope => LINK_SCOPE_REGEX.test(scope))
) {
return token.value;
}
},
// Get the link for the given name.
//
// This is for Markdown links of the style:
//
// ```
// [label][name]
//
// [name]: https://github.com
// ```
//
// Returns a {String} link
linkForName(editor, linkName) {
let link = linkName;
const regex = new RegExp(
`^\\s*\\[${_.escapeRegExp(linkName)}\\]\\s*:\\s*(.+)$`,
'g'
);
editor.backwardsScanInBufferRange(
regex,
[[0, 0], [Infinity, Infinity]],
({ match, stop }) => {
link = match[1];
stop();
}
);
return link;
}
};