├── .editorconfig ├── .gitattributes ├── .gitignore ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── appveyor.yml ├── grammars ├── emacs-lisp.cson ├── muse.cson └── yasnippet.cson ├── index.js ├── package.json ├── settings └── editor.cson └── snippets └── snippets.cson /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | trim_trailing_whitespace = false 8 | indent_style = tab 9 | 10 | [*.el] 11 | indent_style = space 12 | indent_size = 2 13 | 14 | [*.{yaml,yml}] 15 | indent_style = space 16 | indent_size = 4 17 | 18 | [*.yasnippet] 19 | insert_final_newline = false 20 | 21 | 22 | # Fixture files 23 | [spec/fixtures/input/*.muse] 24 | indent_style = space 25 | indent_size = 2 26 | 27 | [spec/fixtures/input/literal-{html,texinfo,xml}.muse] 28 | indent_style = tab 29 | indent_size = unset 30 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Include CSON files in GitHub's language breakdown graph 2 | *.cson linguist-detectable 3 | 4 | # Don't convert line-endings on Windows 5 | /spec/fixtures/*/* binary 6 | 7 | # Exclude from package distribution 8 | *.sy export-ignore linguist-language=RegExp 9 | /spec export-ignore 10 | /.travis.yml export-ignore 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Thumbs.db 3 | Desktop.ini 4 | node_modules 5 | package-lock.json 6 | ._* 7 | .\#* 8 | \#*\# 9 | *~ 10 | *.log 11 | *.lock 12 | [._]*.s[a-v][a-z] 13 | [._]*.sw[a-p] 14 | [._]s[a-v][a-z] 15 | [._]sw[a-p] 16 | !urls.log 17 | /test.mjs 18 | /test.js 19 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Change Log 2 | ========== 3 | 4 | This project adheres to [Semantic Versioning](http://semver.org). 5 | 6 | [Unpublished]: ../../compare/v1.4.1...HEAD 7 | 8 | 9 | [Unpublished] 10 | ------------------------------------------------------------------------ 11 | * __Added:__ Highlighting for [key binding substitution sequences][2] in 12 | Elisp comments and docstrings, introduced (or changed) circa Emacs 28.1. 13 | * __Fixed:__ Escaped brackets and quotes not recognised in YASnippets 14 | * __Improved:__ Highlighting of escape sequences in strings on GitHub 15 | 16 | [2]: https://bit.ly/44MSmgO 17 | 18 | 19 | [v1.4.1] 20 | ------------------------------------------------------------------------ 21 | **August 4th, 2021** 22 | * __Added:__ Comment highlighting for interpreter directives (hashbangs) 23 | * __Added:__ Snippets for [YASnippet][] metadata and placeholders 24 | * __Fixed:__ [Various inaccuracies][1] related to modeline matching 25 | 26 | [1]: https://github.com/github/linguist/pull/5271 27 | 28 | 29 | 30 | [v1.4.0] 31 | ------------------------------------------------------------------------ 32 | **October 17th, 2019** 33 | * __Added:__ Syntax highlighting for [Emacs Muse] and [AmuseWiki] markup 34 | * __Added:__ Highlighting for [`el-get`], [`straight.el`] and [`quelpa`] 35 | * __Fixed:__ Automatic insertion of closing backticks and single-quotes 36 | * __Fixed:__ Unescaped and mangled output from evaluation commands 37 | 38 | 39 | 40 | [v1.3.1] 41 | ------------------------------------------------------------------------ 42 | **July 1st, 2019** 43 | * __Added:__ Highlighting for another 30 keywords used by [`mocha.el`][] 44 | * __Added:__ Highlighting for the [`use-package`][] macro 45 | * __Fixed:__ Highlighting of YASnippets without prologues 46 | 47 | 48 | 49 | [v1.3.0] 50 | ------------------------------------------------------------------------ 51 | **September 6th, 2018** 52 | * __Added:__ `defun` highlighting for `cl-{defun,defmacro,defsubst}` 53 | * __Added:__ Highlighting for "magic" autoloading comments 54 | * __Added:__ Highlighting for another 1,935 function names 55 | * __Added:__ Support for strings using ASCII-style directional quotes 56 | * __Added:__ Syntax highlighting for [YASnippet][] files 57 | * __Fixed:__ Inconsistent highlighting of `(lambda())` and `(lambda ())` 58 | * __Fixed:__ Missing highlighting of `,` when inserting symbols 59 | 60 | 61 | 62 | [v1.2.0] 63 | ------------------------------------------------------------------------ 64 | **October 14th, 2017** 65 | * __Added:__ Highlighting for faces and another 30,134 function names, 66 | courtesy of [Endless Parentheses](http://doc.endlessparentheses.com/) 67 | * __Fixed:__ Broken highlighting of `<=` and `>=` in functions 68 | * __Fixed:__ Editor commands still registered after deactivating package 69 | * __Fixed:__ Deprecation warning when evaluating Lisp expressions 70 | * __Fixed:__ Duplicated output when `language-emacs-lisp:run-selection` 71 | is used to evaluate an expression already enclosed by `(message "%s" …)` 72 | 73 | 74 | [v1.1.1] 75 | ------------------------------------------------------------------------ 76 | **October 2nd, 2016** 77 | * __Fixed [#1]:__ Inaccurate matching of formatting specifiers 78 | 79 | [#1]: https://github.com/Alhadis/language-emacs-lisp/issues/1 80 | 81 | 82 | [v1.1.0] 83 | ------------------------------------------------------------------------ 84 | **September 28th, 2016** 85 | Improves file support and highlighting of numeric constants. 86 | 87 | * __Added:__ File extension support for `_emacs`, `abbrev_defs`, `.eld`, 88 | `gnus`, `Project.ede`, and `viper` 89 | * __Added:__ Highlighting to pair separators and square brackets 90 | * __Added:__ Recognition of modelines and hashbangs 91 | * __Added:__ Support for [character escape sequences][2.3.3.2] 92 | * __Fixed:__ Partial highlighting of binary and hexadecimal literals 93 | * __Fixed:__ Partial highlighting of `±INF` and `±NaN` constants 94 | 95 | 96 | [v1.0.1] 97 | ------------------------------------------------------------------------ 98 | **August 29th, 2016** 99 | Small patch to fix broken highlighting in certain symbols with dashes. 100 | 101 | 102 | [v1.0.0] 103 | ------------------------------------------------------------------------ 104 | **August 28th, 2016** 105 | Initial release. Adds editor commands and highlighting for Emacs Lisp. 106 | 107 | 108 | [Referenced links]:_____________________________________________________ 109 | [v1.4.1]: https://github.com/Alhadis/language-emacs-lisp/releases/v1.4.1 110 | [v1.4.0]: https://github.com/Alhadis/language-emacs-lisp/releases/v1.4.0 111 | [v1.3.1]: https://github.com/Alhadis/language-emacs-lisp/releases/v1.3.1 112 | [v1.3.0]: https://github.com/Alhadis/language-emacs-lisp/releases/v1.3.0 113 | [v1.2.0]: https://github.com/Alhadis/language-emacs-lisp/releases/v1.2.0 114 | [v1.1.1]: https://github.com/Alhadis/language-emacs-lisp/releases/v1.1.1 115 | [v1.1.0]: https://github.com/Alhadis/language-emacs-lisp/releases/v1.1.0 116 | [v1.0.1]: https://github.com/Alhadis/language-emacs-lisp/releases/v1.0.1 117 | [v1.0.0]: https://github.com/Alhadis/language-emacs-lisp/releases/v1.0.0 118 | [2.3.3.2]: http://www.hep.by/gnu/elisp/General-Escape-Syntax.html 119 | [AmuseWiki]: https://amusewiki.org/library/manual 120 | [Emacs Muse]: https://gnu.org/software/emacs-muse/manual/muse.html 121 | [YASnippet]: http://joaotavora.github.io/yasnippet 122 | [`el-get`]: https://github.com/dimitri/el-get 123 | [`mocha.el`]: https://github.com/scottaj/mocha.el 124 | [`quelpa`]: https://github.com/quelpa/quelpa 125 | [`straight.el`]: https://github.com/raxod502/straight.el 126 | [`use-package`]: https://github.com/jwiegley/use-package 127 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016-2023, John Gardner 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Emacs Lisp Support 2 | ================== 3 | 4 | [![Build status: TravisCI][TravisCI-badge]][TravisCI-link] 5 | [![Build status: AppVeyor][AppVeyor-badge]][AppVeyor-link] 6 | [![Latest package version][APM-badge]][APM-link] 7 | 8 | Hand-crafted syntax highlighting and editor commands for Emacs Lisp in Atom. 9 | 10 | Atomacs 11 | 12 | 13 | Commands 14 | -------- 15 | This package includes two commands to run Lisp code in Emacs from Atom: 16 | 17 | * `language-emacs-lisp:run-selection` 18 | * `language-emacs-lisp:run-file` 19 | 20 | Math: One not even 21 | 22 | These aren't attached to any keybindings by default. You'll need to assign them 23 | [shortcuts](http://flight-manual.atom.io/behind-atom/sections/keymaps-in-depth/) 24 | yourself. 25 | 26 | **NOTE:** 27 | These require Emacs to be in your `$PATH`, and probably don't work on Windows. 28 | 29 | 30 | 31 | [TravisCI-badge]: https://travis-ci.org/Alhadis/language-emacs-lisp.svg?branch=master 32 | [TravisCI-link]: https://travis-ci.org/Alhadis/language-emacs-lisp 33 | [AppVeyor-badge]: https://ci.appveyor.com/api/projects/status/9m9wn1u6f76wr05f?svg=true 34 | [AppVeyor-link]: https://ci.appveyor.com/project/Alhadis/language-emacs-lisp 35 | [APM-badge]: https://img.shields.io/apm/v/language-emacs-lisp.svg?colorB=brightgreen 36 | [APM-link]: https://atom.io/packages/language-emacs-lisp 37 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: "{build}" 2 | platform: x64 3 | test: on 4 | build: off 5 | deploy: off 6 | skip_tags: true 7 | 8 | branches: 9 | only: 10 | - master 11 | 12 | environment: 13 | matrix: 14 | - ATOM_CHANNEL: stable 15 | - ATOM_CHANNEL: beta 16 | 17 | install: 18 | - ps: Install-Product node $env:nodejs_version 19 | 20 | test_script: 21 | - ps: (New-Object net.WebClient).DownloadString("https://git.io/JWdh6") | iex 22 | -------------------------------------------------------------------------------- /grammars/muse.cson: -------------------------------------------------------------------------------- 1 | name: "Muse" 2 | scopeName: "text.muse" 3 | fileTypes: ["muse"] 4 | patterns: [{ 5 | # Skip blank lines 6 | name: "meta.blank-lines.muse" 7 | begin: "\\A\\s*$" 8 | end: "(?=^\\s*\\S)" 9 | },{ 10 | # Prologue (directive lines) 11 | name: "meta.prologue.muse" 12 | begin: "^(?=#\\w+)" 13 | end: "^(?=\\s*$)" 14 | patterns: [include: "#directives"] 15 | },{ 16 | # Remainder of document 17 | name: "meta.document.muse" 18 | begin: "^(?=[^\\s#]|\\s+\\S)" 19 | end: "(?=A)B" 20 | patterns: [include: "#main"] 21 | }] 22 | firstLineMatch: """(?x) 23 | 24 | # Emacs modeline 25 | -\\*-(?i:[ \\t]*(?=[^:;\\s]+[ \\t]*-\\*-)|(?:.*?[ \\t;]|(?<=-\\*-))[ \\t]*mode[ \\t]*:[ \\t]*) 26 | (?i:muse) 27 | (?=[ \\t;]|(?]?[0-9]+|m)?|[ \\t]ex)(?=:(?=[ \\t]*set?[ \\t][^\\r\\n:]+:)|:(?![ \\t]*set?[ \\t])) 33 | (?:(?:[ \\t]*:[ \\t]*|[ \\t])\\w*(?:[ \\t]*=(?:[^\\\\\\s]|\\\\.)*)?)*[ \\t:] 34 | (?:filetype|ft|syntax)[ \\t]*= 35 | (?i:muse) 36 | (?=$|\\s|:) 37 | """ 38 | 39 | repository: 40 | main: 41 | patterns: [ 42 | {include: "#comment"} 43 | {include: "#heading"} 44 | {include: "#pageBreak"} 45 | {include: "#divider"} 46 | {include: "#anchorLine"} 47 | {include: "#term"} 48 | {include: "#list"} 49 | {include: "#verse"} 50 | {include: "#table"} 51 | {include: "#quote"} 52 | {include: "#footnote"} 53 | {include: "#inline"} 54 | {include: "#alignCentre"} 55 | {include: "#alignRight"} 56 | {include: "#alignLeft"} 57 | ] 58 | 59 | 60 | # Muse's equivalent of 61 | anchor: 62 | match: "(?:\\G|^)\\s*((#)[a-zA-Z][-a-zA-Z0-9]*)" 63 | captures: 64 | 1: name: "keyword.control.anchor.muse" 65 | 2: name: "punctuation.definition.anchor.muse" 66 | 67 | # A named anchor occupying a line by itself 68 | anchorLine: 69 | match: "^\\s*((#)[a-zA-Z][-a-zA-Z0-9]*)\\s*$" 70 | captures: 71 | 1: name: "keyword.control.anchor.muse" 72 | 2: name: "punctuation.definition.anchor.muse" 73 | 74 | 75 | # Left-aligned (ordinary) paragraph 76 | alignLeft: 77 | name: "meta.paragraph.align.left.muse" 78 | begin: "^\\s?(?=\\S)" 79 | end: "(?=^>\\s|^\\s*$|^\\s{2,}\\S|^\\s(?:-|(?:\\d+|[a-z]+|[A-Z]+)\\.\\s))" 80 | patterns: [ 81 | {include: "#anchor"} 82 | {include: "#inline"} 83 | ] 84 | 85 | 86 | # Centred paragraph 87 | alignCentre: 88 | name: "meta.paragraph.align.center.muse" 89 | begin: "^(\\s{6,19})(?=\\S)" 90 | end: "^(?!\\1|\\s*$)" 91 | patterns: [ 92 | {include: "#anchor"} 93 | {include: "#inline"} 94 | ] 95 | 96 | 97 | # Right-aligned paragraph 98 | alignRight: 99 | name: "meta.paragraph.align.right.muse" 100 | begin: "^(\\s{20,})(?=\\S)" 101 | end: "^(?!\\1|\\s*$)" 102 | patterns: [ 103 | {include: "#anchor"} 104 | {include: "#inline"} 105 | ] 106 | 107 | 108 | # Comment line 109 | comment: 110 | name: "comment.line.semicolon.muse" 111 | begin: "^(;)\\s" 112 | end: "(?=$)" 113 | beginCaptures: 114 | 1: name: "punctuation.definition.comment.begin.muse" 115 | 116 | 117 | # Metadata declared in document “prologue” 118 | directives: 119 | name: "meta.directive.$3.muse" 120 | begin: "^((#)([a-zA-Z]+))" 121 | end: "(?!\\G)(?=^(?:#|\\s*$))" 122 | beginCaptures: 123 | 1: name: "variable.assignment.directive.muse" 124 | 2: name: "punctuation.definition.directive.muse" 125 | contentName: "entity.other.$3.muse" 126 | patterns: [{ 127 | match: "\\G(?<=#pubdate|#date)\\s+(\\d{4}(?:-\\d{2}-\\d{2})?)(?=\\s|$)" 128 | captures: 129 | 1: name: "constant.other.date.muse" 130 | }, include: "#link"] 131 | 132 | 133 | # Horizontal divider 134 | divider: 135 | match: "^\\s*(-{4,})\\s*$" 136 | captures: 137 | 1: name: "constant.character.horizontal.line.muse" 138 | 139 | 140 | # Bold and/or italic text 141 | emphasis: 142 | patterns: [{ 143 | # ***Bold italic*** 144 | name: "markup.bold.italic.strong.emphasis.muse" 145 | begin: "(?<=\\W|^)(\\*{3})(?=\\S)" 146 | end: "(?<=\\S)\\1(?!\\*+\\w)(?=\\W|$)|(?=^[ \\t]*$)" 147 | beginCaptures: 1: name: "punctuation.definition.emphasis.begin.muse" 148 | endCaptures: 0: name: "punctuation.definition.emphasis.end.muse" 149 | patterns: [include: "#inlineInnards"] 150 | },{ 151 | # **Bold** 152 | name: "markup.bold.strong.emphasis.muse" 153 | begin: "(?<=\\W|^)(\\*{2})(?=\\S)" 154 | end: "(?<=\\S)\\1(?!\\*+\\w)(?=\\W|$)|(?=^[ \\t]*$)" 155 | beginCaptures: 1: name: "punctuation.definition.emphasis.begin.muse" 156 | endCaptures: 0: name: "punctuation.definition.emphasis.end.muse" 157 | patterns: [include: "#inlineInnards"] 158 | },{ 159 | # *Italic* 160 | name: "markup.italic.emphasis.muse" 161 | begin: "(?<=\\W|^)\\*(?=\\S)" 162 | end: "(?<=\\S)\\*(?!\\*+\\w)(?=\\W|$)|(?=^[ \\t]*$)" 163 | beginCaptures: 0: name: "punctuation.definition.emphasis.begin.muse" 164 | endCaptures: 0: name: "punctuation.definition.emphasis.end.muse" 165 | patterns: [include: "#inlineInnards"] 166 | }] 167 | 168 | 169 | # {{{ … }}} 170 | example: 171 | name: "meta.example.muse" 172 | begin: "{{{" 173 | end: "}}}" 174 | beginCaptures: 0: name: "keyword.operator.example.begin.muse" 175 | endCaptures: 0: name: "keyword.operator.example.end.muse" 176 | contentName: "markup.raw.code.muse" 177 | 178 | 179 | # Footnote references [1] 180 | footnoteReference: 181 | patterns: [{ 182 | # Primary footnote: [1] 183 | name: "entity.footnote.$2.primary.muse" 184 | match: "(\\[)(\\d+)(\\])" 185 | captures: 186 | 1: name: "punctuation.definition.footnote.begin.muse" 187 | 3: name: "punctuation.definition.footnote.end.muse" 188 | },{ 189 | # Secondary footnote: {2} 190 | name: "entity.footnote.$2.secondary.muse" 191 | match: "(\\{)(\\d+)(\\})" 192 | captures: 193 | 1: name: "punctuation.definition.footnote.begin.muse" 194 | 3: name: "punctuation.definition.footnote.end.muse" 195 | }] 196 | 197 | # Actual footnote definition 198 | # 199 | # Known limitation: there's no feasible way of suppressing quote 200 | # highlighting immediately after an insufficiently indented line: 201 | # 202 | # [1] Footnote 203 | # Footnote 204 | # Normal 205 | # Quoted 206 | footnote: 207 | patterns: [{ 208 | # Indexes 0-9 209 | name: "meta.footnote.muse" 210 | begin: "^(\\[\\d\\]|\\{\\d\\})(\\s+)(?=\\S)" 211 | end: "^(?!\\s{3}\\2)(?:\\s*$|\\s*?(?=\\s\\S))" 212 | contentName: "markup.list.footnote.muse" 213 | beginCaptures: 214 | 1: patterns: [include: "#footnoteReference"] 215 | 2: name: "punctuation.whitespace.separator.muse" 216 | patterns: [include: "#inline"] 217 | },{ 218 | # Indexes: 10-99 219 | name: "meta.footnote.muse" 220 | begin: "^(\\[\\d{2}\\]|\\{\\d{2}\\})(\\s+)(?=\\S)" 221 | end: "^(?!\\s{4}\\2)(?:\\s*$|\\s*?(?=\\s\\S))" 222 | contentName: "markup.list.footnote.muse" 223 | beginCaptures: 224 | 1: patterns: [include: "#footnoteReference"] 225 | 2: name: "punctuation.whitespace.separator.muse" 226 | patterns: [include: "#inline"] 227 | },{ 228 | # Indexes: 100-999 229 | name: "meta.footnote.muse" 230 | begin: "^(\\[\\d{3}\\]|\\{\\d{3}\\})(\\s+)(?=\\S)" 231 | end: "^(?!\\s{5}\\2)(?:\\s*$|\\s*?(?=\\s\\S))" 232 | contentName: "markup.list.footnote.muse" 233 | beginCaptures: 234 | 1: patterns: [include: "#footnoteReference"] 235 | 2: name: "punctuation.whitespace.separator.muse" 236 | patterns: [include: "#inline"] 237 | }] 238 | 239 | 240 | # Bulleted headings 241 | heading: 242 | match: "^(\\*{1,5})( )(.*)" 243 | captures: 244 | 1: name: "keyword.operator.heading.bullet.muse" 245 | 2: name: "punctuation.whitespace.separator.muse" 246 | 3: name: "markup.heading.muse" 247 | 248 | 249 | # Stuff that's safe to nest 250 | inline: 251 | patterns: [ 252 | {include: "#tags"} 253 | {include: "#example"} 254 | {include: "#emphasis"} 255 | {include: "#literal"} 256 | {include: "#link"} 257 | {include: "#footnoteReference"} 258 | {include: "#nbsp"} 259 | {include: "#underline"} 260 | ] 261 | 262 | # Stuff matched inside an span of inline markup 263 | inlineInnards: 264 | patterns: [{ 265 | # Swallow asterisks embedded between word characters. 266 | # See: Alhadis/language-emacs-lisp#5, jgm/pandoc#5821 267 | match: "(?:(?=\\G|^)|(?<=[\\w*]))\\*+(?=\\w)" 268 | 269 | }, include: "#inline"] 270 | 271 | 272 | # Hyperlink 273 | link: 274 | name: "meta.link.muse" 275 | begin: "(\\[)(?=\\[.*?\\]\\])" 276 | end: "\\]" 277 | beginCaptures: 1: name: "punctuation.definition.link.begin.muse" 278 | endCaptures: 0: name: "punctuation.definition.link.end.muse" 279 | patterns: [{ 280 | name: "meta.link.target.muse" 281 | begin: "\\G(\\[)" 282 | end: "\\]" 283 | beginCaptures: 1: name: "punctuation.definition.link.target.begin.muse" 284 | endCaptures: 0: name: "punctuation.definition.link.target.end.muse" 285 | patterns: [{ 286 | match: "\\G\\s*([^\\s\\]]+)" 287 | captures: 288 | 1: name: "constant.other.reference.link.muse" 289 | },{ 290 | match: "(?<=\\s)(?:([\\d.]+)([rlf])?|([rlf]))" 291 | captures: 292 | 1: name: "constant.numeric.width.muse" 293 | 2: name: "storage.modifier.align.muse" 294 | 3: name: "storage.modifier.align.muse" 295 | }] 296 | },{ 297 | name: "meta.link.label.muse" 298 | begin: "(?<=\\])(\\[)" 299 | end: "\\]" 300 | beginCaptures: 1: name: "punctuation.definition.link.label.begin.muse" 301 | endCaptures: 0: name: "punctuation.definition.link.label.end.muse" 302 | contentName: "entity.name.link.label.muse" 303 | patterns: [include: "#inline"] 304 | }] 305 | 306 | 307 | # Bulleted or numbered list 308 | list: 309 | name: "markup.list.muse" 310 | begin: "^(\\s+)(?=-|(?:\\d+|[a-z]+|[A-Z]+)\\.)" 311 | end: "(?=^(?!\\1)(?!\\s*$))|(?=^\\S)" 312 | beginCaptures: 313 | 1: name: "punctuation.whitespace.leading.muse" 314 | patterns: [{ 315 | # Needed for line-continuation 316 | begin: "(?<=\\S)\\s*$\\s*" 317 | end: "(?=^\\s*$|^(?=\\S))" 318 | patterns: [include: "#listInnards"] 319 | }, include: "#listInnards"] 320 | 321 | # Stuff matched inside list entries 322 | listInnards: 323 | patterns: [ 324 | {include: "#listMarker"} 325 | {include: "#term"} 326 | {include: "#inline"} 327 | ] 328 | 329 | # Bullets or numbers prefixing a list entry 330 | listMarker: 331 | patterns: [{ 332 | match: "(?:\\G|^\\s+)(-)\\s" 333 | captures: 334 | 1: name: "keyword.operator.list.unnumbered.marker.muse" 335 | },{ 336 | match: "(?:\\G|^\\s+)((?:\\d+|[a-z]+|[A-Z]+)\\.)\\s" 337 | captures: 338 | 1: name: "keyword.operator.list.numbered.marker.muse" 339 | }] 340 | 341 | 342 | 343 | # =literal= 344 | literal: 345 | name: "markup.raw.literal.muse" 346 | begin: "(?<=\\W|^)=(?=\\S)" 347 | end: "(?!\\G)(?<=\\S)=(?=\\W|$)|(?=^[ \\t]*$)" 348 | beginCaptures: 0: name: "punctuation.definition.literal.begin.muse" 349 | endCaptures: 0: name: "punctuation.definition.literal.end.muse" 350 | 351 | 352 | # Non-breaking space: `~~` 353 | nbsp: 354 | name: "constant.character.non-breaking-space.muse" 355 | match: "~~" 356 | 357 | 358 | # `* * * * *` 359 | pageBreak: 360 | match: "^(\\s{5})((?:\\s+\\*){5})" 361 | captures: 362 | 1: name: "punctuation.whitespace.separator.muse" 363 | 2: name: "meta.separator.page-break.muse" 364 | 365 | 366 | # Indented block-quote 367 | quote: 368 | name: "markup.quote.paragraph.muse" 369 | begin: "^(\\s{2,5})(?=\\S)" 370 | end: "^(?!\\1|\\s*$)" 371 | patterns: [ 372 | {include: "#anchor"} 373 | {include: "#inline"} 374 | ] 375 | 376 | 377 | # Table blocks 378 | table: 379 | name: "markup.table.muse" 380 | begin: "^(?=\\s+(?:\\|\\+.*?\\+\\||\\S.*?\\s\\|{1,3}\\s+\\S))" 381 | end: "(?=\\s*$)" 382 | patterns: [{ 383 | name: "markup.table.caption.muse" 384 | match: "^\\s+(\\|\\+)(.*)(\\+\\|)" 385 | captures: 386 | 1: name: "keyword.operator.caption.begin.muse" 387 | 2: name: "constant.other.caption.muse" 388 | 3: name: "keyword.operator.caption.end.muse" 389 | },{ 390 | name: "markup.table.footer.muse" 391 | match: "^\\s+(\\S.*?\\s\\|\\|\\|\\s.*)\\s*$" 392 | captures: 393 | 0: patterns: [{ 394 | match: "\\s(\\|\\|\\|)\\s" 395 | captures: 1: name: "keyword.operator.table.separator.muse" 396 | },{ 397 | match: "(?:[^|\\s]|\\s(?!\\|))+" 398 | name: "constant.other.table.footer.muse" 399 | captures: 0: patterns: [include: "#inline"] 400 | }] 401 | },{ 402 | name: "markup.table.header.muse" 403 | match: "^\\s+(\\S.*?\\s\\|\\|\\s.*)\\s*$" 404 | captures: 405 | 0: patterns: [{ 406 | match: "\\s(\\|\\|)\\s" 407 | captures: 1: name: "keyword.operator.table.separator.muse" 408 | },{ 409 | match: "(?:[^|\\s]|\\s(?!\\|))+" 410 | name: "markup.heading.table.muse" 411 | captures: 0: patterns: [include: "#inline"] 412 | }] 413 | },{ 414 | name: "markup.table.body.muse" 415 | match: "^\\s+(\\S.*?\\s\\|\\s.*)\\s*$" 416 | captures: 417 | 0: patterns: [{ 418 | match: "\\s(\\|)\\s" 419 | captures: 1: name: "keyword.operator.table.separator.muse" 420 | },{ 421 | match: "(?:[^|\\s]|\\s(?!\\|))+" 422 | name: "constant.other.table.cell.muse" 423 | captures: 0: patterns: [include: "#inline"] 424 | }] 425 | }] 426 | 427 | 428 | 429 | # HTML-like tags 430 | tags: 431 | patterns: [{ 432 | # Line-break 433 | name: "meta.tag.br.muse" 434 | match: "(<)br(>)" 435 | captures: 436 | 0: name: "entity.name.tag.br.muse" 437 | 1: name: "punctuation.definition.tag.begin.muse" 438 | 3: name: "punctuation.definition.tag.end.muse" 439 | },{ 440 | # Text alignment 441 | name: "meta.tag.$2.muse" 442 | begin: "(<)(center|right)(>)" 443 | end: "()" 444 | beginCaptures: 445 | 0: name: "entity.name.tag.$2.muse" 446 | 1: name: "punctuation.definition.tag.begin.muse" 447 | 3: name: "punctuation.definition.tag.end.muse" 448 | endCaptures: 449 | 0: name: "entity.name.tag.$2.muse" 450 | 1: name: "punctuation.definition.tag.begin.muse" 451 | 3: name: "punctuation.definition.tag.end.muse" 452 | contentName: "meta.paragraph.align.$2.muse" 453 | patterns: [include: "#inline"] 454 | },{ 455 | # Monospaced/verbatim content 456 | name: "meta.tag.$2.muse" 457 | begin: "(<)(code|example|verbatim)(>)" 458 | end: "()" 459 | beginCaptures: 460 | 0: name: "entity.name.tag.$2.muse" 461 | 1: name: "punctuation.definition.tag.begin.muse" 462 | 3: name: "punctuation.definition.tag.end.muse" 463 | endCaptures: 464 | 0: name: "entity.name.tag.$2.muse" 465 | 1: name: "punctuation.definition.tag.begin.muse" 466 | 3: name: "punctuation.definition.tag.end.muse" 467 | contentName: "markup.raw.code.muse" 468 | },{ 469 | # Comment 470 | name: "meta.tag.comment-block.muse" 471 | begin: "(<)comment(>)" 472 | end: "()" 473 | beginCaptures: 474 | 0: name: "entity.name.tag.comments.muse" 475 | 1: name: "punctuation.definition.tag.begin.muse" 476 | 2: name: "punctuation.definition.tag.end.muse" 477 | endCaptures: 478 | 0: name: "entity.name.tag.comments.muse" 479 | 1: name: "punctuation.definition.tag.begin.muse" 480 | 2: name: "punctuation.definition.tag.end.muse" 481 | contentName: "comment.block.muse" 482 | },{ 483 | # Emphasised text 484 | name: "meta.tag.em.muse" 485 | begin: "(<)em(>)" 486 | end: "()" 487 | beginCaptures: 488 | 0: name: "entity.name.tag.em.muse" 489 | 1: name: "punctuation.definition.tag.begin.muse" 490 | 2: name: "punctuation.definition.tag.end.muse" 491 | endCaptures: 492 | 0: name: "entity.name.tag.em.muse" 493 | 1: name: "punctuation.definition.tag.begin.muse" 494 | 2: name: "punctuation.definition.tag.end.muse" 495 | contentName: "markup.italic.emphasis.muse" 496 | patterns: [include: "#inline"] 497 | },{ 498 | # Strongly-emphasised text 499 | name: "meta.tag.strong.muse" 500 | begin: "(<)strong(>)" 501 | end: "()" 502 | beginCaptures: 503 | 0: name: "entity.name.tag.strong.muse" 504 | 1: name: "punctuation.definition.tag.begin.muse" 505 | 2: name: "punctuation.definition.tag.end.muse" 506 | endCaptures: 507 | 0: name: "entity.name.tag.strong.muse" 508 | 1: name: "punctuation.definition.tag.begin.muse" 509 | 2: name: "punctuation.definition.tag.end.muse" 510 | contentName: "markup.bold.strong.emphasis.muse" 511 | patterns: [include: "#inline"] 512 | },{ 513 | # Deleted content 514 | name: "meta.tag.del.muse" 515 | begin: "(<)del(>)" 516 | end: "()" 517 | beginCaptures: 518 | 0: name: "entity.name.tag.del.muse" 519 | 1: name: "punctuation.definition.tag.begin.muse" 520 | 2: name: "punctuation.definition.tag.end.muse" 521 | endCaptures: 522 | 0: name: "entity.name.tag.del.muse" 523 | 1: name: "punctuation.definition.tag.begin.muse" 524 | 2: name: "punctuation.definition.tag.end.muse" 525 | contentName: "markup.deleted.muse" 526 | patterns: [include: "#inline"] 527 | },{ 528 | # Superscript 529 | name: "meta.tag.sup.muse" 530 | begin: "(<)sup(>)" 531 | end: "()" 532 | beginCaptures: 533 | 0: name: "entity.name.tag.sup.muse" 534 | 1: name: "punctuation.definition.tag.begin.muse" 535 | 2: name: "punctuation.definition.tag.end.muse" 536 | endCaptures: 537 | 0: name: "entity.name.tag.sup.muse" 538 | 1: name: "punctuation.definition.tag.begin.muse" 539 | 2: name: "punctuation.definition.tag.end.muse" 540 | contentName: "markup.superscript.muse" 541 | patterns: [include: "#inline"] 542 | },{ 543 | # Subscript 544 | name: "meta.tag.sub.muse" 545 | begin: "(<)sub(>)" 546 | end: "()" 547 | beginCaptures: 548 | 0: name: "entity.name.tag.sub.muse" 549 | 1: name: "punctuation.definition.tag.begin.muse" 550 | 2: name: "punctuation.definition.tag.end.muse" 551 | endCaptures: 552 | 0: name: "entity.name.tag.sub.muse" 553 | 1: name: "punctuation.definition.tag.begin.muse" 554 | 2: name: "punctuation.definition.tag.end.muse" 555 | contentName: "markup.subscript.muse" 556 | patterns: [include: "#inline"] 557 | },{ 558 | # Verse 559 | name: "meta.tag.verse.muse" 560 | begin: "^\\s*((<)verse(>))" 561 | end: "()" 562 | beginCaptures: 563 | 1: name: "entity.name.tag.verse.muse" 564 | 2: name: "punctuation.definition.tag.begin.muse" 565 | 3: name: "punctuation.definition.tag.end.muse" 566 | endCaptures: 567 | 0: name: "entity.name.tag.verse.muse" 568 | 1: name: "punctuation.definition.tag.begin.muse" 569 | 2: name: "punctuation.definition.tag.end.muse" 570 | contentName: "markup.quote.verse.muse" 571 | patterns: [include: "#inline"] 572 | },{ 573 | # Citations 574 | name: "meta.tag.biblio.muse" 575 | begin: "^\\s*((<)biblio(>))" 576 | end: "()" 577 | beginCaptures: 578 | 1: name: "entity.name.tag.biblio.muse" 579 | 2: name: "punctuation.definition.tag.begin.muse" 580 | 3: name: "punctuation.definition.tag.end.muse" 581 | endCaptures: 582 | 0: name: "entity.name.tag.biblio.muse" 583 | 1: name: "punctuation.definition.tag.begin.muse" 584 | 2: name: "punctuation.definition.tag.end.muse" 585 | contentName: "meta.citation.muse" 586 | patterns: [include: "#inline"] 587 | },{ 588 | # Theatrical scripts 589 | name: "meta.tag.play.muse" 590 | begin: "^\\s*((<)play(>))" 591 | end: "()" 592 | beginCaptures: 593 | 1: name: "entity.name.tag.play.muse" 594 | 2: name: "punctuation.definition.tag.begin.muse" 595 | 3: name: "punctuation.definition.tag.end.muse" 596 | endCaptures: 597 | 0: name: "entity.name.tag.play.muse" 598 | 1: name: "punctuation.definition.tag.begin.muse" 599 | 2: name: "punctuation.definition.tag.end.muse" 600 | contentName: "meta.play.muse" 601 | patterns: [include: "#inline"] 602 | },{ 603 | # Quotes 604 | name: "meta.tag.quote.muse" 605 | begin: "^\\s*((<)quote(>))" 606 | end: "()" 607 | beginCaptures: 608 | 1: name: "entity.name.tag.quote.muse" 609 | 2: name: "punctuation.definition.tag.begin.muse" 610 | 3: name: "punctuation.definition.tag.end.muse" 611 | endCaptures: 612 | 0: name: "entity.name.tag.quote.muse" 613 | 1: name: "punctuation.definition.tag.begin.muse" 614 | 2: name: "punctuation.definition.tag.end.muse" 615 | contentName: "markup.quote.block.muse" 616 | patterns: [include: "#inline"] 617 | }, include: "#unprocessed"] 618 | 619 | 620 | # [term] :: [description] 621 | term: 622 | match: "^\\s+(\\S.*?)\\s+(::)\\s+" 623 | captures: 624 | 1: name: "entity.name.term.muse" 625 | 2: name: "keyword.operator.key-value.separator.muse" 626 | 627 | 628 | # Underlined text (not supported in AmuseWiki) 629 | underline: 630 | name: "constant.other.reference.link.muse" 631 | begin: "(?<=\\W|^)_(?=[^\\s_])" 632 | end: "(?<=[^\\s_])_(?=\\W|$)|(?=^[ \\t]*$)" 633 | beginCaptures: 0: name: "punctuation.definition.emphasis.begin.muse" 634 | endCaptures: 0: name: "punctuation.definition.emphasis.end.muse" 635 | patterns: [include: "#inline"] 636 | 637 | 638 | # blocks 639 | unprocessed: 640 | patterns: [ 641 | {include: "#unprocessedLatex"} 642 | {include: "#unprocessedHTML"} 643 | {include: "#unprocessedXML"} 644 | {include: "#unprocessedTexinfo"} 645 | {include: "#unprocessedDefault"} 646 | ] 647 | 648 | 649 | # Unprocessed block fallback 650 | unprocessedDefault: 651 | name: "meta.unprocessed.$8-output.muse" 652 | begin: "^\\s*((<)literal(?:\\s+((style)\\s*(=)\\s*((\"|'|\\b)([^>\\s]+)(\\7))))?\\s*(>))" 653 | end: "()" 654 | beginCaptures: 655 | 0: name: "meta.tag.literal.muse" 656 | 1: name: "entity.name.tag.literal.muse" 657 | 2: name: "punctuation.definition.tag.begin.muse" 658 | 3: name: "meta.attribute-with-value.style.muse" 659 | 4: name: "entity.other.attribute-name.style.muse" 660 | 5: name: "punctuation.separator.key-value.muse" 661 | 6: name: "string.quoted.muse" 662 | 7: name: "punctuation.definition.string.begin.muse" 663 | 9: name: "punctuation.definition.string.end.muse" 664 | 10: name: "punctuation.definition.tag.end.muse" 665 | endCaptures: 666 | 0: name: "entity.name.tag.literal.muse" 667 | 1: name: "punctuation.definition.tag.begin.muse" 668 | 2: name: "punctuation.definition.tag.end.muse" 669 | contentName: "markup.raw.code.muse" 670 | 671 | 672 | # Unprocessed source: HTML 673 | unprocessedHTML: 674 | name: "meta.unprocessed.$8-output.muse" 675 | begin: """(?x) ^\\s* ( 676 | (<) literal \\s+ 677 | ( 678 | (style) \\s* (=) \\s* 679 | ( 680 | ("|'|\\b) 681 | ( blosxom-html 682 | | blosxom-xhtml 683 | | journal-html 684 | | html 685 | | xhtml 686 | ) (\\7) 687 | ) 688 | ) \\s* (>) 689 | )""" 690 | end: "()" 691 | beginCaptures: 692 | 0: name: "meta.tag.literal.muse" 693 | 1: name: "entity.name.tag.literal.muse" 694 | 2: name: "punctuation.definition.tag.begin.muse" 695 | 3: name: "meta.attribute-with-value.style.muse" 696 | 4: name: "entity.other.attribute-name.style.muse" 697 | 5: name: "punctuation.separator.key-value.muse" 698 | 6: name: "string.quoted.muse" 699 | 7: name: "punctuation.definition.string.begin.muse" 700 | 9: name: "punctuation.definition.string.end.muse" 701 | 10: name: "punctuation.definition.tag.end.muse" 702 | endCaptures: 703 | 0: name: "entity.name.tag.literal.muse" 704 | 1: name: "punctuation.definition.tag.begin.muse" 705 | 2: name: "punctuation.definition.tag.end.muse" 706 | contentName: "text.embedded.html.basic" 707 | patterns: [include: "text.html.basic"] 708 | 709 | 710 | # Unprocessed source: LaTeX 711 | unprocessedLatex: 712 | name: "meta.unprocessed.$8-output.muse" 713 | begin: """(?x) ^\\s* ( 714 | (<) literal \\s+ 715 | ( 716 | (style) \\s* (=) \\s* 717 | ( 718 | ("|'|\\b) 719 | ( book-latex 720 | | book-pdf 721 | | chapbook-latex 722 | | chapbook-pdf 723 | | context-pdf 724 | | context-slides-pdf 725 | | context-slides 726 | | context 727 | | journal-book-latex 728 | | journal-book-pdf 729 | | journal-latex 730 | | journal-pdf 731 | | journal-xhtml 732 | | latexcjk 733 | | latex 734 | | lecture-notes-pdf 735 | | lecture-notes 736 | | pdfcjk 737 | | pdf 738 | | poem-latex 739 | | poem-pdf 740 | | slides-pdf 741 | | slides 742 | ) (\\7) 743 | ) 744 | ) \\s* (>) 745 | )""" 746 | end: "()" 747 | beginCaptures: 748 | 0: name: "meta.tag.literal.muse" 749 | 1: name: "entity.name.tag.literal.muse" 750 | 2: name: "punctuation.definition.tag.begin.muse" 751 | 3: name: "meta.attribute-with-value.style.muse" 752 | 4: name: "entity.other.attribute-name.style.muse" 753 | 5: name: "punctuation.separator.key-value.muse" 754 | 6: name: "string.quoted.muse" 755 | 7: name: "punctuation.definition.string.begin.muse" 756 | 9: name: "punctuation.definition.string.end.muse" 757 | 10: name: "punctuation.definition.tag.end.muse" 758 | endCaptures: 759 | 0: name: "entity.name.tag.literal.muse" 760 | 1: name: "punctuation.definition.tag.begin.muse" 761 | 2: name: "punctuation.definition.tag.end.muse" 762 | contentName: "text.embedded.latex" 763 | patterns: [include: "text.tex.latex"] 764 | 765 | 766 | # Unprocessed source: Texinfo 767 | unprocessedTexinfo: 768 | name: "meta.unprocessed.$8-output.muse" 769 | begin: """(?x) ^\\s* ( 770 | (<) literal \\s+ 771 | ( 772 | (style) \\s* (=) \\s* 773 | ( 774 | ("|'|\\b) 775 | ( info-pdf 776 | | info 777 | | texi 778 | ) (\\7) 779 | ) 780 | ) \\s* (>) 781 | )""" 782 | end: "()" 783 | beginCaptures: 784 | 0: name: "meta.tag.literal.muse" 785 | 1: name: "entity.name.tag.literal.muse" 786 | 2: name: "punctuation.definition.tag.begin.muse" 787 | 3: name: "meta.attribute-with-value.style.muse" 788 | 4: name: "entity.other.attribute-name.style.muse" 789 | 5: name: "punctuation.separator.key-value.muse" 790 | 6: name: "string.quoted.muse" 791 | 7: name: "punctuation.definition.string.begin.muse" 792 | 9: name: "punctuation.definition.string.end.muse" 793 | 10: name: "punctuation.definition.tag.end.muse" 794 | endCaptures: 795 | 0: name: "entity.name.tag.literal.muse" 796 | 1: name: "punctuation.definition.tag.begin.muse" 797 | 2: name: "punctuation.definition.tag.end.muse" 798 | contentName: "text.embedded.texinfo" 799 | patterns: [include: "text.texinfo"] 800 | 801 | 802 | # Unprocessed source: XML 803 | unprocessedXML: 804 | name: "meta.unprocessed.$8-output.muse" 805 | begin: """(?x) ^\\s* ( 806 | (<) literal \\s+ 807 | ( 808 | (style) \\s* (=) \\s* 809 | ( 810 | ("|'|\\b) 811 | ( docbook 812 | | journal-rdf 813 | | journal-rss-entry 814 | | journal-rss 815 | | xml 816 | ) (\\7) 817 | ) 818 | ) \\s* (>) 819 | )""" 820 | end: "()" 821 | beginCaptures: 822 | 0: name: "meta.tag.literal.muse" 823 | 1: name: "entity.name.tag.literal.muse" 824 | 2: name: "punctuation.definition.tag.begin.muse" 825 | 3: name: "meta.attribute-with-value.style.muse" 826 | 4: name: "entity.other.attribute-name.style.muse" 827 | 5: name: "punctuation.separator.key-value.muse" 828 | 6: name: "string.quoted.muse" 829 | 7: name: "punctuation.definition.string.begin.muse" 830 | 9: name: "punctuation.definition.string.end.muse" 831 | 10: name: "punctuation.definition.tag.end.muse" 832 | endCaptures: 833 | 0: name: "entity.name.tag.literal.muse" 834 | 1: name: "punctuation.definition.tag.begin.muse" 835 | 2: name: "punctuation.definition.tag.end.muse" 836 | contentName: "text.embedded.xml" 837 | patterns: [include: "text.xml"] 838 | 839 | 840 | # Poetic stanza 841 | verse: 842 | name: "markup.quote.verse.muse" 843 | begin: "^(\\s*)(>)(\\s)" 844 | end: "^(?!\\1\\2\\3)" 845 | beginCaptures: 846 | 1: name: "punctuation.whitespace.leading.muse" 847 | 2: name: "keyword.operator.verse-line.muse" 848 | 3: name: "punctuation.whitespace.separator.muse" 849 | patterns: [{ 850 | match: "^(\\s*)(>)(\\s)" 851 | captures: 852 | 1: name: "punctuation.whitespace.leading.muse" 853 | 2: name: "keyword.operator.verse-line.muse" 854 | 3: name: "punctuation.whitespace.separator.muse" 855 | }, include: "#inline"] 856 | -------------------------------------------------------------------------------- /grammars/yasnippet.cson: -------------------------------------------------------------------------------- 1 | name: "YASnippet" 2 | scopeName: "source.yasnippet" 3 | fileTypes: [ 4 | "yasnippet" 5 | "yas" 6 | ] 7 | firstLineMatch: """(?x) 8 | # Emacs modeline 9 | -\\*-(?i:[ \\t]*(?=[^:;\\s]+[ \\t]*-\\*-)|(?:.*?[ \\t;]|(?<=-\\*-))[ \\t]*mode[ \\t]*:[ \\t]*) 10 | (?i:yasnippet|snippet) 11 | (?=[ \\t;]|(? 107 | match: "([^\\s<>,](?:[^\\s<>,]|\\s[^<>,])*+)(?:\\s+((<)([^@>\\s]+@[^<>@\\s]+)(>)))?" 108 | captures: 109 | 1: name: "entity.name.author.yasnippet" 110 | 2: name: "meta.email-address.yasnippet" 111 | 3: name: "punctuation.definition.bracket.angle.begin.yasnippet" 112 | 4: name: "constant.other.reference.link.underline.email.yasnippet" 113 | 5: name: "punctuation.definition.bracket.angle.end.yasnippet" 114 | },{ 115 | # 116 | name: "meta.email-address.yasnippet" 117 | match: "(<)([^@>\\s]+@[^<>@\\s]+)(>)" 118 | captures: 119 | 1: name: "punctuation.definition.bracket.angle.begin.yasnippet" 120 | 2: name: "constant.other.reference.link.underline.email.yasnippet" 121 | 3: name: "punctuation.definition.bracket.angle.end.yasnippet" 122 | },{ 123 | # E-mail separators 124 | name: "punctuation.separator.comma.yasnippet" 125 | match: "," 126 | }] 127 | },{ 128 | # Miscellaneous directives 129 | name: "meta.directive.other.yasnippet" 130 | match: "(?<=[\\s#])([^:\\s#]+)\\s*(:)(?:\\s*(\\S.*))?" 131 | captures: 132 | 1: name: "variable.assignment.custom.yasnippet" 133 | 2: name: "punctuation.separator.dictionary.key-value.colon.yasnippet" 134 | 3: name: "string.unquoted.yasnippet" 135 | }] 136 | 137 | 138 | body: 139 | name: "meta.snippet-body.yasnippet" 140 | begin: "^\\s*((#+)\\s*(--)\\s*$\\n?|(?=[^\\s#]))" 141 | end: "(?=A)B" 142 | beginCaptures: 143 | 1: name: "comment.line.number-sign.yasnippet" 144 | 2: name: "punctuation.definition.comment.number-sign.yasnippet" 145 | 3: name: "punctuation.terminator.double-dash.yasnippet" 146 | patterns: [ 147 | {include: "#tab-stops"} 148 | {include: "#indentation-marker"} 149 | {include: "#placeholder-fields"} 150 | {include: "#escaped-characters"} 151 | {include: "#embedded-lisp"} 152 | ] 153 | 154 | "tab-stops": 155 | name: "variable.positional.$2-nth.tab-stop.yasnippet" 156 | match: "(\\$)([0-9]+)" 157 | captures: 158 | 1: name: "punctuation.definition.variable.sigil.dollar-sign.yasnippet" 159 | 160 | "indentation-marker": 161 | name: "keyword.operator.indentation-marker.yasnippet" 162 | match: "(\\$)>" 163 | captures: 164 | 1: name: "punctuation.definition.variable.sigil.dollar-sign.yasnippet" 165 | 166 | # NOTE: This list should be kept in sync with `yas--escaped-characters` 167 | "escaped-characters": 168 | patterns: [{ 169 | # Escaped backslash 170 | name: "constant.character.escape.backslash.yasnippet" 171 | match: "(\\\\)\\\\" 172 | captures: 173 | 1: name: "punctuation.definition.escape.yasnippet" 174 | },{ 175 | # \$ 176 | name: "constant.character.escape.dollar-sign.yasnippet" 177 | match: "(\\\\)\\$" 178 | captures: 179 | 1: name: "punctuation.definition.escape.yasnippet" 180 | },{ 181 | # \` 182 | name: "constant.character.escape.backtick.yasnippet" 183 | match: "(\\\\)`" 184 | captures: 185 | 1: name: "punctuation.definition.escape.yasnippet" 186 | },{ 187 | # \' 188 | name: "constant.character.escape.quote.single.yasnippet" 189 | match: "(\\\\)'" 190 | captures: 191 | 1: name: "punctuation.definition.escape.yasnippet" 192 | },{ 193 | # \" 194 | name: "constant.character.escape.quote.double.yasnippet" 195 | match: '(\\\\)"' 196 | captures: 197 | 1: name: "punctuation.definition.escape.yasnippet" 198 | },{ 199 | # \{ \} 200 | name: "constant.character.escape.bracket.curly.brace.yasnippet" 201 | match: "(\\\\)[{}]" 202 | captures: 203 | 1: name: "punctuation.definition.escape.yasnippet" 204 | },{ 205 | # \( \) 206 | name: "constant.character.escape.bracket.round.parenthesis.yasnippet" 207 | match: "(\\\\)[\\(\\)]" 208 | captures: 209 | 1: name: "punctuation.definition.escape.yasnippet" 210 | }] 211 | 212 | "embedded-lisp": 213 | name: "string.interpolated.yasnippet" 214 | begin: "`" 215 | end: "`" 216 | contentName: "source.embedded.emacs.lisp" 217 | patterns: [include: "source.emacs.lisp"] 218 | beginCaptures: 0: name: "punctuation.section.begin.embedded.yasnippet" 219 | endCaptures: 0: name: "punctuation.section.end.embedded.yasnippet" 220 | 221 | 222 | "placeholder-fields": 223 | patterns: [ 224 | {include: "#numbered-placeholder"} 225 | {include: "#unnumbered-placeholder"} 226 | ] 227 | 228 | "numbered-placeholder": 229 | name: "meta.placeholder-field.numbered.$2-nth.yasnippet" 230 | begin: "(\\${)([0-9]+)(:)" 231 | end: "}" 232 | beginCaptures: 233 | 1: name: "punctuation.section.embedded.field.begin.yasnippet" 234 | 2: name: "constant.numeric.integer.int.decimal.yasnippet" 235 | 3: name: "punctuation.separator.colon.field.yasnippet" 236 | endCaptures: 237 | 0: name: "punctuation.section.embedded.field.end.yasnippet" 238 | contentName: "string.unquoted.default-text.yasnippet" 239 | patterns: [include: "#placeholder-innards"] 240 | 241 | "unnumbered-placeholder": 242 | name: "meta.placeholder-field.unnumbered.yasnippet" 243 | begin: "(\\${)(:)" 244 | end: "}" 245 | beginCaptures: 246 | 1: name: "punctuation.section.embedded.field.begin.yasnippet" 247 | 2: name: "punctuation.separator.colon.field.yasnippet" 248 | endCaptures: 249 | 0: name: "punctuation.section.embedded.field.end.yasnippet" 250 | contentName: "string.unquoted.default-text.yasnippet" 251 | patterns: [include: "#placeholder-innards"] 252 | 253 | "placeholder-innards": 254 | patterns: [ 255 | {include: "#escaped-characters"} 256 | {include: "#embedded-lisp"} 257 | {include: "#placeholder-fields"} 258 | 259 | name: "meta.transformation.yasnippet" 260 | begin: "\\${1,2}(?=\\()" 261 | end: "(?<=\\))" 262 | beginCaptures: 263 | 0: name: "keyword.operator.transformation.yasnippet" 264 | contentName: "source.embedded.emacs.lisp" 265 | patterns: [include: "source.emacs.lisp"] 266 | ] 267 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const {CompositeDisposable} = require("atom"); 4 | const childProcess = require("child_process"); 5 | const path = require("path"); 6 | 7 | 8 | /** 9 | * Singleton class which manages the package's lifecycle. 10 | * @hideconstructor 11 | * @class 12 | */ 13 | class EmacsLisp{ 14 | 15 | /** 16 | * Register the package's commands with Atom. 17 | * @internal 18 | */ 19 | activate(){ 20 | this.disposables = new CompositeDisposable(); 21 | this.disposables.add(atom.commands.add("atom-text-editor", { 22 | "language-emacs-lisp:run-selection": e => { 23 | const text = this.getSelection(); 24 | if(text && !/^\s+$/.test(text)) 25 | this.eval(text) 26 | .then(output => this.showOutput(output)) 27 | .catch(output => this.showOutput(output, true)); 28 | }, 29 | "language-emacs-lisp:run-file": e => { 30 | const ed = atom.workspace.getActiveTextEditor(); 31 | if(ed) this.runFile(ed.getPath()) 32 | .then(output => this.showOutput(output)) 33 | .catch(output => this.showOutput(output, true)); 34 | }, 35 | })); 36 | } 37 | 38 | 39 | /** 40 | * Free up memory when deactivating package. 41 | * @internal 42 | */ 43 | deactivate(){ 44 | if(null !== this.disposables) 45 | this.disposables.dispose(); 46 | this.disposables = null; 47 | } 48 | 49 | 50 | /** 51 | * Evaluate a string of Emacs Lisp code. 52 | * 53 | * @example eval("(+ 5 5)") -> "10" 54 | * @param {String} expr 55 | * @return {Promise} Resolves with collected output. 56 | */ 57 | eval(expr){ 58 | return new Promise((resolve, reject) => { 59 | expr = expr.replace(/\r(?=\n)/g, ""); 60 | if(!/^\s*\(message\s+".+?%.+?"\s(?:.|\n)+\)\s*$/.test(expr)) 61 | expr = `(message "%s" ${expr})`; 62 | const emacs = childProcess.spawn("emacs", ["--batch", "--eval", expr]); 63 | 64 | let output = ""; 65 | emacs.stderr.on("data", data => { 66 | if(data) output += data.toString(); 67 | }); 68 | 69 | emacs.on("close", code => { 70 | output = output.replace(/^\n+|\n+$/g, ""); 71 | code !== 0 72 | ? reject(output) 73 | : resolve(output); 74 | }) 75 | }); 76 | } 77 | 78 | 79 | /** 80 | * Run a Lisp file in Emacs. 81 | * 82 | * @example runFile("~/.emacs.d/lisp/script.el") 83 | * @param {String} file - Path to file 84 | * @return {Promise} Resolves with the script's output, if any. 85 | */ 86 | runFile(file){ 87 | return new Promise((resolve, reject) => { 88 | const emacs = childProcess.spawn("emacs", ["--script", file]); 89 | 90 | let output = ""; 91 | emacs.stderr.on("data", data => { 92 | if(data) output += data.toString(); 93 | }); 94 | 95 | emacs.on("close", code => { 96 | output = output.replace(/^\n+|\n+$/g, ""); 97 | code !== 0 98 | ? reject(output) 99 | : resolve(output); 100 | }) 101 | }); 102 | } 103 | 104 | 105 | /** 106 | * Show output in the notifications area. 107 | * 108 | * @param {String} text 109 | * @param {Boolean} error 110 | * @return {NotificationElement} 111 | * @internal 112 | */ 113 | showOutput(text, error = false){ 114 | const msg = "**Emacs:**"; 115 | const opt = {dismissable: true, detail: text}; 116 | const view = atom.views.getView(error 117 | ? atom.notifications.addError(msg, opt) 118 | : atom.notifications.addInfo(msg, opt)); 119 | 120 | // Select output when clicked to make copying easier 121 | if(view && view.element){ 122 | const output = view.element.querySelector(".content > .detail.item"); 123 | output && Object.assign(output.style, {userSelect: "all", cursor: "text"}); 124 | } 125 | return view; 126 | } 127 | 128 | 129 | /** 130 | * Retrieve an editor's currently-selected text. 131 | * 132 | * If nothing's selected, the scope enclosing the cursor's 133 | * current position is selected and returned instead. 134 | * 135 | * @param {TextEditor} ed - Defaults to current editor 136 | * @return {String} 137 | * @internal 138 | */ 139 | getSelection(ed){ 140 | ed = ed || atom.workspace.getActiveTextEditor(); 141 | if(!ed) return ""; 142 | let text = ed.getSelectedText(); 143 | 144 | // If the user hasn't made a selection, make one for 'em 145 | if(!text){ 146 | if(atom.packages.activePackages["bracket-matcher"]){ 147 | const command = "bracket-matcher:select-inside-brackets"; 148 | atom.commands.dispatch(ed.element, command); 149 | 150 | // Select containing brackets too 151 | const range = ed.getSelectedBufferRange(); 152 | --range.start.column; 153 | ++range.end.column; 154 | ed.setSelectedBufferRange(range); 155 | } 156 | 157 | // Fallback if bracket-matcher isn't available 158 | else ed.selectWordsContainingCursors(); 159 | 160 | text = ed.getSelectedText(); 161 | } 162 | return text; 163 | } 164 | } 165 | 166 | EmacsLisp.prototype.disposables = null; 167 | module.exports = new EmacsLisp(); 168 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "language-emacs-lisp", 3 | "version": "1.4.1", 4 | "description": "Emacs Lisp support for Atom.", 5 | "keywords": ["Emacs", "Lisp", "Elisp", "Scheme", "GNU", "FSF", "YASnippet", "YAS", "Muse", "AmuseWiki"], 6 | "repository": "https://github.com/Alhadis/language-emacs-lisp", 7 | "license": "ISC", 8 | "atomTestRunner": "atom-mocha", 9 | "devDependencies": { 10 | "atom-mocha": "^2.2.2", 11 | "language-texinfo": "^1.0.0" 12 | }, 13 | "engines": { 14 | "atom": "*" 15 | }, 16 | "scripts": { 17 | "test": "atom -t spec/" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /settings/editor.cson: -------------------------------------------------------------------------------- 1 | ".source.emacs.lisp": 2 | editor: 3 | commentStart: ";; " 4 | "bracket-matcher": 5 | autocompleteCharacters: ["()", "[]", "{}", '""', "“”", "‘’", "«»", "‹›"] 6 | 7 | ".text.muse": 8 | editor: 9 | commentStart: "; " 10 | 11 | ".source.yasnippet": 12 | editor: 13 | commentStart: "# " 14 | whitespace: 15 | ensureSingleTrailingNewline: false 16 | -------------------------------------------------------------------------------- /snippets/snippets.cson: -------------------------------------------------------------------------------- 1 | ".source.yasnippet": 2 | Snippet: 3 | prefix: "snip" 4 | leftLabel: "yas" 5 | description: "File header containing the snippet's metadata." 6 | descriptionMoreURL: "http://joaotavora.github.io/yasnippet/snippet-development.html" 7 | body: """ 8 | # -*- mode: snippet -*- 9 | # key: ${1:name} 10 | # name: ${1:${2:name}} 11 | # -- 12 | $3 13 | """ 14 | 15 | Snippet2: 16 | prefix: "vars" 17 | leftLabel: "yas" 18 | description: "Extended snippet header with less common metadata." 19 | descriptionMoreURL: "https://github.com/joaotavora/yasnippet-snippets/blob/ac385b0e/snippet-mode/vars" 20 | body: """ 21 | # -*- mode: snippet -*- 22 | # name: $1${2: 23 | # key: ${3:trigger-key}}${4: 24 | # keybinding: ${5:keybinding}}${6: 25 | # expand-env: (${7:})} 26 | # contributor: $6 27 | # -- 28 | $0 29 | """ 30 | 31 | Modeline1: 32 | prefix: "mo" 33 | body: "# -*- mode: snippet -*-" 34 | leftLabel: "yas" 35 | description: "Emacs modeline enabling snippet-mode." 36 | descriptionMoreURL: "https://github.com/joaotavora/yasnippet" 37 | 38 | Modeline2: 39 | prefix: "md" 40 | body: "# -*- mode: snippet -*-" 41 | leftLabel: "yas" 42 | description: "Aliased form of Modeline1." 43 | descriptionMoreURL: "https://github.com/joaotavora/yasnippet" 44 | 45 | Key: 46 | prefix: "key" 47 | body: "# key: ${1:prefix}" 48 | leftLabel: "yas" 49 | description: "Prefix used to trigger snippet expansion." 50 | descriptionMoreURL: "http://joaotavora.github.io/yasnippet/snippet-reference.html#yas-expand" 51 | 52 | Name: 53 | prefix: "name" 54 | body: "# name: ${1:Label}" 55 | leftLabel: "yas" 56 | description: "Optional human-readable label for snippet's menu entry." 57 | descriptionMoreURL: "http://joaotavora.github.io/yasnippet/snippet-development.html#org592456a" 58 | 59 | Field: 60 | prefix: "$f" 61 | body: "\\${${1:${2:n}:}$3${4:\\$(${5:lisp-fn})}\\}$0" 62 | leftLabel: "yas" 63 | description: "${…} field" 64 | descriptionMoreURL: "https://github.com/joaotavora/yasnippet-snippets/blob/ac385b0e/snippet-mode/field" 65 | 66 | Group: 67 | prefix: "g" 68 | body: "# group: ${1:Menu grouping}" 69 | leftLabel: "yas" 70 | description: "Snippet menu grouping." 71 | descriptionMoreURL: "http://joaotavora.github.io/yasnippet/snippet-development.html#orgd710184" 72 | 73 | Mirror: 74 | prefix: "$m" 75 | body: "\\${${2:n}:${4:\\$(${5:reflection-fn})}\\}$0" 76 | leftLabel: "yas" 77 | description: "`${n:$(…)}` mirror" 78 | descriptionMoreURL: "https://github.com/joaotavora/yasnippet-snippets/blob/ac385b0e/snippet-mode/mirror" 79 | 80 | Author: 81 | prefix: "au" 82 | body: "# contributor: ${1:John Doe} <${2:john.doe@email}>$0" 83 | leftLabel: "yas" 84 | description: "Name of snippet's author or contributor." 85 | descriptionMoreURL: "http://joaotavora.github.io/yasnippet/snippet-development.html#orge2b38b9" 86 | 87 | AtomDescriptionMoreURL: 88 | prefix: "url" 89 | body: "# atom-description-more-url: ${1:http://more.info/}" 90 | leftLabel: "yas" 91 | description: "Atom-specific header used by `yas2atom`" 92 | descriptionMoreURL: "https://github.com/atom/snippets#optional-parameters" 93 | 94 | AtomSelector: 95 | prefix: "as" 96 | body: "# atom-selector: ${1::not(*)}" 97 | leftLabel: "yas" 98 | description: "Atom-specific header used by `yas2atom`." 99 | descriptionMoreURL: "https://github.com/Alhadis/YASR" 100 | --------------------------------------------------------------------------------