问题
I am creating a plugin for ST3 and need the list of all defined scopes. I know that hitting ctrl+alt+shift+p
shows the current scope in the status bar but I can't do it for every file extension.
Edit:
In addition to simple .tmLanguage
files I am extracting the .sublime-package
files and reading .tmLanguage
files from inside. This added some entries like source.php
to the list. But source.python
is still missing !
Actually, the python code is: ( this is for Python 3.3 )
import sublime, sublime_plugin, os, subprocess, glob, tempfile, plistlib
from zipfile import ZipFile
def scopes_inside(d):
result = []
for k in d.keys():
if k == 'scopeName':
result = result + [ s.strip() for s in d[k].split(',') ]
elif isinstance(d[k], dict):
result = result + scopes_inside(d[k])
return result
scopes = set()
for x in os.walk(sublime.packages_path() + '/..'):
for f in glob.glob(os.path.join(x[0], '*.tmLanguage')):
for s in scopes_inside(plistlib.readPlist(f)):
scopes.add(s.strip())
for x in os.walk(sublime.packages_path() + '/..'):
for f in glob.glob(os.path.join(x[0], '*.sublime-package')):
input_zip = ZipFile(f)
for name in input_zip.namelist():
if name.endswith('.tmLanguage'):
for s in self.get_scopes_from(plistlib.readPlistFromBytes(input_zip.read(name))):
scopes.add(s.strip())
scopes = list(scopes)
And it gives this list now:
"font",
"license",
"source.c++",
"source.cmake",
"source.coffee",
"source.css",
"source.d",
"source.disasm",
"source.dockerfile",
"source.gdb.session",
"source.gdbregs",
"source.git",
"source.gradle",
"source.groovy",
"source.gruntfile.coffee",
"source.gruntfile.js",
"source.gulpfile.coffee",
"source.gulpfile.js",
"source.ini",
"source.ini.editorconfig",
"source.jade",
"source.jl",
"source.js",
"source.json",
"source.json.bower",
"source.json.npm",
"source.jsx",
"source.less",
"source.php",
"source.procfile",
"source.puppet",
"source.pyjade",
"source.qml",
"source.rust",
"source.sass",
"source.scss",
"source.shell",
"source.stylus",
"source.swift",
"source.yaml",
"source.zen.5a454e6772616d6d6172",
"text.html.basic",
"text.html.mustache",
"text.html.ruby",
"text.html.twig",
"text.slim",
"text.todo"
But I can't find some languages like python
in this list. I guess other are stored within some binary files somewhere within the installation folder. If that's true so how the parse thoses files ?
回答1:
I just found the remaining packages wich are stored within the installation directory. So the final code which gives all scope names is:
import sublime, sublime_plugin, os, subprocess, glob, tempfile, plistlib
from zipfile import ZipFile
# This function gives array of scope names from the plist dictionary passed as argument
def scopes_inside(d):
result = []
for k in d.keys():
if k == 'scopeName':
result = result + [ s.strip() for s in d[k].split(',') ]
elif isinstance(d[k], dict):
result = result + scopes_inside(d[k])
return result
# Using set to have unique values
scopes = set()
# Parsing all .tmLanguage files from the Packages directory
for x in os.walk(sublime.packages_path()):
for f in glob.glob(os.path.join(x[0], '*.tmLanguage')):
for s in scopes_inside(plistlib.readPlist(f)):
scopes.add(s.strip())
# Parsing all .tmLanguage files inside .sublime-package files from the Installed Packages directory
for x in os.walk(sublime.installed_packages_path()):
for f in glob.glob(os.path.join(x[0], '*.sublime-package')):
input_zip = ZipFile(f)
for name in input_zip.namelist():
if name.endswith('.tmLanguage'):
for s in self.get_scopes_from(plistlib.readPlistFromBytes(input_zip.read(name))):
scopes.add(s.strip())
# Parsing all .tmLanguage files inside .sublime-package files from the Installation directory
for x in os.walk(os.path.dirname(sublime.executable_path())):
for f in glob.glob(os.path.join(x[0], '*.sublime-package')):
input_zip = ZipFile(f)
for name in input_zip.namelist():
if name.endswith('.tmLanguage'):
for s in self.get_scopes_from(plistlib.readPlistFromBytes(input_zip.read(name))):
scopes.add(s.strip())
scopes = list(scopes)
This code may give different results depending on Packages installed (some packages add new syntax/scope names). In my case, the result was :
font
license
source.actionscript.2
source.applescript
source.asp
source.c
source.c++
source.camlp4.ocaml
source.clojure
source.cmake
source.coffee
source.cs
source.css
source.d
source.diff
source.disasm
source.dockerfile
source.dosbatch
source.dot
source.erlang
source.gdb.session
source.gdbregs
source.git
source.go
source.gradle
source.groovy
source.gruntfile.coffee
source.gruntfile.js
source.gulpfile.coffee
source.gulpfile.js
source.haskell
source.ini
source.ini.editorconfig
source.jade
source.java
source.java-props
source.jl
source.js
source.js.rails
source.json
source.json.bower
source.json.npm
source.jsx
source.less
source.lisp
source.lua
source.makefile
source.matlab
source.nant-build
source.objc
source.objc++
source.ocaml
source.ocamllex
source.ocamlyacc
source.pascal
source.perl
source.php
source.procfile
source.puppet
source.pyjade
source.python
source.qml
source.r
source.r-console
source.regexp
source.regexp.python
source.ruby
source.ruby.rails
source.rust
source.sass
source.scala
source.scss
source.shell
source.sql
source.sql.ruby
source.stylus
source.swift
source.tcl
source.yaml
source.zen.5a454e6772616d6d6172
text.bibtex
text.haml
text.html.asp
text.html.basic
text.html.erlang.yaws
text.html.javadoc
text.html.jsp
text.html.markdown
text.html.markdown.multimarkdown
text.html.mustache
text.html.ruby
text.html.tcl
text.html.textile
text.html.twig
text.log.latex
text.plain
text.restructuredtext
text.slim
text.tex
text.tex.latex
text.tex.latex.beamer
text.tex.latex.haskell
text.tex.latex.memoir
text.tex.latex.rd
text.tex.math
text.todo
text.xml
text.xml.xsl
来源:https://stackoverflow.com/questions/30153110/get-all-scope-names-on-sublime-text-3