123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- 'use babel';
- import _ from 'underscore-plus';
- import { CompositeDisposable, Disposable } from 'atom';
- import { Selector } from './selector';
- import StatusBarItem from './status-bar-item';
- import helpers from './helpers';
- const LineEndingRegExp = /\r\n|\n/g;
- // the following regular expression is executed natively via the `substring` package,
- // where `\A` corresponds to the beginning of the string.
- // More info: https://github.com/atom/line-ending-selector/pull/56
- // eslint-disable-next-line no-useless-escape
- const LFRegExp = /(\A|[^\r])\n/g;
- const CRLFRegExp = /\r\n/g;
- let disposables = null;
- export function activate() {
- disposables = new CompositeDisposable();
- let selectorDisposable;
- let selector;
- disposables.add(
- atom.commands.add('atom-text-editor', {
- 'line-ending-selector:show': () => {
- // Initiating Selector object - called only once when `line-ending-selector:show` is called
- if (!selectorDisposable) {
- // make a Selector object
- selector = new Selector([
- { name: 'LF', value: '\n' },
- { name: 'CRLF', value: '\r\n' }
- ]);
- // Add disposable for selector
- selectorDisposable = new Disposable(() => selector.dispose());
- disposables.add(selectorDisposable);
- }
- selector.show();
- },
- 'line-ending-selector:convert-to-LF': event => {
- const editorElement = event.target.closest('atom-text-editor');
- setLineEnding(editorElement.getModel(), '\n');
- },
- 'line-ending-selector:convert-to-CRLF': event => {
- const editorElement = event.target.closest('atom-text-editor');
- setLineEnding(editorElement.getModel(), '\r\n');
- }
- })
- );
- }
- export function deactivate() {
- disposables.dispose();
- }
- export function consumeStatusBar(statusBar) {
- let statusBarItem = new StatusBarItem();
- let currentBufferDisposable = null;
- let tooltipDisposable = null;
- const updateTile = _.debounce(buffer => {
- getLineEndings(buffer).then(lineEndings => {
- if (lineEndings.size === 0) {
- let defaultLineEnding = getDefaultLineEnding();
- buffer.setPreferredLineEnding(defaultLineEnding);
- lineEndings = new Set().add(defaultLineEnding);
- }
- statusBarItem.setLineEndings(lineEndings);
- });
- }, 0);
- disposables.add(
- atom.workspace.observeActiveTextEditor(editor => {
- if (currentBufferDisposable) currentBufferDisposable.dispose();
- if (editor && editor.getBuffer) {
- let buffer = editor.getBuffer();
- updateTile(buffer);
- currentBufferDisposable = buffer.onDidChange(({ oldText, newText }) => {
- if (!statusBarItem.hasLineEnding('\n')) {
- if (newText.indexOf('\n') >= 0) {
- updateTile(buffer);
- }
- } else if (!statusBarItem.hasLineEnding('\r\n')) {
- if (newText.indexOf('\r\n') >= 0) {
- updateTile(buffer);
- }
- } else if (oldText.indexOf('\n')) {
- updateTile(buffer);
- }
- });
- } else {
- statusBarItem.setLineEndings(new Set());
- currentBufferDisposable = null;
- }
- if (tooltipDisposable) {
- disposables.remove(tooltipDisposable);
- tooltipDisposable.dispose();
- }
- tooltipDisposable = atom.tooltips.add(statusBarItem.element, {
- title() {
- return `File uses ${statusBarItem.description()} line endings`;
- }
- });
- disposables.add(tooltipDisposable);
- })
- );
- disposables.add(
- new Disposable(() => {
- if (currentBufferDisposable) currentBufferDisposable.dispose();
- })
- );
- statusBarItem.onClick(() => {
- const editor = atom.workspace.getActiveTextEditor();
- atom.commands.dispatch(
- atom.views.getView(editor),
- 'line-ending-selector:show'
- );
- });
- let tile = statusBar.addRightTile({ item: statusBarItem, priority: 200 });
- disposables.add(new Disposable(() => tile.destroy()));
- }
- function getDefaultLineEnding() {
- switch (atom.config.get('line-ending-selector.defaultLineEnding')) {
- case 'LF':
- return '\n';
- case 'CRLF':
- return '\r\n';
- case 'OS Default':
- default:
- return helpers.getProcessPlatform() === 'win32' ? '\r\n' : '\n';
- }
- }
- function getLineEndings(buffer) {
- if (typeof buffer.find === 'function') {
- return Promise.all([buffer.find(LFRegExp), buffer.find(CRLFRegExp)]).then(
- ([hasLF, hasCRLF]) => {
- const result = new Set();
- if (hasLF) result.add('\n');
- if (hasCRLF) result.add('\r\n');
- return result;
- }
- );
- } else {
- return new Promise(resolve => {
- const result = new Set();
- for (let i = 0; i < buffer.getLineCount() - 1; i++) {
- result.add(buffer.lineEndingForRow(i));
- }
- resolve(result);
- });
- }
- }
- export function setLineEnding(item, lineEnding) {
- if (item && item.getBuffer) {
- let buffer = item.getBuffer();
- buffer.setPreferredLineEnding(lineEnding);
- buffer.setText(buffer.getText().replace(LineEndingRegExp, lineEnding));
- }
- }
|