├── LICENSE.md ├── README.md ├── filetype-color.gif ├── keymaps └── filetype-color.cson ├── lib ├── filetype-color-view.coffee ├── filetype-color-view.js └── filetype-color.coffee ├── menus └── filetype-color.cson ├── package.json ├── spec ├── filetype-color-spec.coffee └── filetype-color-view-spec.coffee └── stylesheets └── filetype-color.less /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Per Sommer 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # filetype-color package 2 | 3 | ##Description 4 | This package makes it possible to modify the colors of file names in the side bar and the panes. 5 | 6 | When enabled it will add an extra class according to the file extension, for example: 7 | 8 | * ".js" files get "filetype-color-js" 9 | * ".jpg" files get "filetype-color-jpg" 10 | * ".php" files get "filetype-color-php" 11 | 12 | There are already some predefined colors, but if you want to override or add colors you can do it in your own "styles.less" file. 13 | An example could be: 14 | 15 | .filetype-color-js 16 | { 17 | color: #90c276; 18 | } 19 | 20 | ##Usage 21 | Toggle on and off with **ctrl-alt-cmd-b** 22 | 23 | ##Screenshot 24 | ![Screenshot](https://github.com/sommerper/filetype-color/raw/master/filetype-color.gif) 25 | 26 | ##Disclaimer 27 | Since I don't code in coffeescript and the Atom API docs still leave a lot to be desired I couldn't see if there are any events fired when content changes in the tree and pane view. 28 | Until I figure that out, this package will be using the MutationObserver to listen for DOM changes. Probably a less desireable solution as it creates uneeded overhead and leaves me with no other choice but to set some timeouts before applying the colors. 29 | Any insight to how it may be optimized is appreciated. 30 | -------------------------------------------------------------------------------- /filetype-color.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sommerper/filetype-color/22acf4ccf4f8ea2d12033f637c7820312beaa3a5/filetype-color.gif -------------------------------------------------------------------------------- /keymaps/filetype-color.cson: -------------------------------------------------------------------------------- 1 | # Keybindings require three things to be fully defined: A selector that is 2 | # matched against the focused element, the keystroke and the command to 3 | # execute. 4 | # 5 | # Below is a basic keybinding which registers on all platforms by applying to 6 | # the root workspace element. 7 | 8 | # For more detailed documentation see 9 | # https://atom.io/docs/latest/advanced/keymaps 10 | 'atom-workspace': 11 | 'ctrl-alt-cmd-b': 'filetype-color:toggle' 12 | -------------------------------------------------------------------------------- /lib/filetype-color-view.coffee: -------------------------------------------------------------------------------- 1 | {View} = require 'atom' 2 | 3 | module.exports = 4 | class FiletypeColorView extends View 5 | @content: -> 6 | @div class: 'filetype-color overlay from-top', => 7 | @div "The FiletypeColor package is Alive! It's ALIVE!", class: "message" 8 | 9 | initialize: (serializeState) -> 10 | 11 | atom.workspaceView.command "filetype-color:toggle", => @toggle() 12 | 13 | # Returns an object that can be retrieved when package is activated 14 | serialize: -> 15 | 16 | # Tear down any state and detach 17 | destroy: -> 18 | @detach() 19 | 20 | toggle: -> 21 | console.log "FiletypeColorView was toggled!" 22 | if @hasParent() 23 | @detach() 24 | else 25 | atom.workspaceView.append(this) 26 | @runme() 27 | 28 | runme: -> 29 | alert('YO') 30 | -------------------------------------------------------------------------------- /lib/filetype-color-view.js: -------------------------------------------------------------------------------- 1 | 2 | var observerTree; 3 | var observerPanes; 4 | var timeoutTree; 5 | var timeoutPanes; 6 | var timeoutTreeObserver; 7 | var timeoutPanesObserver; 8 | var View = require('atom').View; 9 | var __hasProp = {}.hasOwnProperty; 10 | var __extends = function(child, parent) { 11 | for (var key in parent) { 12 | if (__hasProp.call(parent, key)) child[key] = parent[key]; 13 | } 14 | 15 | function ctor() { 16 | this.constructor = child; 17 | } 18 | ctor.prototype = parent.prototype; 19 | child.prototype = new ctor(); 20 | child.__super__ = parent.prototype; 21 | return child; 22 | }; 23 | 24 | var observerConfig = { 25 | attributes: true, 26 | childList: true, 27 | characterData: false, 28 | subtree: true 29 | }; 30 | 31 | module.exports = FiletypeColorView = (function(_super) { 32 | __extends(FiletypeColorView, _super); 33 | 34 | function FiletypeColorView() { 35 | 36 | return FiletypeColorView.__super__.constructor.apply(this, arguments); 37 | } 38 | 39 | FiletypeColorView.content = function() { 40 | return this.div({ 41 | //"class": 'filetype-color overlay from-top' 42 | }, (function(_this) { 43 | return function() { 44 | return; 45 | //_this.div("The FiletypeColor package is Alive! It's GONE!", {"class": "message"}); 46 | }; 47 | })(this)); 48 | }; 49 | 50 | FiletypeColorView.prototype.initialize = function(serializeState) { 51 | var autoInit = atom.config.get('filetype-color.enabled'); 52 | 53 | if(!autoInit) { 54 | atom.config.set('filetype-color.enabled', 'false'); 55 | autoInit = 'false'; 56 | } 57 | 58 | if(autoInit == 'true') { 59 | var self = this; 60 | setTimeout(function(){ 61 | self.toggle(); 62 | }, 1000); 63 | } 64 | 65 | return atom.workspaceView.command("filetype-color:toggle", (function(_this) { 66 | return function() { 67 | return _this.toggle(); 68 | }; 69 | })(this)); 70 | }; 71 | 72 | FiletypeColorView.prototype.activate = function() {}; 73 | 74 | FiletypeColorView.prototype.deactivate = function() {}; 75 | 76 | FiletypeColorView.prototype.serialize = function() {}; 77 | 78 | FiletypeColorView.prototype.destroy = function() { 79 | return this.detach(); 80 | }; 81 | 82 | FiletypeColorView.prototype.toggle = function() { 83 | 84 | if (this.hasParent()) { 85 | 86 | this.clearAll(); 87 | this.clearAllPanes(); 88 | 89 | if (observerTree) { 90 | observerTree.disconnect(); 91 | observerPanes.disconnect(); 92 | } 93 | 94 | atom.config.set('filetype-color.enabled', 'false'); 95 | 96 | return this.detach(); 97 | 98 | } else { 99 | 100 | if(document.querySelector('.tree-view')) { 101 | this.colorAll(); 102 | this.createTreeViewObserver(); 103 | } 104 | 105 | this.colorAllPanes(); 106 | this.createPaneViewObserver(); 107 | 108 | atom.config.set('filetype-color.enabled', 'true'); 109 | 110 | return atom.workspaceView.append(this); 111 | } 112 | }; 113 | 114 | FiletypeColorView.prototype.createPaneViewObserver = function(mutation) { 115 | 116 | var targetPanes = document.querySelector('.panes .pane ul'); 117 | var self = this; 118 | 119 | observerPanes = new WebKitMutationObserver(function(mutations) { 120 | 121 | observerPanes.disconnect(); 122 | 123 | mutations.forEach(function() { 124 | 125 | var that = self; 126 | 127 | clearTimeout(timeoutPanes); 128 | 129 | timeoutPanes = setTimeout(function() { 130 | that.colorAllPanes(); 131 | }, 100); 132 | 133 | }); 134 | 135 | clearTimeout(timeoutPanesObserver); 136 | 137 | timeoutPanesObserver = setTimeout(function() { 138 | observerPanes.observe(targetPanes, observerConfig); 139 | }, 150); 140 | }); 141 | 142 | observerPanes.observe(targetPanes, observerConfig); 143 | }; 144 | 145 | FiletypeColorView.prototype.createTreeViewObserver = function(mutation) { 146 | 147 | var targetTree = document.querySelector('.tree-view'); 148 | var self = this; 149 | 150 | observerTree = new WebKitMutationObserver(function(mutations) { 151 | 152 | observerTree.disconnect(); 153 | 154 | mutations.forEach(function() { 155 | 156 | var that = self; 157 | 158 | clearTimeout(timeoutTree); 159 | 160 | timeoutTree = setTimeout(function() { 161 | that.colorAll(); 162 | }, 100); 163 | 164 | }); 165 | 166 | clearTimeout(timeoutTreeObserver); 167 | 168 | timeoutTreeObserver = setTimeout(function() { 169 | observerTree.observe(targetTree, observerConfig); 170 | }, 150); 171 | }); 172 | 173 | observerTree.observe(targetTree, observerConfig); 174 | }; 175 | 176 | FiletypeColorView.prototype.attrModified = function(mutation) { 177 | // var name = mutation.attributeName, 178 | // newValue = mutation.target.getAttribute(name), 179 | // oldValue = mutation.oldValue; 180 | // console.log(name, newValue, oldValue); 181 | // console.log(mutation.target); 182 | }; 183 | 184 | FiletypeColorView.prototype.colorAll = function() { 185 | 186 | treeView = document.querySelector(".tree-view"); 187 | elements = treeView.querySelectorAll("li.file span"); 188 | 189 | for (var i = 0; i < elements.length; i++) { 190 | var el = elements[i]; 191 | this.colorElement(el); 192 | } 193 | 194 | }; 195 | 196 | FiletypeColorView.prototype.colorAllPanes = function() { 197 | 198 | paneView = document.querySelector(".panes"); 199 | elements = paneView.querySelectorAll("li .title"); 200 | 201 | for (var i = 0; i < elements.length; i++) { 202 | var el = elements[i]; 203 | this.colorElement(el); 204 | } 205 | }; 206 | 207 | FiletypeColorView.prototype.clearAll = function() { 208 | if(document.querySelector('.tree-view')) 209 | { 210 | treeView = document.querySelector(".tree-view"); 211 | elements = treeView.querySelectorAll("li.file span"); 212 | 213 | for (var i = 0; i < elements.length; i++) { 214 | var el = elements[i]; 215 | this.clearElement(el); 216 | } 217 | } 218 | }; 219 | 220 | FiletypeColorView.prototype.clearAllPanes = function() { 221 | paneView = document.querySelector(".panes"); 222 | elements = paneView.querySelectorAll("li .title"); 223 | 224 | for (var i = 0; i < elements.length; i++) { 225 | var el = elements[i]; 226 | this.clearElement(el); 227 | } 228 | }; 229 | 230 | FiletypeColorView.prototype.colorElement = function(el) { 231 | var fileName = el.innerHTML; 232 | 233 | var ext = fileName.split('.').pop(); 234 | var className = "filetype-color filetype-color-" + ext; 235 | this.clearElement(el); 236 | el.className = el.className + " " + className; 237 | }; 238 | 239 | FiletypeColorView.prototype.clearElement = function(el) { 240 | el.className = el.className.replace(/\sfiletype-color-[\S]+/, ''); 241 | el.className = el.className.replace('filetype-color', ''); 242 | }; 243 | 244 | return FiletypeColorView; 245 | 246 | })(View); 247 | -------------------------------------------------------------------------------- /lib/filetype-color.coffee: -------------------------------------------------------------------------------- 1 | FiletypeColorView = require './filetype-color-view' 2 | 3 | module.exports = 4 | filetypeColorView: null 5 | 6 | activate: (state) -> 7 | @filetypeColorView = new FiletypeColorView(state.filetypeColorViewState) 8 | 9 | deactivate: -> 10 | @filetypeColorView.destroy() 11 | 12 | serialize: -> 13 | filetypeColorViewState: @filetypeColorView.serialize() 14 | -------------------------------------------------------------------------------- /menus/filetype-color.cson: -------------------------------------------------------------------------------- 1 | # See https://atom.io/docs/latest/creating-a-package#menus for more details 2 | 'context-menu': 3 | '.overlayer': 4 | 'Enable filetype-color': 'filetype-color:toggle' 5 | 6 | 'menu': [ 7 | { 8 | 'label': 'Packages' 9 | 'submenu': [ 10 | 'label': 'filetype-color' 11 | 'submenu': [ 12 | { 'label': 'Toggle', 'command': 'filetype-color:toggle' } 13 | ] 14 | ] 15 | } 16 | ] 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "filetype-color", 3 | "main": "./lib/filetype-color", 4 | "version": "0.1.4", 5 | "description": "Color codes file names in the side bar and pane view.", 6 | "repository": "https://github.com/sommerper/filetype-color", 7 | "license": "MIT", 8 | "engines": { 9 | "atom": ">0.50.0" 10 | }, 11 | "dependencies": {} 12 | } 13 | -------------------------------------------------------------------------------- /spec/filetype-color-spec.coffee: -------------------------------------------------------------------------------- 1 | FiletypeColor = require '../lib/filetype-color' 2 | 3 | # Use the command `window:run-package-specs` (cmd-alt-ctrl-p) to run specs. 4 | # 5 | # To run a specific `it` or `describe` block add an `f` to the front (e.g. `fit` 6 | # or `fdescribe`). Remove the `f` to unfocus the block. 7 | 8 | describe "FiletypeColor", -> 9 | activationPromise = null 10 | 11 | beforeEach -> 12 | atom.workspaceView = new WorkspaceView 13 | activationPromise = atom.packages.activatePackage('filetypeColor') 14 | 15 | describe "when the filetype-color:toggle event is triggered", -> 16 | it "attaches and then detaches the view", -> 17 | expect(atom.workspaceView.find('.filetype-color')).not.toExist() 18 | 19 | # This is an activation event, triggering it will cause the package to be 20 | # activated. 21 | atom.workspaceView.trigger 'filetype-color:toggle' 22 | 23 | waitsForPromise -> 24 | activationPromise 25 | 26 | runs -> 27 | expect(atom.workspaceView.find('.filetype-color')).toExist() 28 | atom.workspaceView.trigger 'filetype-color:toggle' 29 | expect(atom.workspaceView.find('.filetype-color')).not.toExist() 30 | -------------------------------------------------------------------------------- /spec/filetype-color-view-spec.coffee: -------------------------------------------------------------------------------- 1 | FiletypeColorView = require '../lib/filetype-color-view' 2 | {WorkspaceView} = require 'atom' 3 | 4 | describe "FiletypeColorView", -> 5 | it "has one valid test", -> 6 | expect("life").toBe "easy" 7 | -------------------------------------------------------------------------------- /stylesheets/filetype-color.less: -------------------------------------------------------------------------------- 1 | .file.status-modified { 2 | 3 | .filetype-color { 4 | 5 | position: relative; 6 | 7 | &:after { 8 | content: "\2039"; 9 | color: #ff982d; 10 | font-size: 1.5em; 11 | position: absolute; 12 | margin-left: 0.2em; 13 | } 14 | } 15 | } 16 | 17 | .filetype-color { 18 | transition: color 200ms; 19 | } 20 | 21 | .filetype-color-js 22 | { 23 | color: #90c276; 24 | } 25 | 26 | .filetype-color-md 27 | { 28 | color: #78b4c4; 29 | } 30 | 31 | .filetype-color-json 32 | { 33 | color: #b17bc7; 34 | } 35 | 36 | .filetype-color-cson 37 | { 38 | color: #c67dc9; 39 | } 40 | 41 | .filetype-color-npmignore 42 | { 43 | color: #c97d7d; 44 | } 45 | 46 | .filetype-color-gitignore 47 | { 48 | color: #c9a07d; 49 | } 50 | 51 | .filetype-color-yml 52 | { 53 | color: #bec97d; 54 | } 55 | 56 | .filetype-color-txt 57 | { 58 | color: #7dc9c6; 59 | } 60 | 61 | .filetype-color-coffee 62 | { 63 | color: #b0734b; 64 | } 65 | 66 | .filetype-color-php 67 | { 68 | color: #5991db; 69 | } 70 | 71 | .filetype-color-less 72 | { 73 | color: #78c497; 74 | } 75 | 76 | .filetype-color-sass 77 | { 78 | color: #8078c4; 79 | } 80 | 81 | .filetype-color-css 82 | { 83 | color: #c478c3; 84 | } 85 | 86 | .filetype-color-jshintrc 87 | { 88 | color: #c77b9f; 89 | } 90 | 91 | .filetype-color-editorconfig 92 | { 93 | color: #c77b81; 94 | } 95 | 96 | .filetype-color-png 97 | { 98 | color: #d5b559; 99 | } 100 | 101 | .filetype-color-gif 102 | { 103 | color: #d6d85b; 104 | } 105 | 106 | .filetype-color-jpg 107 | { 108 | color: #c2d85b; 109 | } 110 | 111 | .filetype-color-jade 112 | { 113 | color: #00a86b; 114 | } 115 | 116 | .filetype-color-html 117 | { 118 | color: #5cb5db; 119 | } 120 | 121 | .filetype-color-sh 122 | { 123 | color: #de5ebd; 124 | } 125 | 126 | .filetype-color-htaccess 127 | { 128 | color: #e16178; 129 | } 130 | 131 | .filetype-color-module 132 | { 133 | color: #e1c761; 134 | } 135 | 136 | .filetype-color-xml 137 | { 138 | color: #a9e161; 139 | } 140 | 141 | .filetype-color-hbs 142 | { 143 | color: #f7931e; 144 | } 145 | 146 | .filetype-color-d 147 | { 148 | color: #B13429; 149 | } 150 | 151 | .filetype-color-eot, .filetype-color-svg, .filetype-color-ttf, .filetype-color-woff 152 | { 153 | color: #a8d173; 154 | } 155 | --------------------------------------------------------------------------------