diff --git a/build/Gruntfile.coffee b/build/Gruntfile.coffee index 7833ac0ac..85edc9c49 100644 --- a/build/Gruntfile.coffee +++ b/build/Gruntfile.coffee @@ -25,6 +25,7 @@ module.exports = (grunt) -> grunt.loadNpmTasks('grunt-markdown') grunt.loadNpmTasks('grunt-shell') grunt.loadNpmTasks('grunt-download-atom-shell') + grunt.loadNpmTasks('grunt-peg') grunt.loadTasks('tasks') # This allows all subsequent paths to the relative to the root of the repo @@ -102,6 +103,13 @@ module.exports = (grunt) -> dest: appDir ext: '.json' + pegConfig = + glob_to_multiple: + expand: true + src: ['src/**/*.pegjs'] + dest: appDir + ext: '.js' + for child in fs.readdirSync('node_modules') when child isnt '.bin' directory = path.join('node_modules', child) {engines, theme} = grunt.file.readJSON(path.join(directory, 'package.json')) @@ -110,6 +118,7 @@ module.exports = (grunt) -> lessConfig.glob_to_multiple.src.push("#{directory}/**/*.less") prebuildLessConfig.src.push("#{directory}/**/*.less") unless theme csonConfig.glob_to_multiple.src.push("#{directory}/**/*.cson") + pegConfig.glob_to_multiple.src.push("#{directory}/**/*.pegjs") grunt.initConfig pkg: grunt.file.readJSON('package.json') @@ -124,6 +133,8 @@ module.exports = (grunt) -> cson: csonConfig + peg: pegConfig + coffeelint: options: no_empty_param_list: @@ -207,7 +218,7 @@ module.exports = (grunt) -> stderr: false failOnError: false - grunt.registerTask('compile', ['coffee', 'prebuild-less', 'cson']) + grunt.registerTask('compile', ['coffee', 'prebuild-less', 'cson', 'peg']) grunt.registerTask('lint', ['coffeelint', 'csslint', 'lesslint']) grunt.registerTask('test', ['shell:kill-atom', 'run-specs']) grunt.registerTask('ci', ['output-disk-space', 'download-atom-shell', 'build', 'set-development-version', 'lint', 'test', 'publish-build']) diff --git a/build/package.json b/build/package.json index 221dc69c2..1f74aaf3c 100644 --- a/build/package.json +++ b/build/package.json @@ -28,6 +28,7 @@ "request": "~2.27.0", "rimraf": "~2.2.2", "unzip": "~0.1.9", - "walkdir": "0.0.7" + "walkdir": "0.0.7", + "grunt-peg": "~1.1.0" } } diff --git a/package.json b/package.json index 5e4927e83..e14c663ed 100644 --- a/package.json +++ b/package.json @@ -24,10 +24,10 @@ "coffee-script": "1.6.3", "coffeestack": "0.6.0", "emissary": "0.31.0", - "first-mate": "0.14.0", + "first-mate": "0.17.0", "fs-plus": "0.14.0", "fstream": "0.1.24", - "fuzzaldrin": "0.5.0", + "fuzzaldrin": "0.6.0", "git-utils": "0.29.0", "guid": "0.0.10", "jasmine-focused": "~0.15.0", @@ -41,7 +41,7 @@ "oniguruma": "0.24.0", "optimist": "0.4.0", "pathwatcher": "0.11.0", - "pegjs": "0.7.0", + "pegjs": "0.8.0", "q": "0.9.7", "scandal": "0.11.0", "season": "0.14.0", @@ -52,7 +52,8 @@ "underscore-plus": "0.6.1", "theorist": "~0.13.0", "delegato": "~0.4.0", - "mixto": "~0.4.0" + "mixto": "~0.4.0", + "underscore-plus": "0.6.1" }, "packageDependencies": { "atom-dark-syntax": "0.10.0", @@ -66,14 +67,14 @@ "autocomplete": "0.19.0", "autoflow": "0.11.0", "autosave": "0.10.0", - "background-tips": "0.3.0", + "background-tips": "0.4.0", "bookmarks": "0.15.0", "bracket-matcher": "0.16.0", "command-logger": "0.8.0", "command-palette": "0.14.0", "dev-live-reload": "0.22.0", "editor-stats": "0.12.0", - "exception-reporting": "0.10.0", + "exception-reporting": "0.11.0", "feedback": "0.22.0", "find-and-replace": "0.74.0", "fuzzy-finder": "0.30.0", @@ -85,20 +86,21 @@ "image-view": "0.15.0", "keybinding-resolver": "0.8.0", "markdown-preview": "0.24.0", - "metrics": "0.20.0", + "markdown-preview": "0.23.0", + "metrics": "0.21.0", "package-generator": "0.23.0", "release-notes": "0.15.0", "settings-view": "0.55.0", - "snippets": "0.17.0", + "snippets": "0.18.0", "spell-check": "0.18.0", - "status-bar": "0.30.0", + "status-bar": "0.31.0", "styleguide": "0.19.0", "symbols-view": "0.27.0", "tabs": "0.17.0", "terminal": "0.23.0", - "timecop": "0.12.0", + "timecop": "0.13.0", "to-the-hubs": "0.17.0", - "tree-view": "0.58.0", + "tree-view": "0.59.0", "visual-bell": "0.6.0", "welcome": "0.4.0", "whitespace": "0.10.0", diff --git a/src/key-binding.coffee b/src/key-binding.coffee index 11b4505d0..1f3ad1d65 100644 --- a/src/key-binding.coffee +++ b/src/key-binding.coffee @@ -1,8 +1,6 @@ -{$} = require './space-pen-extensions' _ = require 'underscore-plus' fs = require 'fs-plus' {specificity} = require 'clear-cut' -PEG = require 'pegjs' ### Internal ### @@ -10,28 +8,41 @@ module.exports = class KeyBinding @parser: null @currentIndex: 1 + @specificities: null + + @calculateSpecificity: (selector) -> + @specificities ?= {} + value = @specificities[selector] + unless value? + value = specificity(selector) + @specificities[selector] = value + value @normalizeKeystroke: (keystroke) -> normalizedKeystroke = keystroke.split(/\s+/).map (keystroke) => - keys = @getParser().parse(keystroke) + keys = @parseKeystroke(keystroke) modifiers = keys[0...-1] modifiers.sort() [modifiers..., _.last(keys)].join('-') normalizedKeystroke.join(' ') - @getParser: -> - if not KeyBinding.parser - keystrokePattern = fs.readFileSync(require.resolve('./keystroke-pattern.pegjs'), 'utf8') - KeyBinding.parser = PEG.buildParser(keystrokePattern) + @parseKeystroke: (keystroke) -> + unless @parser? + try + @parser = require './keystroke-pattern' + catch + keystrokePattern = fs.readFileSync(require.resolve('./keystroke-pattern.pegjs'), 'utf8') + PEG = require 'pegjs' + @parser = PEG.buildParser(keystrokePattern) - KeyBinding.parser + @parser.parse(keystroke) constructor: (source, command, keystroke, selector) -> @source = source @command = command @keystroke = KeyBinding.normalizeKeystroke(keystroke) @selector = selector.replace(/!important/g, '') - @specificity = specificity(selector) + @specificity = KeyBinding.calculateSpecificity(selector) @index = KeyBinding.currentIndex++ matches: (keystroke) -> diff --git a/src/task.coffee b/src/task.coffee index de8d3de10..80eaa81b8 100644 --- a/src/task.coffee +++ b/src/task.coffee @@ -91,6 +91,7 @@ class Task # * message: # The message to send send: (message) -> + throw new Error("Cannot send message to terminated process") unless @childProcess? @childProcess.send(message) # Public: Forcefully stop the running task.