Manual decaf status-bar source

This commit is contained in:
confused-Techie 2023-09-04 03:01:39 -07:00
parent 0c10f0a775
commit 5895c21048
16 changed files with 140 additions and 908 deletions

View File

@ -1,63 +0,0 @@
{Disposable} = require 'atom'
module.exports =
class CursorPositionView
constructor: ->
@viewUpdatePending = false
@element = document.createElement('status-bar-cursor')
@element.classList.add('cursor-position', 'inline-block')
@goToLineLink = document.createElement('a')
@goToLineLink.classList.add('inline-block')
@element.appendChild(@goToLineLink)
@formatString = atom.config.get('status-bar.cursorPositionFormat') ? '%L:%C'
@activeItemSubscription = atom.workspace.onDidChangeActiveTextEditor (activeEditor) => @subscribeToActiveTextEditor()
@subscribeToConfig()
@subscribeToActiveTextEditor()
@tooltip = atom.tooltips.add(@element, title: => "Line #{@row}, Column #{@column}")
@handleClick()
destroy: ->
@activeItemSubscription.dispose()
@cursorSubscription?.dispose()
@tooltip.dispose()
@configSubscription?.dispose()
@clickSubscription.dispose()
@updateSubscription?.dispose()
subscribeToActiveTextEditor: ->
@cursorSubscription?.dispose()
selectionsMarkerLayer = atom.workspace.getActiveTextEditor()?.selectionsMarkerLayer
@cursorSubscription = selectionsMarkerLayer?.onDidUpdate(@scheduleUpdate.bind(this))
@scheduleUpdate()
subscribeToConfig: ->
@configSubscription?.dispose()
@configSubscription = atom.config.observe 'status-bar.cursorPositionFormat', (value) =>
@formatString = value ? '%L:%C'
@scheduleUpdate()
handleClick: ->
clickHandler = -> atom.commands.dispatch(atom.views.getView(atom.workspace.getActiveTextEditor()), 'go-to-line:toggle')
@element.addEventListener('click', clickHandler)
@clickSubscription = new Disposable => @element.removeEventListener('click', clickHandler)
scheduleUpdate: ->
return if @viewUpdatePending
@viewUpdatePending = true
@updateSubscription = atom.views.updateDocument =>
@viewUpdatePending = false
if position = atom.workspace.getActiveTextEditor()?.getCursorBufferPosition()
@row = position.row + 1
@column = position.column + 1
@goToLineLink.textContent = @formatString.replace('%L', @row).replace('%C', @column)
@element.classList.remove('hide')
else
@goToLineLink.textContent = ''
@element.classList.add('hide')

View File

