mirror of
https://github.com/atom/atom.git
synced 2026-01-25 23:08:18 -05:00
Merge branch 'master' into aw/custom-line-number-gutter
This commit is contained in:
6563
apm/package-lock.json
generated
Normal file
6563
apm/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,6 @@
|
||||
"url": "https://github.com/atom/atom.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"atom-package-manager": "1.19.0"
|
||||
"atom-package-manager": "2.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,8 +79,8 @@
|
||||
'ctrl-shift-tab ^ctrl': 'pane:move-active-item-to-top-of-stack'
|
||||
'cmd-=': 'window:increase-font-size'
|
||||
'cmd-+': 'window:increase-font-size'
|
||||
'cmd--': 'window:decrease-font-size'
|
||||
'cmd-_': 'window:decrease-font-size'
|
||||
'cmd--': 'window:decrease-font-size'
|
||||
'cmd-0': 'window:reset-font-size'
|
||||
|
||||
'cmd-k up': 'pane:split-up-and-copy-active-item' # Atom Specific
|
||||
|
||||
5971
package-lock.json
generated
Normal file
5971
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
102
package.json
102
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "atom",
|
||||
"productName": "Atom",
|
||||
"version": "1.30.0-dev",
|
||||
"version": "1.31.0-dev",
|
||||
"description": "A hackable text editor for the 21st Century.",
|
||||
"main": "./src/main-process/main.js",
|
||||
"repository": {
|
||||
@@ -15,23 +15,48 @@
|
||||
"electronVersion": "2.0.5",
|
||||
"dependencies": {
|
||||
"@atom/nsfw": "^1.0.18",
|
||||
"@atom/watcher": "1.0.3",
|
||||
"@atom/source-map-support": "^0.3.4",
|
||||
"@atom/watcher": "1.0.3",
|
||||
"about": "https://www.atom.io/api/packages/about/versions/1.10.0/tarball",
|
||||
"archive-view": "https://www.atom.io/api/packages/archive-view/versions/0.65.1/tarball",
|
||||
"async": "0.2.6",
|
||||
"atom-dark-syntax": "https://www.atom.io/api/packages/atom-dark-syntax/versions/0.29.0/tarball",
|
||||
"atom-dark-ui": "https://www.atom.io/api/packages/atom-dark-ui/versions/0.53.2/tarball",
|
||||
"atom-keymap": "8.2.10",
|
||||
"atom-light-syntax": "https://www.atom.io/api/packages/atom-light-syntax/versions/0.29.0/tarball",
|
||||
"atom-light-ui": "https://www.atom.io/api/packages/atom-light-ui/versions/0.46.2/tarball",
|
||||
"atom-select-list": "^0.7.0",
|
||||
"atom-ui": "0.4.1",
|
||||
"autocomplete-atom-api": "https://www.atom.io/api/packages/autocomplete-atom-api/versions/0.10.7/tarball",
|
||||
"autocomplete-css": "https://www.atom.io/api/packages/autocomplete-css/versions/0.17.5/tarball",
|
||||
"autocomplete-html": "https://www.atom.io/api/packages/autocomplete-html/versions/0.8.4/tarball",
|
||||
"autocomplete-plus": "https://www.atom.io/api/packages/autocomplete-plus/versions/2.40.6/tarball",
|
||||
"autocomplete-snippets": "https://www.atom.io/api/packages/autocomplete-snippets/versions/1.12.0/tarball",
|
||||
"autoflow": "https://www.atom.io/api/packages/autoflow/versions/0.29.4/tarball",
|
||||
"autosave": "https://www.atom.io/api/packages/autosave/versions/0.24.6/tarball",
|
||||
"babel-core": "5.8.38",
|
||||
"background-tips": "https://www.atom.io/api/packages/background-tips/versions/0.28.0/tarball",
|
||||
"base16-tomorrow-dark-theme": "https://www.atom.io/api/packages/base16-tomorrow-dark-theme/versions/1.5.0/tarball",
|
||||
"base16-tomorrow-light-theme": "https://www.atom.io/api/packages/base16-tomorrow-light-theme/versions/1.5.0/tarball",
|
||||
"bookmarks": "https://www.atom.io/api/packages/bookmarks/versions/0.45.1/tarball",
|
||||
"bracket-matcher": "https://www.atom.io/api/packages/bracket-matcher/versions/0.89.2/tarball",
|
||||
"cached-run-in-this-context": "0.4.1",
|
||||
"chai": "3.5.0",
|
||||
"chart.js": "^2.3.0",
|
||||
"clear-cut": "^2.0.2",
|
||||
"coffee-script": "1.12.7",
|
||||
"color": "^0.7.3",
|
||||
"command-palette": "https://www.atom.io/api/packages/command-palette/versions/0.43.5/tarball",
|
||||
"dalek": "https://www.atom.io/api/packages/dalek/versions/0.2.2/tarball",
|
||||
"dedent": "^0.7.0",
|
||||
"deprecation-cop": "https://www.atom.io/api/packages/deprecation-cop/versions/0.56.9/tarball",
|
||||
"dev-live-reload": "https://www.atom.io/api/packages/dev-live-reload/versions/0.48.1/tarball",
|
||||
"devtron": "1.3.0",
|
||||
"encoding-selector": "https://www.atom.io/api/packages/encoding-selector/versions/0.23.9/tarball",
|
||||
"etch": "^0.12.6",
|
||||
"event-kit": "^2.5.0",
|
||||
"exception-reporting": "https://www.atom.io/api/packages/exception-reporting/versions/0.43.1/tarball",
|
||||
"find-and-replace": "https://www.atom.io/api/packages/find-and-replace/versions/0.215.11/tarball",
|
||||
"find-parent-dir": "^0.3.0",
|
||||
"first-mate": "7.1.1",
|
||||
"focus-trap": "2.4.5",
|
||||
@@ -39,24 +64,76 @@
|
||||
"fs-plus": "^3.0.1",
|
||||
"fstream": "0.1.24",
|
||||
"fuzzaldrin": "^2.1",
|
||||
"fuzzy-finder": "https://www.atom.io/api/packages/fuzzy-finder/versions/1.8.2/tarball",
|
||||
"git-diff": "https://www.atom.io/api/packages/git-diff/versions/1.3.9/tarball",
|
||||
"git-utils": "5.4.0",
|
||||
"github": "https://www.atom.io/api/packages/github/versions/0.18.2/tarball",
|
||||
"glob": "^7.1.1",
|
||||
"go-to-line": "https://www.atom.io/api/packages/go-to-line/versions/0.33.0/tarball",
|
||||
"grammar-selector": "https://www.atom.io/api/packages/grammar-selector/versions/0.50.1/tarball",
|
||||
"grim": "1.5.0",
|
||||
"image-view": "https://www.atom.io/api/packages/image-view/versions/0.63.0/tarball",
|
||||
"incompatible-packages": "https://www.atom.io/api/packages/incompatible-packages/versions/0.27.3/tarball",
|
||||
"jasmine-json": "~0.0",
|
||||
"jasmine-reporters": "1.1.0",
|
||||
"jasmine-tagged": "^1.1.4",
|
||||
"key-path-helpers": "^0.4.0",
|
||||
"keybinding-resolver": "https://www.atom.io/api/packages/keybinding-resolver/versions/0.38.2/tarball",
|
||||
"language-c": "https://www.atom.io/api/packages/language-c/versions/0.60.0/tarball",
|
||||
"language-clojure": "https://www.atom.io/api/packages/language-clojure/versions/0.22.7/tarball",
|
||||
"language-coffee-script": "https://www.atom.io/api/packages/language-coffee-script/versions/0.49.3/tarball",
|
||||
"language-csharp": "https://www.atom.io/api/packages/language-csharp/versions/1.0.4/tarball",
|
||||
"language-css": "https://www.atom.io/api/packages/language-css/versions/0.42.11/tarball",
|
||||
"language-gfm": "https://www.atom.io/api/packages/language-gfm/versions/0.90.5/tarball",
|
||||
"language-git": "https://www.atom.io/api/packages/language-git/versions/0.19.1/tarball",
|
||||
"language-go": "https://www.atom.io/api/packages/language-go/versions/0.46.0/tarball",
|
||||
"language-html": "https://www.atom.io/api/packages/language-html/versions/0.51.1/tarball",
|
||||
"language-hyperlink": "https://www.atom.io/api/packages/language-hyperlink/versions/0.16.3/tarball",
|
||||
"language-java": "https://www.atom.io/api/packages/language-java/versions/0.30.0/tarball",
|
||||
"language-javascript": "https://www.atom.io/api/packages/language-javascript/versions/0.129.1/tarball",
|
||||
"language-json": "https://www.atom.io/api/packages/language-json/versions/0.19.2/tarball",
|
||||
"language-less": "https://www.atom.io/api/packages/language-less/versions/0.34.2/tarball",
|
||||
"language-make": "https://www.atom.io/api/packages/language-make/versions/0.22.3/tarball",
|
||||
"language-mustache": "https://www.atom.io/api/packages/language-mustache/versions/0.14.5/tarball",
|
||||
"language-objective-c": "https://www.atom.io/api/packages/language-objective-c/versions/0.15.1/tarball",
|
||||
"language-perl": "https://www.atom.io/api/packages/language-perl/versions/0.38.1/tarball",
|
||||
"language-php": "https://www.atom.io/api/packages/language-php/versions/0.44.0/tarball",
|
||||
"language-property-list": "https://www.atom.io/api/packages/language-property-list/versions/0.9.1/tarball",
|
||||
"language-python": "https://www.atom.io/api/packages/language-python/versions/0.51.0/tarball",
|
||||
"language-ruby": "https://www.atom.io/api/packages/language-ruby/versions/0.72.2/tarball",
|
||||
"language-ruby-on-rails": "https://www.atom.io/api/packages/language-ruby-on-rails/versions/0.25.3/tarball",
|
||||
"language-sass": "https://www.atom.io/api/packages/language-sass/versions/0.62.0/tarball",
|
||||
"language-shellscript": "https://www.atom.io/api/packages/language-shellscript/versions/0.27.0/tarball",
|
||||
"language-source": "https://www.atom.io/api/packages/language-source/versions/0.9.0/tarball",
|
||||
"language-sql": "https://www.atom.io/api/packages/language-sql/versions/0.25.10/tarball",
|
||||
"language-text": "https://www.atom.io/api/packages/language-text/versions/0.7.4/tarball",
|
||||
"language-todo": "https://www.atom.io/api/packages/language-todo/versions/0.29.4/tarball",
|
||||
"language-toml": "https://www.atom.io/api/packages/language-toml/versions/0.18.2/tarball",
|
||||
"language-typescript": "https://www.atom.io/api/packages/language-typescript/versions/0.4.0/tarball",
|
||||
"language-xml": "https://www.atom.io/api/packages/language-xml/versions/0.35.2/tarball",
|
||||
"language-yaml": "https://www.atom.io/api/packages/language-yaml/versions/0.32.0/tarball",
|
||||
"less-cache": "1.1.0",
|
||||
"line-ending-selector": "https://www.atom.io/api/packages/line-ending-selector/versions/0.7.7/tarball",
|
||||
"line-top-index": "0.3.1",
|
||||
"link": "https://www.atom.io/api/packages/link/versions/0.31.4/tarball",
|
||||
"markdown-preview": "https://www.atom.io/api/packages/markdown-preview/versions/0.159.20/tarball",
|
||||
"marked": "^0.3.12",
|
||||
"metrics": "https://www.atom.io/api/packages/metrics/versions/1.6.0/tarball",
|
||||
"minimatch": "^3.0.3",
|
||||
"mocha": "2.5.1",
|
||||
"mocha-junit-reporter": "^1.13.0",
|
||||
"mocha-multi-reporters": "^1.1.4",
|
||||
"mock-spawn": "^0.2.6",
|
||||
"normalize-package-data": "^2.0.0",
|
||||
"notifications": "https://www.atom.io/api/packages/notifications/versions/0.70.5/tarball",
|
||||
"nslog": "^3",
|
||||
"one-dark-syntax": "https://www.atom.io/api/packages/one-dark-syntax/versions/1.8.4/tarball",
|
||||
"one-dark-ui": "https://www.atom.io/api/packages/one-dark-ui/versions/1.12.4/tarball",
|
||||
"one-light-syntax": "https://www.atom.io/api/packages/one-light-syntax/versions/1.8.4/tarball",
|
||||
"one-light-ui": "https://www.atom.io/api/packages/one-light-ui/versions/1.12.4/tarball",
|
||||
"oniguruma": "6.2.1",
|
||||
"open-on-github": "https://www.atom.io/api/packages/open-on-github/versions/1.3.1/tarball",
|
||||
"package-generator": "https://www.atom.io/api/packages/package-generator/versions/1.3.0/tarball",
|
||||
"pathwatcher": "8.0.1",
|
||||
"postcss": "5.2.4",
|
||||
"postcss-selector-parser": "2.2.1",
|
||||
@@ -69,13 +146,28 @@
|
||||
"season": "^6.0.2",
|
||||
"semver": "^4.3.3",
|
||||
"service-hub": "^0.7.4",
|
||||
"settings-view": "https://www.atom.io/api/packages/settings-view/versions/0.255.0/tarball",
|
||||
"sinon": "1.17.4",
|
||||
"snippets": "https://www.atom.io/api/packages/snippets/versions/1.3.3/tarball",
|
||||
"solarized-dark-syntax": "https://www.atom.io/api/packages/solarized-dark-syntax/versions/1.1.5/tarball",
|
||||
"solarized-light-syntax": "https://www.atom.io/api/packages/solarized-light-syntax/versions/1.1.5/tarball",
|
||||
"spell-check": "https://www.atom.io/api/packages/spell-check/versions/0.74.0/tarball",
|
||||
"status-bar": "https://www.atom.io/api/packages/status-bar/versions/1.8.15/tarball",
|
||||
"styleguide": "https://www.atom.io/api/packages/styleguide/versions/0.49.11/tarball",
|
||||
"symbols-view": "https://www.atom.io/api/packages/symbols-view/versions/0.118.2/tarball",
|
||||
"tabs": "https://www.atom.io/api/packages/tabs/versions/0.109.2/tarball",
|
||||
"temp": "^0.8.3",
|
||||
"text-buffer": "13.14.5",
|
||||
"timecop": "https://www.atom.io/api/packages/timecop/versions/0.36.2/tarball",
|
||||
"tree-sitter": "0.13.0",
|
||||
"tree-view": "https://www.atom.io/api/packages/tree-view/versions/0.222.0/tarball",
|
||||
"typescript-simple": "1.0.0",
|
||||
"underscore-plus": "^1.6.8",
|
||||
"update-package-dependencies": "https://www.atom.io/api/packages/update-package-dependencies/versions/0.13.1/tarball",
|
||||
"welcome": "https://www.atom.io/api/packages/welcome/versions/0.36.6/tarball",
|
||||
"whitespace": "https://www.atom.io/api/packages/whitespace/versions/0.37.6/tarball",
|
||||
"winreg": "^1.2.1",
|
||||
"wrap-guide": "https://www.atom.io/api/packages/wrap-guide/versions/0.40.3/tarball",
|
||||
"yargs": "^3.23.0"
|
||||
},
|
||||
"packageDependencies": {
|
||||
@@ -96,7 +188,7 @@
|
||||
"autocomplete-atom-api": "0.10.7",
|
||||
"autocomplete-css": "0.17.5",
|
||||
"autocomplete-html": "0.8.4",
|
||||
"autocomplete-plus": "2.40.6",
|
||||
"autocomplete-plus": "2.40.7",
|
||||
"autocomplete-snippets": "1.12.0",
|
||||
"autoflow": "0.29.4",
|
||||
"autosave": "0.24.6",
|
||||
@@ -109,7 +201,7 @@
|
||||
"dev-live-reload": "0.48.1",
|
||||
"encoding-selector": "0.23.9",
|
||||
"exception-reporting": "0.43.1",
|
||||
"find-and-replace": "0.215.11",
|
||||
"find-and-replace": "0.215.12",
|
||||
"fuzzy-finder": "1.8.2",
|
||||
"github": "0.18.2",
|
||||
"git-diff": "1.3.9",
|
||||
@@ -158,7 +250,7 @@
|
||||
"language-perl": "0.38.1",
|
||||
"language-php": "0.44.0",
|
||||
"language-property-list": "0.9.1",
|
||||
"language-python": "0.51.0",
|
||||
"language-python": "0.51.1",
|
||||
"language-ruby": "0.72.2",
|
||||
"language-ruby-on-rails": "0.25.3",
|
||||
"language-sass": "0.62.0",
|
||||
|
||||
@@ -29,7 +29,6 @@ const argv = yargs
|
||||
|
||||
const checkChromedriverVersion = require('./lib/check-chromedriver-version')
|
||||
const cleanOutputDirectory = require('./lib/clean-output-directory')
|
||||
const cleanPackageLock = require('./lib/clean-package-lock')
|
||||
const codeSignOnMac = require('./lib/code-sign-on-mac')
|
||||
const codeSignOnWindows = require('./lib/code-sign-on-windows')
|
||||
const compressArtifacts = require('./lib/compress-artifacts')
|
||||
@@ -60,7 +59,6 @@ const CONFIG = require('./config')
|
||||
let binariesPromise = Promise.resolve()
|
||||
|
||||
if (!argv.existingBinaries) {
|
||||
cleanPackageLock()
|
||||
checkChromedriverVersion()
|
||||
cleanOutputDirectory()
|
||||
copyAssets()
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
// This module exports a function that deletes all `package-lock.json` files that do
|
||||
// not exist under a `node_modules` directory.
|
||||
|
||||
'use strict'
|
||||
|
||||
const CONFIG = require('../config')
|
||||
const fs = require('fs-extra')
|
||||
const glob = require('glob')
|
||||
const path = require('path')
|
||||
|
||||
module.exports = function () {
|
||||
console.log('Deleting problematic package-lock.json files')
|
||||
let paths = glob.sync(path.join(CONFIG.repositoryRootPath, '**', 'package-lock.json'), {ignore: [path.join('**', 'node_modules', '**'), path.join('**', 'vsts', '**')]})
|
||||
|
||||
for (let path of paths) {
|
||||
fs.unlinkSync(path)
|
||||
}
|
||||
}
|
||||
11381
script/package-lock.json
generated
Normal file
11381
script/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
3
spec/fixtures/git/master.git/config
vendored
3
spec/fixtures/git/master.git/config
vendored
@@ -4,3 +4,6 @@
|
||||
bare = false
|
||||
logallrefupdates = true
|
||||
ignorecase = true
|
||||
[remote "origin"]
|
||||
url = https://github.com/example-user/example-repo.git
|
||||
fetch = +refs/heads/*:refs/remotes/origin/*
|
||||
|
||||
@@ -219,6 +219,34 @@ describe('Pane', () => {
|
||||
runs(() => expect(eventOrder).toEqual(['add', 'remove']))
|
||||
})
|
||||
|
||||
it('subscribes to be notified when item terminates its pending state', () => {
|
||||
const fakeDisposable = { dispose: () => {} }
|
||||
const spy = jasmine.createSpy('onDidTerminatePendingState').andReturn((fakeDisposable))
|
||||
|
||||
const pane = new Pane(paneParams({items: []}))
|
||||
const item = {
|
||||
getTitle: () => '',
|
||||
onDidTerminatePendingState: spy
|
||||
}
|
||||
pane.addItem(item)
|
||||
|
||||
expect(spy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('subscribes to be notified when item is destroyed', () => {
|
||||
const fakeDisposable = { dispose: () => {} }
|
||||
const spy = jasmine.createSpy('onDidDestroy').andReturn((fakeDisposable))
|
||||
|
||||
const pane = new Pane(paneParams({items: []}))
|
||||
const item = {
|
||||
getTitle: () => '',
|
||||
onDidDestroy: spy
|
||||
}
|
||||
pane.addItem(item)
|
||||
|
||||
expect(spy).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
describe('when using the old API of ::addItem(item, index)', () => {
|
||||
beforeEach(() => spyOn(Grim, 'deprecate'))
|
||||
|
||||
|
||||
@@ -1000,10 +1000,13 @@ describe('Project', () => {
|
||||
const observed = []
|
||||
const disposable = atom.project.onDidAddRepository((repo) => observed.push(repo))
|
||||
|
||||
const repositoryPath = path.join(__dirname, '..')
|
||||
atom.project.addPath(repositoryPath)
|
||||
const projectRootPath = temp.mkdirSync()
|
||||
const fixtureRepoPath = fs.absolute(path.join(__dirname, 'fixtures', 'git', 'master.git'))
|
||||
fs.copySync(fixtureRepoPath, path.join(projectRootPath, '.git'))
|
||||
|
||||
atom.project.addPath(projectRootPath)
|
||||
expect(observed.length).toBe(1)
|
||||
expect(observed[0].getOriginURL()).toContain('atom/atom')
|
||||
expect(observed[0].getOriginURL()).toEqual('https://github.com/example-user/example-repo.git')
|
||||
|
||||
disposable.dispose()
|
||||
})
|
||||
@@ -1012,9 +1015,16 @@ describe('Project', () => {
|
||||
const observed = []
|
||||
const disposable = atom.project.onDidAddRepository((repo) => observed.push(repo))
|
||||
|
||||
atom.project.addPath(__dirname)
|
||||
const projectRootPath = temp.mkdirSync()
|
||||
const fixtureRepoPath = fs.absolute(path.join(__dirname, 'fixtures', 'git', 'master.git'))
|
||||
fs.copySync(fixtureRepoPath, path.join(projectRootPath, '.git'))
|
||||
|
||||
const projectSubDirPath = path.join(projectRootPath, 'sub-dir')
|
||||
fs.mkdirSync(projectSubDirPath)
|
||||
|
||||
atom.project.addPath(projectSubDirPath)
|
||||
expect(observed.length).toBe(1)
|
||||
expect(observed[0].getOriginURL()).toContain('atom/atom')
|
||||
expect(observed[0].getOriginURL()).toEqual('https://github.com/example-user/example-repo.git')
|
||||
|
||||
disposable.dispose()
|
||||
})
|
||||
|
||||
@@ -1304,6 +1304,206 @@ describe('TreeSitterLanguageMode', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('.bufferRangeForScopeAtPosition(selector?, position)', () => {
|
||||
describe('when selector = null', () => {
|
||||
it('returns the range of the smallest node at position', async () => {
|
||||
const grammar = new TreeSitterGrammar(atom.grammars, jsGrammarPath, {
|
||||
id: 'javascript',
|
||||
parser: 'tree-sitter-javascript'
|
||||
})
|
||||
|
||||
buffer.setText('foo({bar: baz});')
|
||||
|
||||
buffer.setLanguageMode(new TreeSitterLanguageMode({buffer, grammar}))
|
||||
await nextHighlightingUpdate(buffer.getLanguageMode())
|
||||
expect(editor.bufferRangeForScopeAtPosition(null, [0, 6])).toEqual(
|
||||
[[0, 5], [0, 8]]
|
||||
)
|
||||
expect(editor.bufferRangeForScopeAtPosition(null, [0, 9])).toEqual(
|
||||
[[0, 8], [0, 9]]
|
||||
)
|
||||
})
|
||||
|
||||
it('includes nodes in injected syntax trees', async () => {
|
||||
const jsGrammar = new TreeSitterGrammar(atom.grammars, jsGrammarPath, {
|
||||
id: 'javascript',
|
||||
parser: 'tree-sitter-javascript',
|
||||
scopes: {},
|
||||
injectionRegExp: 'javascript',
|
||||
injectionPoints: [HTML_TEMPLATE_LITERAL_INJECTION_POINT]
|
||||
})
|
||||
|
||||
const htmlGrammar = new TreeSitterGrammar(atom.grammars, htmlGrammarPath, {
|
||||
id: 'html',
|
||||
parser: 'tree-sitter-html',
|
||||
scopes: {},
|
||||
injectionRegExp: 'html',
|
||||
injectionPoints: [SCRIPT_TAG_INJECTION_POINT]
|
||||
})
|
||||
|
||||
atom.grammars.addGrammar(jsGrammar)
|
||||
atom.grammars.addGrammar(htmlGrammar)
|
||||
|
||||
buffer.setText(`
|
||||
<div>
|
||||
<script>
|
||||
html \`
|
||||
<span>\${person.name}</span>
|
||||
\`
|
||||
</script>
|
||||
</div>
|
||||
`)
|
||||
|
||||
const languageMode = new TreeSitterLanguageMode({buffer, grammar: htmlGrammar, grammars: atom.grammars})
|
||||
buffer.setLanguageMode(languageMode)
|
||||
await nextHighlightingUpdate(languageMode)
|
||||
await nextHighlightingUpdate(languageMode)
|
||||
await nextHighlightingUpdate(languageMode)
|
||||
|
||||
const nameProperty = buffer.findSync('name')
|
||||
const {start} = nameProperty
|
||||
const position = Object.assign({}, start, {column: start.column + 2})
|
||||
expect(languageMode.bufferRangeForScopeAtPosition(null, position))
|
||||
.toEqual(nameProperty)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with a selector', () => {
|
||||
it('returns the range of the smallest matching node at position', async () => {
|
||||
const grammar = new TreeSitterGrammar(atom.grammars, jsGrammarPath, {
|
||||
id: 'javascript',
|
||||
parser: 'tree-sitter-javascript'
|
||||
})
|
||||
|
||||
buffer.setText('foo({bar: baz});')
|
||||
|
||||
buffer.setLanguageMode(new TreeSitterLanguageMode({buffer, grammar}))
|
||||
await nextHighlightingUpdate(buffer.getLanguageMode())
|
||||
expect(editor.bufferRangeForScopeAtPosition('.property_identifier', [0, 6])).toEqual(
|
||||
buffer.findSync('bar')
|
||||
)
|
||||
expect(editor.bufferRangeForScopeAtPosition('.call_expression', [0, 6])).toEqual(
|
||||
[[0, 0], [0, buffer.getText().length - 1]]
|
||||
)
|
||||
expect(editor.bufferRangeForScopeAtPosition('.object', [0, 9])).toEqual(
|
||||
buffer.findSync('{bar: baz}')
|
||||
)
|
||||
})
|
||||
|
||||
it('includes nodes in injected syntax trees', async () => {
|
||||
const jsGrammar = new TreeSitterGrammar(atom.grammars, jsGrammarPath, {
|
||||
id: 'javascript',
|
||||
parser: 'tree-sitter-javascript',
|
||||
scopes: {},
|
||||
injectionRegExp: 'javascript',
|
||||
injectionPoints: [HTML_TEMPLATE_LITERAL_INJECTION_POINT]
|
||||
})
|
||||
|
||||
const htmlGrammar = new TreeSitterGrammar(atom.grammars, htmlGrammarPath, {
|
||||
id: 'html',
|
||||
parser: 'tree-sitter-html',
|
||||
scopes: {},
|
||||
injectionRegExp: 'html',
|
||||
injectionPoints: [SCRIPT_TAG_INJECTION_POINT]
|
||||
})
|
||||
|
||||
atom.grammars.addGrammar(jsGrammar)
|
||||
atom.grammars.addGrammar(htmlGrammar)
|
||||
|
||||
buffer.setText(`
|
||||
<div>
|
||||
<script>
|
||||
html \`
|
||||
<span>\${person.name}</span>
|
||||
\`
|
||||
</script>
|
||||
</div>
|
||||
`)
|
||||
|
||||
const languageMode = new TreeSitterLanguageMode({buffer, grammar: htmlGrammar, grammars: atom.grammars})
|
||||
buffer.setLanguageMode(languageMode)
|
||||
await nextHighlightingUpdate(languageMode)
|
||||
await nextHighlightingUpdate(languageMode)
|
||||
await nextHighlightingUpdate(languageMode)
|
||||
|
||||
const nameProperty = buffer.findSync('name')
|
||||
const {start} = nameProperty
|
||||
const position = Object.assign({}, start, {column: start.column + 2})
|
||||
expect(languageMode.bufferRangeForScopeAtPosition('.property_identifier', position))
|
||||
.toEqual(nameProperty)
|
||||
expect(languageMode.bufferRangeForScopeAtPosition('.element', position))
|
||||
.toEqual(buffer.findSync('<span>\\${person\\.name}</span>'))
|
||||
})
|
||||
|
||||
it('accepts node-matching functions as selectors', async () => {
|
||||
const jsGrammar = new TreeSitterGrammar(atom.grammars, jsGrammarPath, {
|
||||
id: 'javascript',
|
||||
parser: 'tree-sitter-javascript',
|
||||
scopes: {},
|
||||
injectionRegExp: 'javascript',
|
||||
injectionPoints: [HTML_TEMPLATE_LITERAL_INJECTION_POINT]
|
||||
})
|
||||
|
||||
const htmlGrammar = new TreeSitterGrammar(atom.grammars, htmlGrammarPath, {
|
||||
id: 'html',
|
||||
parser: 'tree-sitter-html',
|
||||
scopes: {},
|
||||
injectionRegExp: 'html',
|
||||
injectionPoints: [SCRIPT_TAG_INJECTION_POINT]
|
||||
})
|
||||
|
||||
atom.grammars.addGrammar(jsGrammar)
|
||||
atom.grammars.addGrammar(htmlGrammar)
|
||||
|
||||
buffer.setText(`
|
||||
<div>
|
||||
<script>
|
||||
html \`
|
||||
<span>\${person.name}</span>
|
||||
\`
|
||||
</script>
|
||||
</div>
|
||||
`)
|
||||
|
||||
const languageMode = new TreeSitterLanguageMode({buffer, grammar: htmlGrammar, grammars: atom.grammars})
|
||||
buffer.setLanguageMode(languageMode)
|
||||
await nextHighlightingUpdate(languageMode)
|
||||
await nextHighlightingUpdate(languageMode)
|
||||
await nextHighlightingUpdate(languageMode)
|
||||
|
||||
const nameProperty = buffer.findSync('name')
|
||||
const {start} = nameProperty
|
||||
const position = Object.assign({}, start, {column: start.column + 2})
|
||||
const templateStringInCallExpression = node =>
|
||||
node.type === 'template_string' && node.parent.type === 'call_expression'
|
||||
expect(languageMode.bufferRangeForScopeAtPosition(templateStringInCallExpression, position))
|
||||
.toEqual([[3, 19], [5, 15]])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('.getSyntaxNodeAtPosition(position, where?)', () => {
|
||||
it('returns the range of the smallest matching node at position', async () => {
|
||||
const grammar = new TreeSitterGrammar(atom.grammars, jsGrammarPath, {
|
||||
id: 'javascript',
|
||||
parser: 'tree-sitter-javascript'
|
||||
})
|
||||
|
||||
buffer.setText('foo(bar({x: 2}));')
|
||||
const languageMode = new TreeSitterLanguageMode({buffer, grammar})
|
||||
buffer.setLanguageMode(languageMode)
|
||||
await nextHighlightingUpdate(languageMode)
|
||||
expect(languageMode.getSyntaxNodeAtPosition([0, 6]).range).toEqual(
|
||||
buffer.findSync('bar')
|
||||
)
|
||||
const findFoo = node =>
|
||||
node.type === 'call_expression' && node.firstChild.text === 'foo'
|
||||
expect(languageMode.getSyntaxNodeAtPosition([0, 6], findFoo).range).toEqual(
|
||||
[[0, 0], [0, buffer.getText().length - 1]]
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('TextEditor.selectLargerSyntaxNode and .selectSmallerSyntaxNode', () => {
|
||||
it('expands and contracts the selection based on the syntax tree', async () => {
|
||||
const grammar = new TreeSitterGrammar(atom.grammars, jsGrammarPath, {
|
||||
|
||||
14
src/pane.js
14
src/pane.js
@@ -614,15 +614,15 @@ class Pane {
|
||||
|
||||
if (this.items.includes(item)) return
|
||||
|
||||
const itemSubscriptions = new CompositeDisposable()
|
||||
this.subscriptionsPerItem.set(item, itemSubscriptions)
|
||||
if (typeof item.onDidDestroy === 'function') {
|
||||
const itemSubscriptions = new CompositeDisposable()
|
||||
itemSubscriptions.add(item.onDidDestroy(() => this.removeItem(item, false)))
|
||||
if (typeof item.onDidTerminatePendingState === 'function') {
|
||||
itemSubscriptions.add(item.onDidTerminatePendingState(() => {
|
||||
if (this.getPendingItem() === item) this.clearPendingItem()
|
||||
}))
|
||||
}
|
||||
this.subscriptionsPerItem.set(item, itemSubscriptions)
|
||||
}
|
||||
if (typeof item.onDidTerminatePendingState === 'function') {
|
||||
itemSubscriptions.add(item.onDidTerminatePendingState(() => {
|
||||
if (this.getPendingItem() === item) this.clearPendingItem()
|
||||
}))
|
||||
}
|
||||
|
||||
this.items.splice(index, 0, item)
|
||||
|
||||
38
src/selectors.js
Normal file
38
src/selectors.js
Normal file
@@ -0,0 +1,38 @@
|
||||
module.exports = {selectorMatchesAnyScope, matcherForSelector}
|
||||
|
||||
const {isSubset} = require('underscore-plus')
|
||||
|
||||
// Private: Parse a selector into parts.
|
||||
// If already parsed, returns the selector unmodified.
|
||||
//
|
||||
// * `selector` a {String|Array<String>} specifying what to match
|
||||
// Returns selector parts, an {Array<String>}.
|
||||
function parse (selector) {
|
||||
return typeof selector === 'string'
|
||||
? selector.replace(/^\./, '').split('.')
|
||||
: selector
|
||||
}
|
||||
|
||||
const always = scope => true
|
||||
|
||||
// Essential: Return a matcher function for a selector.
|
||||
//
|
||||
// * selector, a {String} selector
|
||||
// Returns {(scope: String) -> Boolean}, a matcher function returning
|
||||
// true iff the scope matches the selector.
|
||||
function matcherForSelector (selector) {
|
||||
const parts = parse(selector)
|
||||
if (typeof parts === 'function') return parts
|
||||
return selector
|
||||
? scope => isSubset(parts, parse(scope))
|
||||
: always
|
||||
}
|
||||
|
||||
// Essential: Return true iff the selector matches any provided scope.
|
||||
//
|
||||
// * {String} selector
|
||||
// * {Array<String>} scopes
|
||||
// Returns {Boolean} true if any scope matches the selector.
|
||||
function selectorMatchesAnyScope (selector, scopes) {
|
||||
return !selector || scopes.some(matcherForSelector(selector))
|
||||
}
|
||||
@@ -7,6 +7,7 @@ const ScopeDescriptor = require('./scope-descriptor')
|
||||
const NullGrammar = require('./null-grammar')
|
||||
const {OnigRegExp} = require('oniguruma')
|
||||
const {toFirstMateScopeId, fromFirstMateScopeId} = require('./first-mate-helpers')
|
||||
const {selectorMatchesAnyScope} = require('./selectors')
|
||||
|
||||
const NON_WHITESPACE_REGEX = /\S/
|
||||
|
||||
@@ -726,14 +727,6 @@ class TextMateLanguageMode {
|
||||
|
||||
TextMateLanguageMode.prototype.chunkSize = 50
|
||||
|
||||
function selectorMatchesAnyScope (selector, scopes) {
|
||||
const targetClasses = selector.replace(/^\./, '').split('.')
|
||||
return scopes.some((scope) => {
|
||||
const scopeClasses = scope.split('.')
|
||||
return _.isSubset(targetClasses, scopeClasses)
|
||||
})
|
||||
}
|
||||
|
||||
class TextMateHighlightIterator {
|
||||
constructor (languageMode) {
|
||||
this.languageMode = languageMode
|
||||
|
||||
@@ -5,6 +5,7 @@ const {Emitter, Disposable} = require('event-kit')
|
||||
const ScopeDescriptor = require('./scope-descriptor')
|
||||
const TokenizedLine = require('./tokenized-line')
|
||||
const TextMateLanguageMode = require('./text-mate-language-mode')
|
||||
const {matcherForSelector} = require('./selectors')
|
||||
|
||||
let nextId = 0
|
||||
const MAX_RANGE = new Range(Point.ZERO, Point.INFINITY).freeze()
|
||||
@@ -20,6 +21,13 @@ class TreeSitterLanguageMode {
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!Parser.SyntaxNode.prototype.hasOwnProperty('range')) {
|
||||
Object.defineProperty(Parser.SyntaxNode.prototype, 'range', {
|
||||
get () {
|
||||
return rangeForNode(this)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
constructor ({buffer, grammar, config, grammars}) {
|
||||
@@ -334,7 +342,7 @@ class TreeSitterLanguageMode {
|
||||
Section - Syntax Tree APIs
|
||||
*/
|
||||
|
||||
getRangeForSyntaxNodeContainingRange (range) {
|
||||
getSyntaxNodeContainingRange (range, where = _ => true) {
|
||||
const startIndex = this.buffer.characterIndexForPosition(range.start)
|
||||
const endIndex = this.buffer.characterIndexForPosition(range.end)
|
||||
const searchEndIndex = Math.max(0, endIndex - 1)
|
||||
@@ -342,17 +350,35 @@ class TreeSitterLanguageMode {
|
||||
let smallestNode
|
||||
this._forEachTreeWithRange(range, tree => {
|
||||
let node = tree.rootNode.descendantForIndex(startIndex, searchEndIndex)
|
||||
while (node && !nodeContainsIndices(node, startIndex, endIndex)) {
|
||||
while (node) {
|
||||
if (nodeContainsIndices(node, startIndex, endIndex) && where(node)) {
|
||||
if (nodeIsSmaller(node, smallestNode)) smallestNode = node
|
||||
break
|
||||
}
|
||||
node = node.parent
|
||||
}
|
||||
if (nodeIsSmaller(node, smallestNode)) smallestNode = node
|
||||
})
|
||||
|
||||
if (smallestNode) return rangeForNode(smallestNode)
|
||||
return smallestNode
|
||||
}
|
||||
|
||||
bufferRangeForScopeAtPosition (position) {
|
||||
return this.getRangeForSyntaxNodeContainingRange(new Range(position, position))
|
||||
getRangeForSyntaxNodeContainingRange (range, where) {
|
||||
const node = this.getSyntaxNodeContainingRange(range, where)
|
||||
return node && node.range
|
||||
}
|
||||
|
||||
getSyntaxNodeAtPosition (position, where) {
|
||||
return this.getSyntaxNodeContainingRange(new Range(position, position), where)
|
||||
}
|
||||
|
||||
bufferRangeForScopeAtPosition (selector, position) {
|
||||
if (typeof selector === 'string') {
|
||||
const match = matcherForSelector(selector)
|
||||
selector = ({type}) => match(type)
|
||||
}
|
||||
if (selector === null) selector = undefined
|
||||
const node = this.getSyntaxNodeAtPosition(position, selector)
|
||||
return node && node.range
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -849,15 +875,10 @@ class LayerHighlightIterator {
|
||||
let result = false
|
||||
const {endIndex} = this.treeCursor
|
||||
let depth = this.containingNodeEndIndices.length
|
||||
while (depth > 1) {
|
||||
// Once the iterator has found a scope boundary, it needs to stay at the same
|
||||
// position, so it should not move up if the parent node ends later than the
|
||||
// current node.
|
||||
if ((!atLastChild || this.openTags.length || this.closeTags.length) &&
|
||||
this.containingNodeEndIndices[depth - 2] > endIndex) {
|
||||
break
|
||||
}
|
||||
|
||||
// The iterator should not move up until it has visited all of the children of this node.
|
||||
while (depth > 1 && (atLastChild || this.containingNodeEndIndices[depth - 2] === endIndex)) {
|
||||
atLastChild = false
|
||||
result = true
|
||||
this.treeCursor.gotoParent()
|
||||
this.containingNodeTypes.pop()
|
||||
@@ -873,10 +894,11 @@ class LayerHighlightIterator {
|
||||
_moveDown () {
|
||||
let result = false
|
||||
const {startIndex} = this.treeCursor
|
||||
|
||||
// Once the iterator has found a scope boundary, it needs to stay at the same
|
||||
// position, so it should not move down if the first child node starts later than the
|
||||
// current node.
|
||||
while (this.treeCursor.gotoFirstChild()) {
|
||||
// Once the iterator has found a scope boundary, it needs to stay at the same
|
||||
// position, so it should not move down if the first child node starts later than the
|
||||
// current node.
|
||||
if ((this.closeTags.length || this.openTags.length) &&
|
||||
this.treeCursor.startIndex > startIndex) {
|
||||
this.treeCursor.gotoParent()
|
||||
|
||||
Reference in New Issue
Block a user