@ -1,17 +1,8 @@
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS104: Avoid inline assignments
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
let CursorPositionView;
const {Disposable} = require('atom');
module.exports =
(CursorPositionView = class CursorPositionView {
class CursorPositionView {
constructor() {
let left;
this.viewUpdatePending = false;
this.element = document.createElement('status-bar-cursor');
@ -20,7 +11,7 @@ module.exports =
this.goToLineLink.classList.add('inline-block');
this.element.appendChild(this.goToLineLink);
this.formatString = (left = atom.config.get('status-bar.cursorPositionFormat')) != null ? left : '%L:%C';
this.formatString = atom.config.get('status-bar.cursorPositionFormat') ?? '%L:%C';
this.activeItemSubscription = atom.workspace.onDidChangeActiveTextEditor(activeEditor => this.subscribeToActiveTextEditor());
@ -38,46 +29,46 @@ module.exports =
this.tooltip.dispose();
this.configSubscription?.dispose();
this.clickSubscription.dispose();
return this.updateSubscription?.dispose();
this.updateSubscription?.dispose();
}
subscribeToActiveTextEditor() {
this.cursorSubscription?.dispose();
const selectionsMarkerLayer = atom.workspace.getActiveTextEditor()?.selectionsMarkerLayer;
this.cursorSubscription = selectionsMarkerLayer?.onDidUpdate(this.scheduleUpdate.bind(this));
return this.scheduleUpdate();
this.scheduleUpdate();
}
subscribeToConfig() {
this.configSubscription?.dispose();
return this.configSubscription = atom.config.observe('status-bar.cursorPositionFormat', value => {
this.configSubscription = atom.config.observe('status-bar.cursorPositionFormat', value => {
this.formatString = value != null ? value : '%L:%C';
return this.scheduleUpdate();
this.scheduleUpdate();
});
}
handleClick() {
const clickHandler = () => atom.commands.dispatch(atom.views.getView(atom.workspace.getActiveTextEditor()), 'go-to-line:toggle');
this.element.addEventListener('click', clickHandler);
return this.clickSubscription = new Disposable(() => this.element.removeEventListener('click', clickHandler));
this.clickSubscription = new Disposable(() => this.element.removeEventListener('click', clickHandler));
}
scheduleUpdate() {
if (this.viewUpdatePending) { return; }
this.viewUpdatePending = true;
return this.updateSubscription = atom.views.updateDocument(() => {
let position;
this.updateSubscription = atom.views.updateDocument(() => {
const position = atom.workspace.getActiveTextEditor()?.getCursorBufferPosition();
this.viewUpdatePending = false;
if (position = atom.workspace.getActiveTextEditor()?.getCursorBufferPosition()) {
if (position) {
this.row = position.row + 1;
this.column = position.column + 1;
this.goToLineLink.textContent = this.formatString.replace('%L', this.row).replace('%C', this.column);
return this.element.classList.remove('hide');
this.element.classList.remove('hide');
} else {
this.goToLineLink.textContent = '';
return this.element.classList.add('hide');
this.element.classList.add('hide');
}
});
}
});
}

View File

@ -1,118 +0,0 @@
{Disposable} = require 'atom'
url = require 'url'
fs = require 'fs-plus'
module.exports =
class FileInfoView
constructor: ->
@element = document.createElement('status-bar-file')
@element.classList.add('file-info', 'inline-block')
@currentPath = document.createElement('a')
@currentPath.classList.add('current-path')
@element.appendChild(@currentPath)
@element.currentPath = @currentPath
@element.getActiveItem = @getActiveItem.bind(this)
@activeItemSubscription = atom.workspace.getCenter().onDidChangeActivePaneItem =>
@subscribeToActiveItem()
@subscribeToActiveItem()
@registerTooltip()
clickHandler = (event) =>
isShiftClick = event.shiftKey
@showCopiedTooltip(isShiftClick)
text = @getActiveItemCopyText(isShiftClick)
atom.clipboard.write(text)
setTimeout =>
@clearCopiedTooltip()
, 2000
@element.addEventListener('click', clickHandler)
@clickSubscription = new Disposable => @element.removeEventListener('click', clickHandler)
registerTooltip: ->
@tooltip = atom.tooltips.add(@element, title: ->
"Click to copy absolute file path (Shift + Click to copy relative path)")
clearCopiedTooltip: ->
@copiedTooltip?.dispose()
@registerTooltip()
showCopiedTooltip: (copyRelativePath) ->
@tooltip?.dispose()
@copiedTooltip?.dispose()
text = @getActiveItemCopyText(copyRelativePath)
@copiedTooltip = atom.tooltips.add @element,
title: "Copied: #{text}"
trigger: 'manual'
delay:
show: 0
getActiveItemCopyText: (copyRelativePath) ->
activeItem = @getActiveItem()
path = activeItem?.getPath?()
return activeItem?.getTitle?() or '' if not path?
# Make sure we try to relativize before parsing URLs.
if copyRelativePath
relativized = atom.project.relativize(path)
if relativized isnt path
return relativized
# An item path could be a url, we only want to copy the `path` part
if path?.indexOf('://') > 0
path = url.parse(path).path
path
subscribeToActiveItem: ->
@modifiedSubscription?.dispose()
@titleSubscription?.dispose()
if activeItem = @getActiveItem()
@updateCallback ?= => @update()
if typeof activeItem.onDidChangeTitle is 'function'
@titleSubscription = activeItem.onDidChangeTitle(@updateCallback)
else if typeof activeItem.on is 'function'
#TODO Remove once title-changed event support is removed
activeItem.on('title-changed', @updateCallback)
@titleSubscription = dispose: =>
activeItem.off?('title-changed', @updateCallback)
@modifiedSubscription = activeItem.onDidChangeModified?(@updateCallback)
@update()
destroy: ->
@activeItemSubscription.dispose()
@titleSubscription?.dispose()
@modifiedSubscription?.dispose()
@clickSubscription?.dispose()
@copiedTooltip?.dispose()
@tooltip?.dispose()
getActiveItem: ->
atom.workspace.getCenter().getActivePaneItem()
update: ->
@updatePathText()
@updateBufferHasModifiedText(@getActiveItem()?.isModified?())
updateBufferHasModifiedText: (isModified) ->
if isModified
@element.classList.add('buffer-modified')
@isModified = true
else
@element.classList.remove('buffer-modified')
@isModified = false
updatePathText: ->
if path = @getActiveItem()?.getPath?()
relativized = atom.project.relativize(path)
@currentPath.textContent = if relativized? then fs.tildify(relativized) else path
else if title = @getActiveItem()?.getTitle?()
@currentPath.textContent = title
else
@currentPath.textContent = ''

View File

@ -1,16 +1,9 @@
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
let FileInfoView;
const {Disposable} = require('atom');
const { Disposable } = require('atom');
const url = require('url');
const fs = require('fs-plus');
module.exports =
(FileInfoView = class FileInfoView {
class FileInfoView {
constructor() {
this.element = document.createElement('status-bar-file');
this.element.classList.add('file-info', 'inline-block');
@ -23,7 +16,7 @@ module.exports =
this.element.getActiveItem = this.getActiveItem.bind(this);
this.activeItemSubscription = atom.workspace.getCenter().onDidChangeActivePaneItem(() => {
return this.subscribeToActiveItem();
this.subscribeToActiveItem();
});
this.subscribeToActiveItem();
@ -44,7 +37,7 @@ module.exports =
}
registerTooltip() {
return this.tooltip = atom.tooltips.add(this.element, { title() {
this.tooltip = atom.tooltips.add(this.element, { title() {
return "Click to copy absolute file path (Shift + Click to copy relative path)";
}
});
@ -52,14 +45,14 @@ module.exports =
clearCopiedTooltip() {
this.copiedTooltip?.dispose();
return this.registerTooltip();
this.registerTooltip();
}
showCopiedTooltip(copyRelativePath) {
this.tooltip?.dispose();
this.copiedTooltip?.dispose();
const text = this.getActiveItemCopyText(copyRelativePath);
return this.copiedTooltip = atom.tooltips.add(this.element, {
this.copiedTooltip = atom.tooltips.add(this.element, {
title: `Copied: ${text}`,
trigger: 'manual',
delay: {
@ -92,11 +85,11 @@ module.exports =
}
subscribeToActiveItem() {
let activeItem;
this.modifiedSubscription?.dispose();
this.titleSubscription?.dispose();
const activeItem = this.getActiveItem();
if (activeItem = this.getActiveItem()) {
if (activeItem) {
if (this.updateCallback == null) { this.updateCallback = () => this.update(); }
if (typeof activeItem.onDidChangeTitle === 'function') {
@ -113,7 +106,7 @@ module.exports =
this.modifiedSubscription = activeItem.onDidChangeModified?.(this.updateCallback);
}
return this.update();
this.update();
}
destroy() {
@ -122,7 +115,7 @@ module.exports =
this.modifiedSubscription?.dispose();
this.clickSubscription?.dispose();
this.copiedTooltip?.dispose();
return this.tooltip?.dispose();
this.tooltip?.dispose();
}
getActiveItem() {
@ -131,28 +124,30 @@ module.exports =
update() {
this.updatePathText();
return this.updateBufferHasModifiedText(this.getActiveItem()?.isModified?.());
this.updateBufferHasModifiedText(this.getActiveItem()?.isModified?.());
}
updateBufferHasModifiedText(isModified) {
if (isModified) {
this.element.classList.add('buffer-modified');
return this.isModified = true;
this.isModified = true;
} else {
this.element.classList.remove('buffer-modified');
return this.isModified = false;
this.isModified = false;
}
}
updatePathText() {
let path, title;
if (path = this.getActiveItem()?.getPath?.()) {
const path = this.getActiveItem()?.getPath?.();
const title = this.getActiveItem()?.getTitle?.();
if (path) {
const relativized = atom.project.relativize(path);
return this.currentPath.textContent = (relativized != null) ? fs.tildify(relativized) : path;
} else if ((title = this.getActiveItem()?.getTitle?.())) {
return this.currentPath.textContent = title;
this.currentPath.textContent = (relativized != null) ? fs.tildify(relativized) : path;
} else if (title) {
this.currentPath.textContent = title;
} else {
return this.currentPath.textContent = '';
this.currentPath.textContent = '';
}
}
});
}

View File

@ -1,222 +0,0 @@
_ = require "underscore-plus"
{CompositeDisposable, GitRepositoryAsync} = require "atom"
module.exports =
class GitView
constructor: ->
@element = document.createElement('status-bar-git')
@element.classList.add('git-view')
@createBranchArea()
@createCommitsArea()
@createStatusArea()
@activeItemSubscription = atom.workspace.getCenter().onDidChangeActivePaneItem =>
@subscribeToActiveItem()
@projectPathSubscription = atom.project.onDidChangePaths =>
@subscribeToRepositories()
@subscribeToRepositories()
@subscribeToActiveItem()
createBranchArea: ->
@branchArea = document.createElement('div')
@branchArea.classList.add('git-branch', 'inline-block')
@element.appendChild(@branchArea)
@element.branchArea = @branchArea
branchIcon = document.createElement('span')
branchIcon.classList.add('icon', 'icon-git-branch')
@branchArea.appendChild(branchIcon)
@branchLabel = document.createElement('span')
@branchLabel.classList.add('branch-label')
@branchArea.appendChild(@branchLabel)
@element.branchLabel = @branchLabel
createCommitsArea: ->
@commitsArea = document.createElement('div')
@commitsArea.classList.add('git-commits', 'inline-block')
@element.appendChild(@commitsArea)
@commitsAhead = document.createElement('span')
@commitsAhead.classList.add('icon', 'icon-arrow-up', 'commits-ahead-label')
@commitsArea.appendChild(@commitsAhead)
@commitsBehind = document.createElement('span')
@commitsBehind.classList.add('icon', 'icon-arrow-down', 'commits-behind-label')
@commitsArea.appendChild(@commitsBehind)
createStatusArea: ->
@gitStatus = document.createElement('div')
@gitStatus.classList.add('git-status', 'inline-block')
@element.appendChild(@gitStatus)
@gitStatusIcon = document.createElement('span')
@gitStatusIcon.classList.add('icon')
@gitStatus.appendChild(@gitStatusIcon)
@element.gitStatusIcon = @gitStatusIcon
subscribeToActiveItem: ->
activeItem = @getActiveItem()
@savedSubscription?.dispose()
@savedSubscription = activeItem?.onDidSave? => @update()
@update()
subscribeToRepositories: ->
@repositorySubscriptions?.dispose()
@repositorySubscriptions = new CompositeDisposable
for repo in atom.project.getRepositories() when repo?
@repositorySubscriptions.add repo.onDidChangeStatus ({path, status}) =>
@update() if path is @getActiveItemPath()
@repositorySubscriptions.add repo.onDidChangeStatuses =>
@update()
destroy: ->
@activeItemSubscription?.dispose()
@projectPathSubscription?.dispose()
@savedSubscription?.dispose()
@repositorySubscriptions?.dispose()
@branchTooltipDisposable?.dispose()
@commitsAheadTooltipDisposable?.dispose()
@commitsBehindTooltipDisposable?.dispose()
@statusTooltipDisposable?.dispose()
getActiveItemPath: ->
@getActiveItem()?.getPath?()
getRepositoryForActiveItem: ->
[rootDir] = atom.project.relativizePath(@getActiveItemPath())
rootDirIndex = atom.project.getPaths().indexOf(rootDir)
if rootDirIndex >= 0
atom.project.getRepositories()[rootDirIndex]
else
for repo in atom.project.getRepositories() when repo
return repo
getActiveItem: ->
atom.workspace.getCenter().getActivePaneItem()
update: ->
repo = @getRepositoryForActiveItem()
@updateBranchText(repo)
@updateAheadBehindCount(repo)
@updateStatusText(repo)
updateBranchText: (repo) ->
if @showGitInformation(repo)
head = repo.getShortHead(@getActiveItemPath())
@branchLabel.textContent = head
@branchArea.style.display = '' if head
@branchTooltipDisposable?.dispose()
@branchTooltipDisposable = atom.tooltips.add @branchArea, title: "On branch #{head}"
else
@branchArea.style.display = 'none'
showGitInformation: (repo) ->
return false unless repo?
if itemPath = @getActiveItemPath()
atom.project.contains(itemPath)
else
not @getActiveItem()?
updateAheadBehindCount: (repo) ->
unless @showGitInformation(repo)
@commitsArea.style.display = 'none'
return
itemPath = @getActiveItemPath()
{ahead, behind} = repo.getCachedUpstreamAheadBehindCount(itemPath)
if ahead > 0
@commitsAhead.textContent = ahead
@commitsAhead.style.display = ''
@commitsAheadTooltipDisposable?.dispose()
@commitsAheadTooltipDisposable = atom.tooltips.add @commitsAhead, title: "#{_.pluralize(ahead, 'commit')} ahead of upstream"
else
@commitsAhead.style.display = 'none'
if behind > 0
@commitsBehind.textContent = behind
@commitsBehind.style.display = ''
@commitsBehindTooltipDisposable?.dispose()
@commitsBehindTooltipDisposable = atom.tooltips.add @commitsBehind, title: "#{_.pluralize(behind, 'commit')} behind upstream"
else
@commitsBehind.style.display = 'none'
if ahead > 0 or behind > 0
@commitsArea.style.display = ''
else
@commitsArea.style.display = 'none'
clearStatus: ->
@gitStatusIcon.classList.remove('icon-diff-modified', 'status-modified', 'icon-diff-added', 'status-added', 'icon-diff-ignored', 'status-ignored')
updateAsNewFile: ->
@clearStatus()
@gitStatusIcon.classList.add('icon-diff-added', 'status-added')
if textEditor = atom.workspace.getActiveTextEditor()
@gitStatusIcon.textContent = "+#{textEditor.getLineCount()}"
@updateTooltipText("#{_.pluralize(textEditor.getLineCount(), 'line')} in this new file not yet committed")
else
@gitStatusIcon.textContent = ''
@updateTooltipText()
@gitStatus.style.display = ''
updateAsModifiedFile: (repo, path) ->
stats = repo.getDiffStats(path)
@clearStatus()
@gitStatusIcon.classList.add('icon-diff-modified', 'status-modified')
if stats.added and stats.deleted
@gitStatusIcon.textContent = "+#{stats.added}, -#{stats.deleted}"
@updateTooltipText("#{_.pluralize(stats.added, 'line')} added and #{_.pluralize(stats.deleted, 'line')} deleted in this file not yet committed")
else if stats.added
@gitStatusIcon.textContent = "+#{stats.added}"
@updateTooltipText("#{_.pluralize(stats.added, 'line')} added to this file not yet committed")
else if stats.deleted
@gitStatusIcon.textContent = "-#{stats.deleted}"
@updateTooltipText("#{_.pluralize(stats.deleted, 'line')} deleted from this file not yet committed")
else
@gitStatusIcon.textContent = ''
@updateTooltipText()
@gitStatus.style.display = ''
updateAsIgnoredFile: ->
@clearStatus()
@gitStatusIcon.classList.add('icon-diff-ignored', 'status-ignored')
@gitStatusIcon.textContent = ''
@gitStatus.style.display = ''
@updateTooltipText("File is ignored by git")
updateTooltipText: (text) ->
@statusTooltipDisposable?.dispose()
if text
@statusTooltipDisposable = atom.tooltips.add @gitStatusIcon, title: text
updateStatusText: (repo) ->
hideStatus = =>
@clearStatus()
@gitStatus.style.display = 'none'
itemPath = @getActiveItemPath()
if @showGitInformation(repo) and itemPath?
status = repo.getCachedPathStatus(itemPath) ? 0
if repo.isStatusNew(status)
return @updateAsNewFile()
if repo.isStatusModified(status)
return @updateAsModifiedFile(repo, itemPath)
if repo.isPathIgnored(itemPath)
@updateAsIgnoredFile()
else
hideStatus()
else
hideStatus()

View File

@ -1,18 +1,8 @@
/*
* decaffeinate suggestions:
* DS101: Remove unnecessary use of Array.from
* DS102: Remove unnecessary code created because of implicit returns
* DS104: Avoid inline assignments
* DS205: Consider reworking code to avoid use of IIFEs
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
let GitView;
const _ = require("underscore-plus");
const {CompositeDisposable, GitRepositoryAsync} = require("atom");
const { CompositeDisposable, GitRepositoryAsync } = require("atom");
module.exports =
(GitView = class GitView {
class GitView {
constructor() {
this.element = document.createElement('status-bar-git');
this.element.classList.add('git-view');
@ -22,10 +12,10 @@ module.exports =
this.createStatusArea();
this.activeItemSubscription = atom.workspace.getCenter().onDidChangeActivePaneItem(() => {
return this.subscribeToActiveItem();
this.subscribeToActiveItem();
});
this.projectPathSubscription = atom.project.onDidChangePaths(() => {
return this.subscribeToRepositories();
this.subscribeToRepositories();
});
this.subscribeToRepositories();
this.subscribeToActiveItem();
@ -44,7 +34,7 @@ module.exports =
this.branchLabel = document.createElement('span');
this.branchLabel.classList.add('branch-label');
this.branchArea.appendChild(this.branchLabel);
return this.element.branchLabel = this.branchLabel;
this.element.branchLabel = this.branchLabel;
}
createCommitsArea() {
@ -58,7 +48,7 @@ module.exports =
this.commitsBehind = document.createElement('span');
this.commitsBehind.classList.add('icon', 'icon-arrow-down', 'commits-behind-label');
return this.commitsArea.appendChild(this.commitsBehind);
this.commitsArea.appendChild(this.commitsBehind);
}
createStatusArea() {
@ -69,7 +59,7 @@ module.exports =
this.gitStatusIcon = document.createElement('span');
this.gitStatusIcon.classList.add('icon');
this.gitStatus.appendChild(this.gitStatusIcon);
return this.element.gitStatusIcon = this.gitStatusIcon;
this.element.gitStatusIcon = this.gitStatusIcon;
}
subscribeToActiveItem() {
@ -78,29 +68,34 @@ module.exports =
this.savedSubscription?.dispose();
this.savedSubscription = activeItem?.onDidSave?.(() => this.update());
return this.update();
this.update();
}
subscribeToRepositories() {
this.repositorySubscriptions?.dispose();
this.repositorySubscriptions = new CompositeDisposable;
return (() => {
const result = [];
for (let repo of Array.from(atom.project.getRepositories())) {
if (repo != null) {
this.repositorySubscriptions.add(repo.onDidChangeStatus(({path, status}) => {
if (path === this.getActiveItemPath()) { return this.update(); }
const result = [];
for (let repo of atom.project.getRepositories()) {
if (repo != null) {
this.repositorySubscriptions.add(
repo.onDidChangeStatus(({ path, status }) => {
if (path === this.getActiveItemPath()) {
this.update();
}
})
);
result.push(this.repositorySubscriptions.add(repo.onDidChangeStatuses(() => {
return this.update();
);
result.push(this.repositorySubscriptions.add(
repo.onDidChangeStatuses(() => {
this.update();
})
));
}
));
}
return result;
})();
}
return result;
}
destroy() {
@ -111,7 +106,7 @@ module.exports =
this.branchTooltipDisposable?.dispose();
this.commitsAheadTooltipDisposable?.dispose();
this.commitsBehindTooltipDisposable?.dispose();
return this.statusTooltipDisposable?.dispose();
this.statusTooltipDisposable?.dispose();
}
getActiveItemPath() {
@ -124,7 +119,7 @@ module.exports =
if (rootDirIndex >= 0) {
return atom.project.getRepositories()[rootDirIndex];
} else {
for (let repo of Array.from(atom.project.getRepositories())) {
for (let repo of atom.project.getRepositories()) {
if (repo) {
return repo;
}
@ -140,7 +135,7 @@ module.exports =
const repo = this.getRepositoryForActiveItem();
this.updateBranchText(repo);
this.updateAheadBehindCount(repo);
return this.updateStatusText(repo);
this.updateStatusText(repo);
}
updateBranchText(repo) {
@ -149,17 +144,17 @@ module.exports =
this.branchLabel.textContent = head;
if (head) { this.branchArea.style.display = ''; }
this.branchTooltipDisposable?.dispose();
return this.branchTooltipDisposable = atom.tooltips.add(this.branchArea, {title: `On branch ${head}`});
this.branchTooltipDisposable = atom.tooltips.add(this.branchArea, {title: `On branch ${head}`});
} else {
return this.branchArea.style.display = 'none';
this.branchArea.style.display = 'none';
}
}
showGitInformation(repo) {
let itemPath;
if (repo == null) { return false; }
if ((itemPath = this.getActiveItemPath())) {
const itemPath = this.getActiveItemPath();
if (itemPath) {
return atom.project.contains(itemPath);
} else {
return (this.getActiveItem() == null);
@ -193,22 +188,23 @@ module.exports =
}
if ((ahead > 0) || (behind > 0)) {
return this.commitsArea.style.display = '';
this.commitsArea.style.display = '';
} else {
return this.commitsArea.style.display = 'none';
this.commitsArea.style.display = 'none';
}
}
clearStatus() {
return this.gitStatusIcon.classList.remove('icon-diff-modified', 'status-modified', 'icon-diff-added', 'status-added', 'icon-diff-ignored', 'status-ignored');
this.gitStatusIcon.classList.remove('icon-diff-modified', 'status-modified', 'icon-diff-added', 'status-added', 'icon-diff-ignored', 'status-ignored');
}
updateAsNewFile() {
let textEditor;
this.clearStatus();
const textEditor = atom.workspace.getActiveTextEditor();
this.gitStatusIcon.classList.add('icon-diff-added', 'status-added');
if (textEditor = atom.workspace.getActiveTextEditor()) {
if (textEditor) {
this.gitStatusIcon.textContent = `+${textEditor.getLineCount()}`;
this.updateTooltipText(`${_.pluralize(textEditor.getLineCount(), 'line')} in this new file not yet committed`);
} else {
@ -216,7 +212,7 @@ module.exports =
this.updateTooltipText();
}
return this.gitStatus.style.display = '';
this.gitStatus.style.display = '';
}
updateAsModifiedFile(repo, path) {
@ -238,7 +234,7 @@ module.exports =
this.updateTooltipText();
}
return this.gitStatus.style.display = '';
this.gitStatus.style.display = '';
}
updateAsIgnoredFile() {
@ -247,26 +243,25 @@ module.exports =
this.gitStatusIcon.classList.add('icon-diff-ignored', 'status-ignored');
this.gitStatusIcon.textContent = '';
this.gitStatus.style.display = '';
return this.updateTooltipText("File is ignored by git");
this.updateTooltipText("File is ignored by git");
}
updateTooltipText(text) {
this.statusTooltipDisposable?.dispose();
if (text) {
return this.statusTooltipDisposable = atom.tooltips.add(this.gitStatusIcon, {title: text});
this.statusTooltipDisposable = atom.tooltips.add(this.gitStatusIcon, {title: text});
}
}
updateStatusText(repo) {
const hideStatus = () => {
this.clearStatus();
return this.gitStatus.style.display = 'none';
this.gitStatus.style.display = 'none';
};
const itemPath = this.getActiveItemPath();
if (this.showGitInformation(repo) && (itemPath != null)) {
let left;
const status = (left = repo.getCachedPathStatus(itemPath)) != null ? left : 0;
const status = repo.getCachedPathStatus(itemPath) ?? 0;
if (repo.isStatusNew(status)) {
return this.updateAsNewFile();
}
@ -284,4 +279,4 @@ module.exports =
return hideStatus();
}
}
});
}

View File

@ -1,14 +0,0 @@
module.exports =
class LaunchModeView
constructor: ({safeMode, devMode}={}) ->
@element = document.createElement('status-bar-launch-mode')
@element.classList.add('inline-block', 'icon', 'icon-color-mode')
if devMode
@element.classList.add('text-error')
@tooltipDisposable = atom.tooltips.add(@element, title: 'This window is in dev mode')
else if safeMode
@element.classList.add('text-success')
@tooltipDisposable = atom.tooltips.add(@element, title: 'This window is in safe mode')
detachedCallback: ->
@tooltipDisposable?.dispose()

View File

@ -1,15 +1,9 @@
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
let LaunchModeView;
module.exports =
(LaunchModeView = class LaunchModeView {
class LaunchModeView {
constructor(param) {
if (param == null) { param = {}; }
const {safeMode, devMode} = param;
const { safeMode, devMode } = param;
this.element = document.createElement('status-bar-launch-mode');
this.element.classList.add('inline-block', 'icon', 'icon-color-mode');
if (devMode) {
@ -22,6 +16,6 @@ module.exports =
}
detachedCallback() {
return this.tooltipDisposable?.dispose();
this.tooltipDisposable?.dispose();
}
});
}

View File

@ -1,121 +0,0 @@
{CompositeDisposable, Emitter} = require 'atom'
Grim = require 'grim'
StatusBarView = require './status-bar-view'
FileInfoView = require './file-info-view'
CursorPositionView = require './cursor-position-view'
SelectionCountView = require './selection-count-view'
GitView = require './git-view'
LaunchModeView = require './launch-mode-view'
module.exports =
activate: ->
@emitters = new Emitter()
@subscriptions = new CompositeDisposable()
@statusBar = new StatusBarView()
@attachStatusBar()
@subscriptions.add atom.config.onDidChange 'status-bar.fullWidth', =>
@attachStatusBar()
@updateStatusBarVisibility()
@statusBarVisibilitySubscription =
atom.config.observe 'status-bar.isVisible', =>
@updateStatusBarVisibility()
atom.commands.add 'atom-workspace', 'status-bar:toggle', =>
if @statusBarPanel.isVisible()
atom.config.set 'status-bar.isVisible', false
else
atom.config.set 'status-bar.isVisible', true
{safeMode, devMode} = atom.getLoadSettings()
if safeMode or devMode
launchModeView = new LaunchModeView({safeMode, devMode})
@statusBar.addLeftTile(item: launchModeView.element, priority: -1)
@fileInfo = new FileInfoView()
@statusBar.addLeftTile(item: @fileInfo.element, priority: 0)
@cursorPosition = new CursorPositionView()
@statusBar.addLeftTile(item: @cursorPosition.element, priority: 1)
@selectionCount = new SelectionCountView()
@statusBar.addLeftTile(item: @selectionCount.element, priority: 2)
@gitInfo = new GitView()
@gitInfoTile = @statusBar.addRightTile(item: @gitInfo.element, priority: 0)
deactivate: ->
@statusBarVisibilitySubscription?.dispose()
@statusBarVisibilitySubscription = null
@gitInfo?.destroy()
@gitInfo = null
@fileInfo?.destroy()
@fileInfo = null
@cursorPosition?.destroy()
@cursorPosition = null
@selectionCount?.destroy()
@selectionCount = null
@statusBarPanel?.destroy()
@statusBarPanel = null
@statusBar?.destroy()
@statusBar = null
@subscriptions?.dispose()
@subscriptions = null
@emitters?.dispose()
@emitters = null
delete atom.__workspaceView.statusBar if atom.__workspaceView?
updateStatusBarVisibility: ->
if atom.config.get 'status-bar.isVisible'
@statusBarPanel.show()
else
@statusBarPanel.hide()
provideStatusBar: ->
addLeftTile: @statusBar.addLeftTile.bind(@statusBar)
addRightTile: @statusBar.addRightTile.bind(@statusBar)
getLeftTiles: @statusBar.getLeftTiles.bind(@statusBar)
getRightTiles: @statusBar.getRightTiles.bind(@statusBar)
disableGitInfoTile: @gitInfoTile.destroy.bind(@gitInfoTile)
attachStatusBar: ->
@statusBarPanel.destroy() if @statusBarPanel?
panelArgs = {item: @statusBar, priority: 0}
if atom.config.get('status-bar.fullWidth')
@statusBarPanel = atom.workspace.addFooterPanel panelArgs
else
@statusBarPanel = atom.workspace.addBottomPanel panelArgs
# Deprecated
#
# Wrap deprecation calls on the methods returned rather than
# Services API method which would be registered and trigger
# a deprecation call
legacyProvideStatusBar: ->
statusbar = @provideStatusBar()
addLeftTile: (args...) ->
Grim.deprecate("Use version ^1.0.0 of the status-bar Service API.")
statusbar.addLeftTile(args...)
addRightTile: (args...) ->
Grim.deprecate("Use version ^1.0.0 of the status-bar Service API.")
statusbar.addRightTile(args...)
getLeftTiles: ->
Grim.deprecate("Use version ^1.0.0 of the status-bar Service API.")
statusbar.getLeftTiles()
getRightTiles: ->
Grim.deprecate("Use version ^1.0.0 of the status-bar Service API.")
statusbar.getRightTiles()

View File

@ -1,10 +1,4 @@
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
const {CompositeDisposable, Emitter} = require('atom');
const { CompositeDisposable, Emitter } = require('atom');
const Grim = require('grim');
const StatusBarView = require('./status-bar-view');
const FileInfoView = require('./file-info-view');
@ -22,7 +16,7 @@ module.exports = {
this.attachStatusBar();
this.subscriptions.add(atom.config.onDidChange('status-bar.fullWidth', () => {
return this.attachStatusBar();
this.attachStatusBar();
})
);
@ -30,18 +24,18 @@ module.exports = {
this.statusBarVisibilitySubscription =
atom.config.observe('status-bar.isVisible', () => {
return this.updateStatusBarVisibility();
this.updateStatusBarVisibility();
});
atom.commands.add('atom-workspace', 'status-bar:toggle', () => {
if (this.statusBarPanel.isVisible()) {
return atom.config.set('status-bar.isVisible', false);
atom.config.set('status-bar.isVisible', false);
} else {
return atom.config.set('status-bar.isVisible', true);
atom.config.set('status-bar.isVisible', true);
}
});
const {safeMode, devMode} = atom.getLoadSettings();
const { safeMode, devMode } = atom.getLoadSettings();
if (safeMode || devMode) {
const launchModeView = new LaunchModeView({safeMode, devMode});
this.statusBar.addLeftTile({item: launchModeView.element, priority: -1});
@ -57,7 +51,7 @@ module.exports = {
this.statusBar.addLeftTile({item: this.selectionCount.element, priority: 2});
this.gitInfo = new GitView();
return this.gitInfoTile = this.statusBar.addRightTile({item: this.gitInfo.element, priority: 0});
this.gitInfoTile = this.statusBar.addRightTile({item: this.gitInfo.element, priority: 0});
},
deactivate() {
@ -88,14 +82,14 @@ module.exports = {
this.emitters?.dispose();
this.emitters = null;
if (atom.__workspaceView != null) { return delete atom.__workspaceView.statusBar; }
if (atom.__workspaceView != null) { delete atom.__workspaceView.statusBar; }
},
updateStatusBarVisibility() {
if (atom.config.get('status-bar.isVisible')) {
return this.statusBarPanel.show();
this.statusBarPanel.show();
} else {
return this.statusBarPanel.hide();
this.statusBarPanel.hide();
}
},
@ -114,9 +108,9 @@ module.exports = {
const panelArgs = {item: this.statusBar, priority: 0};
if (atom.config.get('status-bar.fullWidth')) {
return this.statusBarPanel = atom.workspace.addFooterPanel(panelArgs);
this.statusBarPanel = atom.workspace.addFooterPanel(panelArgs);
} else {
return this.statusBarPanel = atom.workspace.addBottomPanel(panelArgs);
this.statusBarPanel = atom.workspace.addBottomPanel(panelArgs);
}
},
@ -131,19 +125,19 @@ module.exports = {
return {
addLeftTile(...args) {
Grim.deprecate("Use version ^1.0.0 of the status-bar Service API.");
return statusbar.addLeftTile(...args);
statusbar.addLeftTile(...args);
},
addRightTile(...args) {
Grim.deprecate("Use version ^1.0.0 of the status-bar Service API.");
return statusbar.addRightTile(...args);
statusbar.addRightTile(...args);
},
getLeftTiles() {
Grim.deprecate("Use version ^1.0.0 of the status-bar Service API.");
return statusbar.getLeftTiles();
statusbar.getLeftTiles();
},
getRightTiles() {
Grim.deprecate("Use version ^1.0.0 of the status-bar Service API.");
return statusbar.getRightTiles();
statusbar.getRightTiles();
}
};
}

View File

@ -1,58 +0,0 @@
_ = require 'underscore-plus'
module.exports =
class SelectionCountView
constructor: ->
@element = document.createElement('status-bar-selection')
@element.classList.add('selection-count', 'inline-block')
@tooltipElement = document.createElement('div')
@tooltipDisposable = atom.tooltips.add @element, item: @tooltipElement
@formatString = atom.config.get('status-bar.selectionCountFormat') ? '(%L, %C)'
@activeItemSubscription = atom.workspace.onDidChangeActiveTextEditor => @subscribeToActiveTextEditor()
@subscribeToConfig()
@subscribeToActiveTextEditor()
destroy: ->
@activeItemSubscription.dispose()
@selectionSubscription?.dispose()
@configSubscription?.dispose()
@tooltipDisposable.dispose()
subscribeToConfig: ->
@configSubscription?.dispose()
@configSubscription = atom.config.observe 'status-bar.selectionCountFormat', (value) =>
@formatString = value ? '(%L, %C)'
@scheduleUpdateCount()
subscribeToActiveTextEditor: ->
@selectionSubscription?.dispose()
activeEditor = @getActiveTextEditor()
selectionsMarkerLayer = activeEditor?.selectionsMarkerLayer
@selectionSubscription = selectionsMarkerLayer?.onDidUpdate(@scheduleUpdateCount.bind(this))
@scheduleUpdateCount()
getActiveTextEditor: ->
atom.workspace.getActiveTextEditor()
scheduleUpdateCount: ->
unless @scheduledUpdate
@scheduledUpdate = true
atom.views.updateDocument =>
@updateCount()
@scheduledUpdate = false
updateCount: ->
count = @getActiveTextEditor()?.getSelectedText().length
range = @getActiveTextEditor()?.getSelectedBufferRange()
lineCount = range?.getRowCount()
lineCount -= 1 if range?.end.column is 0
if count > 0
@element.textContent = @formatString.replace('%L', lineCount).replace('%C', count)
@tooltipElement.textContent = "#{_.pluralize(lineCount, 'line')}, #{_.pluralize(count, 'character')} selected"
else
@element.textContent = ''
@tooltipElement.textContent = ''

View File

@ -1,24 +1,15 @@
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS104: Avoid inline assignments
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
let SelectionCountView;
const _ = require('underscore-plus');
module.exports =
(SelectionCountView = class SelectionCountView {
class SelectionCountView {
constructor() {
let left;
this.element = document.createElement('status-bar-selection');
this.element.classList.add('selection-count', 'inline-block');
this.tooltipElement = document.createElement('div');
this.tooltipDisposable = atom.tooltips.add(this.element, {item: this.tooltipElement});
this.formatString = (left = atom.config.get('status-bar.selectionCountFormat')) != null ? left : '(%L, %C)';
this.formatString = atom.config.get('status-bar.selectionCountFormat') ?? '(%L, %C)';
this.activeItemSubscription = atom.workspace.onDidChangeActiveTextEditor(() => this.subscribeToActiveTextEditor());
@ -30,14 +21,14 @@ module.exports =
this.activeItemSubscription.dispose();
this.selectionSubscription?.dispose();
this.configSubscription?.dispose();
return this.tooltipDisposable.dispose();
this.tooltipDisposable.dispose();
}
subscribeToConfig() {
this.configSubscription?.dispose();
return this.configSubscription = atom.config.observe('status-bar.selectionCountFormat', value => {
this.formatString = value != null ? value : '(%L, %C)';
return this.scheduleUpdateCount();
this.configSubscription = atom.config.observe('status-bar.selectionCountFormat', value => {
this.formatString = value ?? '(%L, %C)';
this.scheduleUpdateCount();
});
}
@ -46,7 +37,7 @@ module.exports =
const activeEditor = this.getActiveTextEditor();
const selectionsMarkerLayer = activeEditor?.selectionsMarkerLayer;
this.selectionSubscription = selectionsMarkerLayer?.onDidUpdate(this.scheduleUpdateCount.bind(this));
return this.scheduleUpdateCount();
this.scheduleUpdateCount();
}
getActiveTextEditor() {
@ -56,9 +47,9 @@ module.exports =
scheduleUpdateCount() {
if (!this.scheduledUpdate) {
this.scheduledUpdate = true;
return atom.views.updateDocument(() => {
atom.views.updateDocument(() => {
this.updateCount();
return this.scheduledUpdate = false;
this.scheduledUpdate = false;
});
}
}
@ -70,10 +61,10 @@ module.exports =
if (range?.end.column === 0) { lineCount -= 1; }
if (count > 0) {
this.element.textContent = this.formatString.replace('%L', lineCount).replace('%C', count);
return this.tooltipElement.textContent = `${_.pluralize(lineCount, 'line')}, ${_.pluralize(count, 'character')} selected`;
this.tooltipElement.textContent = `${_.pluralize(lineCount, 'line')}, ${_.pluralize(count, 'character')} selected`;
} else {
this.element.textContent = '';
return this.tooltipElement.textContent = '';
this.tooltipElement.textContent = '';
}
}
});
}

View File

@ -1,107 +0,0 @@
{Disposable} = require 'atom'
Tile = require './tile'
module.exports =
class StatusBarView
constructor: ->
@element = document.createElement('status-bar')
@element.classList.add('status-bar')
flexboxHackElement = document.createElement('div')
flexboxHackElement.classList.add('flexbox-repaint-hack')
@element.appendChild(flexboxHackElement)
@leftPanel = document.createElement('div')
@leftPanel.classList.add('status-bar-left')
flexboxHackElement.appendChild(@leftPanel)
@element.leftPanel = @leftPanel
@rightPanel = document.createElement('div')
@rightPanel.classList.add('status-bar-right')
flexboxHackElement.appendChild(@rightPanel)
@element.rightPanel = @rightPanel
@leftTiles = []
@rightTiles = []
@element.getLeftTiles = @getLeftTiles.bind(this)
@element.getRightTiles = @getRightTiles.bind(this)
@element.addLeftTile = @addLeftTile.bind(this)
@element.addRightTile = @addRightTile.bind(this)
@bufferSubscriptions = []
@activeItemSubscription = atom.workspace.getCenter().onDidChangeActivePaneItem =>
@unsubscribeAllFromBuffer()
@storeActiveBuffer()
@subscribeAllToBuffer()
@element.dispatchEvent(new CustomEvent('active-buffer-changed', bubbles: true))
@storeActiveBuffer()
destroy: ->
@activeItemSubscription.dispose()
@unsubscribeAllFromBuffer()
@element.remove()
addLeftTile: (options) ->
newItem = options.item
newPriority = options?.priority ? @leftTiles[@leftTiles.length - 1].priority + 1
nextItem = null
for {priority, item}, index in @leftTiles
if priority > newPriority
nextItem = item
break
newTile = new Tile(newItem, newPriority, @leftTiles)
@leftTiles.splice(index, 0, newTile)
newElement = atom.views.getView(newItem)
nextElement = atom.views.getView(nextItem)
@leftPanel.insertBefore(newElement, nextElement)
newTile
addRightTile: (options) ->
newItem = options.item
newPriority = options?.priority ? @rightTiles[0].priority + 1
nextItem = null
for {priority, item}, index in @rightTiles
if priority < newPriority
nextItem = item
break
newTile = new Tile(newItem, newPriority, @rightTiles)
@rightTiles.splice(index, 0, newTile)
newElement = atom.views.getView(newItem)
nextElement = atom.views.getView(nextItem)
@rightPanel.insertBefore(newElement, nextElement)
newTile
getLeftTiles: ->
@leftTiles
getRightTiles: ->
@rightTiles
getActiveBuffer: ->
@buffer
getActiveItem: ->
atom.workspace.getCenter().getActivePaneItem()
storeActiveBuffer: ->
@buffer = @getActiveItem()?.getBuffer?()
subscribeToBuffer: (event, callback) ->
@bufferSubscriptions.push([event, callback])
@buffer.on(event, callback) if @buffer
subscribeAllToBuffer: ->
return unless @buffer
for [event, callback] in @bufferSubscriptions
@buffer.on(event, callback)
unsubscribeAllFromBuffer: ->
return unless @buffer
for [event, callback] in @bufferSubscriptions
@buffer.off(event, callback)

View File

@ -1,17 +1,8 @@
/*
* decaffeinate suggestions:
* DS101: Remove unnecessary use of Array.from
* DS102: Remove unnecessary code created because of implicit returns
* DS205: Consider reworking code to avoid use of IIFEs
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
let StatusBarView;
const {Disposable} = require('atom');
const { Disposable } = require('atom');
const Tile = require('./tile');
module.exports =
(StatusBarView = class StatusBarView {
class StatusBarView {
constructor() {
this.element = document.createElement('status-bar');
this.element.classList.add('status-bar');
@ -45,7 +36,7 @@ module.exports =
this.storeActiveBuffer();
this.subscribeAllToBuffer();
return this.element.dispatchEvent(new CustomEvent('active-buffer-changed', {bubbles: true}));
this.element.dispatchEvent(new CustomEvent('active-buffer-changed', {bubbles: true}));
});
this.storeActiveBuffer();
@ -54,7 +45,7 @@ module.exports =
destroy() {
this.activeItemSubscription.dispose();
this.unsubscribeAllFromBuffer();
return this.element.remove();
this.element.remove();
}
addLeftTile(options) {
@ -116,7 +107,7 @@ module.exports =
}
storeActiveBuffer() {
return this.buffer = this.getActiveItem()?.getBuffer?.();
this.buffer = this.getActiveItem()?.getBuffer?.();
}
subscribeToBuffer(event, callback) {
@ -126,23 +117,25 @@ module.exports =
subscribeAllToBuffer() {
if (!this.buffer) { return; }
return (() => {
const result = [];
for (let [event, callback] of Array.from(this.bufferSubscriptions)) {
result.push(this.buffer.on(event, callback));
}
return result;
})();
const result = [];
for (let [event, callback] of this.bufferSubscriptions) {
result.push(this.buffer.on(event, callback));
}
return result;
}
unsubscribeAllFromBuffer() {
if (!this.buffer) { return; }
return (() => {
const result = [];
for (let [event, callback] of Array.from(this.bufferSubscriptions)) {
result.push(this.buffer.off(event, callback));
}
return result;
})();
const result = [];
for (let [event, callback] of this.bufferSubscriptions) {
result.push(this.buffer.off(event, callback));
}
return result;
}
});
}

View File

@ -1,13 +0,0 @@
module.exports =
class Tile
constructor: (@item, @priority, @collection) ->
getItem: ->
@item
getPriority: ->
@priority
destroy: ->
@collection.splice(@collection.indexOf(this), 1)
atom.views.getView(@item).remove()

View File

@ -1,11 +1,6 @@
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
*/
let Tile;
module.exports =
(Tile = class Tile {
class Tile {
constructor(item, priority, collection) {
this.item = item;
this.priority = priority;
@ -22,6 +17,6 @@ module.exports =
destroy() {
this.collection.splice(this.collection.indexOf(this), 1);
return atom.views.getView(this.item).remove();
atom.views.getView(this.item).remove();
}
});
}