Personal emacs config
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

14290 lines
515 KiB

  1. ;;; web-mode.el --- major mode for editing web templates
  2. ;;; -*- coding: utf-8; lexical-binding: t; -*-
  3. ;; Copyright 2011-2020 François-Xavier Bois
  4. ;; Version: 17.0.0
  5. ;; Package-Version: 17
  6. ;; Package-Commit: d115f8dc3052e5779938d782d9cdaa4533ef20ff
  7. ;; Author: François-Xavier Bois <fxbois AT Google Mail Service>
  8. ;; Maintainer: François-Xavier Bois
  9. ;; Package-Requires: ((emacs "23.1"))
  10. ;; URL: http://web-mode.org
  11. ;; Repository: http://github.com/fxbois/web-mode
  12. ;; Created: July 2011
  13. ;; Keywords: languages
  14. ;; License: GNU General Public License >= 2
  15. ;; Distribution: This file is not part of Emacs
  16. ;;; Commentary:
  17. ;;==============================================================================
  18. ;; WEB-MODE is sponsored by ** Kernix ** Best Digital Factory & Data Lab (Paris)
  19. ;;==============================================================================
  20. ;;; Code:
  21. ;;---- CONSTS ------------------------------------------------------------------
  22. (defconst web-mode-version "17.0.0"
  23. "Web Mode version.")
  24. ;;---- GROUPS ------------------------------------------------------------------
  25. (defgroup web-mode nil
  26. "Major mode for editing web templates"
  27. :group 'languages
  28. :prefix "web-"
  29. :link '(url-link :tag "Site" "http://web-mode.org")
  30. :link '(url-link :tag "Repository" "https://github.com/fxbois/web-mode"))
  31. (defgroup web-mode-faces nil
  32. "Faces for syntax highlighting."
  33. :group 'web-mode
  34. :group 'faces)
  35. ;;---- CUSTOMS -----------------------------------------------------------------
  36. (defcustom web-mode-block-padding 0
  37. "Multi-line block (php, ruby, java, python, asp, etc.) left padding.
  38. -1 to have to code aligned on the column 0."
  39. :type '(choice (integer :tags "Number of spaces")
  40. (const :tags "No indent" nil))
  41. :group 'web-mode)
  42. (defcustom web-mode-part-padding 1
  43. "Part elements (script, style) left padding."
  44. :type '(choice (integer :tags "Number of spaces")
  45. (const :tags "No indent" nil))
  46. :group 'web-mode)
  47. (defcustom web-mode-script-padding web-mode-part-padding
  48. "Script element left padding."
  49. :type '(choice (integer :tags "Number of spaces")
  50. (const :tags "No indent" nil))
  51. :group 'web-mode)
  52. (defcustom web-mode-style-padding web-mode-part-padding
  53. "Style element left padding."
  54. :type '(choice (integer :tags "Number of spaces")
  55. (const :tags "No indent" nil))
  56. :group 'web-mode)
  57. (defcustom web-mode-attr-indent-offset nil
  58. "Html attribute indentation level."
  59. :type '(choice (integer :tags "Number of spaces")
  60. (const :tags "Default" nil))
  61. :safe #'(lambda (v) (or (integerp v) (booleanp v)))
  62. :group 'web-mode)
  63. (defcustom web-mode-attr-value-indent-offset nil
  64. "Html attribute value indentation level."
  65. :type '(choice (integer :tags "Number of spaces")
  66. (const :tags "Default" nil))
  67. :safe #'(lambda (v) (or (integerp v) (booleanp v)))
  68. :group 'web-mode)
  69. (defcustom web-mode-markup-indent-offset
  70. (if (and (boundp 'standard-indent) standard-indent) standard-indent 2)
  71. "Html indentation level."
  72. :type 'integer
  73. :safe #'integerp
  74. :group 'web-mode)
  75. (defcustom web-mode-css-indent-offset
  76. (if (and (boundp 'standard-indent) standard-indent) standard-indent 2)
  77. "CSS indentation level."
  78. :type 'integer
  79. :safe #'integerp
  80. :group 'web-mode)
  81. (defcustom web-mode-code-indent-offset
  82. (if (and (boundp 'standard-indent) standard-indent) standard-indent 2)
  83. "Code (javascript, php, etc.) indentation level."
  84. :type 'integer
  85. :safe #'integerp
  86. :group 'web-mode)
  87. (defcustom web-mode-sql-indent-offset 4
  88. "Sql (inside strings) indentation level."
  89. :type 'integer
  90. :safe #'integerp
  91. :group 'web-mode)
  92. (defcustom web-mode-enable-css-colorization (display-graphic-p)
  93. "In a CSS part, set background according to the color: #xxx, rgb(x,x,x)."
  94. :type 'boolean
  95. :group 'web-mode)
  96. (defcustom web-mode-enable-comment-interpolation nil
  97. "Enable highlight of keywords like FIXME, TODO, etc. in comments."
  98. :type 'boolean
  99. :group 'web-mode)
  100. (defcustom web-mode-enable-comment-annotation nil
  101. "Enable annotation in comments (jsdoc, phpdoc, etc.)."
  102. :type 'boolean
  103. :group 'web-mode)
  104. (defcustom web-mode-enable-auto-indentation (display-graphic-p)
  105. "Auto-indentation."
  106. :type 'boolean
  107. :group 'web-mode)
  108. (defcustom web-mode-enable-auto-closing (display-graphic-p)
  109. "Auto-closing."
  110. :type 'boolean
  111. :group 'web-mode)
  112. (defcustom web-mode-enable-auto-pairing (display-graphic-p)
  113. "Auto-pairing."
  114. :type 'boolean
  115. :group 'web-mode)
  116. (defcustom web-mode-enable-auto-opening (display-graphic-p)
  117. "Html element auto-opening."
  118. :type 'boolean
  119. :group 'web-mode)
  120. (defcustom web-mode-enable-auto-quoting (display-graphic-p)
  121. "Add double quotes after the character = in a tag."
  122. :type 'boolean
  123. :group 'web-mode)
  124. (defcustom web-mode-enable-auto-expanding nil
  125. "e.g. s/ expands to <span>|</span>."
  126. :type 'boolean
  127. :group 'web-mode)
  128. (defcustom web-mode-enable-control-block-indentation t
  129. "Control blocks increase indentation."
  130. :type 'boolean
  131. :group 'web-mode)
  132. (defcustom web-mode-enable-current-element-highlight nil
  133. "Enable current element highlight."
  134. :type 'boolean
  135. :group 'web-mode)
  136. (defcustom web-mode-enable-current-column-highlight nil
  137. "Show column for current element."
  138. :type 'boolean
  139. :group 'web-mode)
  140. (defcustom web-mode-enable-whitespace-fontification nil
  141. "Enable whitespaces."
  142. :type 'boolean
  143. :group 'web-mode)
  144. (defcustom web-mode-enable-html-entities-fontification nil
  145. "Enable html entities fontification."
  146. :type 'boolean
  147. :group 'web-mode)
  148. (defcustom web-mode-enable-block-face nil
  149. "Enable block face (useful for setting a background for example).
  150. See web-mode-block-face."
  151. :type 'boolean
  152. :group 'web-mode)
  153. (defcustom web-mode-enable-part-face nil
  154. "Enable part face (useful for setting background of <style> or <script>
  155. elements for example). See web-mode-part-face."
  156. :type 'boolean
  157. :group 'web-mode)
  158. (defcustom web-mode-enable-inlays nil
  159. "Enable inlays (e.g. LaTeX) highlighting."
  160. :type 'boolean
  161. :group 'web-mode)
  162. (defcustom web-mode-enable-sexp-functions t
  163. "Enable specific sexp functions."
  164. :type 'boolean
  165. :group 'web-mode)
  166. (defcustom web-mode-enable-string-interpolation t
  167. "Enable string interpolation fontification (php and erb)."
  168. :type 'boolean
  169. :group 'web-mode)
  170. (defcustom web-mode-enable-literal-interpolation t
  171. "Enable template literal fontification. e.g. css` `."
  172. :type 'boolean
  173. :group 'web-mode)
  174. (defcustom web-mode-enable-sql-detection nil
  175. "Enable fontification and indentation of sql queries in strings."
  176. :type 'boolean
  177. :group 'web-mode)
  178. (defcustom web-mode-enable-heredoc-fontification t
  179. "Enable heredoc fontification. The identifier should contain JS, JAVASCRIPT, CSS or HTML."
  180. :type 'boolean
  181. :group 'web-mode)
  182. (defcustom web-mode-enable-element-content-fontification nil
  183. "Enable element content fontification. The content of an element can have a face associated."
  184. :type 'boolean
  185. :group 'web-mode)
  186. (defcustom web-mode-enable-element-tag-fontification nil
  187. "Enable tag name fontification."
  188. :type 'boolean
  189. :group 'web-mode)
  190. (defcustom web-mode-enable-engine-detection nil
  191. "Detect such directive -*- engine: ENGINE -*- at the top of the file."
  192. :type 'boolean
  193. :group 'web-mode)
  194. (defcustom web-mode-enable-optional-tags nil
  195. "Enable omission of certain closing tags (e.g. a li open tag followed by a li open tag is valid)."
  196. :type 'boolean
  197. :group 'web-mode)
  198. (defcustom web-mode-comment-style 1
  199. "Comment style : 1 = default, 2 = force server comments outside a block."
  200. :group 'web-mode
  201. :type '(choice (const :tag "Default" 1)
  202. (const :tag "Force engine comments" 2)))
  203. (defcustom web-mode-indent-style 2
  204. "Indentation style."
  205. :group 'web-mode
  206. :type '(choice (const :tag "Default (all lines are indented)" 2)
  207. (const :tag "Text at the beginning of line is not indented" 1)))
  208. (defcustom web-mode-auto-close-style 1
  209. "Auto-close style."
  210. :group 'web-mode
  211. :type '(choice (const :tag "Auto-close on </" 1)
  212. (const :tag "Auto-close on > and </" 2)
  213. (const :tag "Auto-close on < and >/>" 3)))
  214. (defcustom web-mode-auto-quote-style 1
  215. "Auto-quoting style."
  216. :group 'web-mode
  217. :type '(choice (const :tag "Auto-quotes with double quote" 1)
  218. (const :tag "Auto-quotes with single quote" 2)
  219. (const :tag "Auto-quotes with paren (for jsx)" 3)))
  220. (defcustom web-mode-extra-expanders '()
  221. "A list of additional expanders."
  222. :type '(alist :key-type string :value-type string)
  223. :group 'web-mode)
  224. (defcustom web-mode-extra-auto-pairs '()
  225. "A list of additional auto-pairs."
  226. :type '(alist :key-type string :value-type string)
  227. :group 'web-mode)
  228. (defcustom web-mode-extra-snippets '()
  229. "A list of additional snippets."
  230. :type '(alist :key-type string :value-type string)
  231. :group 'web-mode)
  232. (defcustom web-mode-extra-builtins '()
  233. "A list of additional builtins."
  234. :type '(alist :key-type string :value-type string)
  235. :group 'web-mode)
  236. (defcustom web-mode-extra-constants '()
  237. "A list of additional constants."
  238. :type '(alist :key-type string :value-type string)
  239. :group 'web-mode)
  240. (defcustom web-mode-extra-keywords '()
  241. "A list of additional keywords."
  242. :type '(alist :key-type string :value-type string)
  243. :group 'web-mode)
  244. (defcustom web-mode-extra-types '()
  245. "A list of additional types."
  246. :type '(alist :key-type string :value-type string)
  247. :group 'web-mode)
  248. (defcustom web-mode-extra-control-blocks '()
  249. "A list of additional control blocks."
  250. :type '(alist :key-type string :value-type string)
  251. :group 'web-mode)
  252. (defcustom web-mode-tests-directory (concat default-directory "tests/")
  253. "Directory containing all the unit tests."
  254. :type 'directory
  255. :group 'web-mode)
  256. (defcustom web-mode-jsx-depth-faces
  257. nil
  258. ;;'(web-mode-jsx-depth-1-face web-mode-jsx-depth-2-face web-mode-jsx-depth-3-face web-mode-jsx-depth-4-face web-mode-jsx-depth-5-face)
  259. "Each jsx depth has is own face."
  260. :type '(repeat face)
  261. :group 'web-mode)
  262. (defcustom web-mode-commands-like-expand-region
  263. '(web-mode-mark-and-expand er/expand-region mc/mark-next-like-this)
  264. "Add it to here if you have some wrapper function for er/expand-region"
  265. :type '(repeat function)
  266. :group 'web-mode)
  267. (defcustom web-mode-comment-formats
  268. '(("java" . "/*")
  269. ("javascript" . "/*")
  270. ("typescript" . "//")
  271. ("php" . "/*")
  272. ("css" . "/*"))
  273. "Default comment format for a language"
  274. :type '(alist :key-type string :value-type string)
  275. :group 'web-mode)
  276. (defcustom web-mode-script-template-types
  277. '("text/x-handlebars"
  278. "text/x-jquery-tmpl"
  279. "text/x-jsrender"
  280. "text/html"
  281. "text/ng-template"
  282. "text/x-template"
  283. "text/mustache"
  284. "text/x-dust-template")
  285. "<script> block types that are interpreted as HTML."
  286. :type '(repeat string)
  287. :group 'web-mode)
  288. ;;---- FACES -------------------------------------------------------------------
  289. (defface web-mode-error-face
  290. '((t :background "red"))
  291. "Face for warning."
  292. :group 'web-mode-faces)
  293. (defface web-mode-warning-face
  294. '((t :inherit font-lock-warning-face))
  295. "Face for warning."
  296. :group 'web-mode-faces)
  297. (defface web-mode-preprocessor-face
  298. '((t :inherit font-lock-preprocessor-face))
  299. "Face for preprocessor commands."
  300. :group 'web-mode-faces)
  301. (defface web-mode-preprocessor-face
  302. '((t :inherit font-lock-preprocessor-face))
  303. "Face for preprocessor."
  304. :group 'web-mode-faces)
  305. (defface web-mode-block-delimiter-face
  306. '((t :inherit font-lock-preprocessor-face))
  307. "Face for block delimiters."
  308. :group 'web-mode-faces)
  309. (defface web-mode-block-control-face
  310. '((t :inherit font-lock-preprocessor-face))
  311. "Face for preprocessor."
  312. :group 'web-mode-faces)
  313. (defface web-mode-builtin-face
  314. '((t :inherit font-lock-builtin-face))
  315. "Face for builtins."
  316. :group 'web-mode-faces)
  317. (defface web-mode-symbol-face
  318. '((t :foreground "goldenrod2"))
  319. "Face for symbols."
  320. :group 'web-mode-faces)
  321. (defface web-mode-doctype-face
  322. '((t :foreground "Grey"))
  323. "Face for html doctype."
  324. :group 'web-mode-faces)
  325. (defface web-mode-html-tag-face
  326. '((((class color) (min-colors 88) (background dark)) :foreground "Snow4")
  327. (((class color) (min-colors 88) (background light)) :foreground "Snow4")
  328. (((class color) (min-colors 16) (background dark)) :foreground "Snow4")
  329. (((class color) (min-colors 16) (background light)) :foreground "Grey15")
  330. (((class color) (min-colors 8)) :foreground "Snow4")
  331. (((type tty) (class mono)) :inverse-video t)
  332. (t :foreground "Snow4"))
  333. "Face for html tags."
  334. :group 'web-mode-faces)
  335. (defface web-mode-html-tag-custom-face
  336. '((t :inherit web-mode-html-tag-face))
  337. "Face for html custom tags (e.g. <polymer-element>)."
  338. :group 'web-mode-faces)
  339. (defface web-mode-html-tag-unclosed-face
  340. '((t :inherit web-mode-html-tag-face :underline t))
  341. "Face for unclosed tags."
  342. :group 'web-mode-faces)
  343. (defface web-mode-html-tag-namespaced-face
  344. '((t :inherit web-mode-block-control-face))
  345. "Face for html namespaced tags (e.g. <c:forEach>)."
  346. :group 'web-mode-faces)
  347. (defface web-mode-html-tag-bracket-face
  348. '((((class color) (min-colors 88) (background dark)) :foreground "Snow3")
  349. (((class color) (min-colors 88) (background light)) :foreground "Grey14")
  350. (((class color) (min-colors 16) (background dark)) :foreground "Snow3")
  351. (((class color) (min-colors 16) (background light)) :foreground "Grey14")
  352. (((class color) (min-colors 8)) :foreground "Snow3")
  353. (((type tty) (class mono)) :inverse-video t)
  354. (t :foreground "Snow3"))
  355. "Face for html tags angle brackets (<, > and />)."
  356. :group 'web-mode-faces)
  357. (defface web-mode-html-attr-name-face
  358. '((((class color) (min-colors 88) (background dark)) :foreground "Snow3")
  359. (((class color) (min-colors 88) (background light)) :foreground "Snow4")
  360. (((class color) (min-colors 16) (background dark)) :foreground "Snow3")
  361. (((class color) (min-colors 16) (background light)) :foreground "Grey13")
  362. (((class color) (min-colors 8)) :foreground "Snow3")
  363. (((type tty) (class mono)) :inverse-video t)
  364. (t :foreground "Snow4"))
  365. "Face for html attribute names."
  366. :group 'web-mode-faces)
  367. (defface web-mode-html-attr-custom-face
  368. '((t :inherit web-mode-html-attr-name-face))
  369. "Face for custom attribute names (e.g. data-*)."
  370. :group 'web-mode-faces)
  371. (defface web-mode-html-attr-engine-face
  372. '((t :inherit web-mode-block-delimiter-face))
  373. "Face for custom engine attribute names (e.g. ng-*)."
  374. :group 'web-mode-faces)
  375. (defface web-mode-html-attr-equal-face
  376. '((t :inherit web-mode-html-attr-name-face))
  377. "Face for the = character between name and value."
  378. :group 'web-mode-faces)
  379. (defface web-mode-html-attr-value-face
  380. '((t :inherit font-lock-string-face))
  381. "Face for html attribute values."
  382. :group 'web-mode-faces)
  383. (defface web-mode-block-attr-name-face
  384. '((t :foreground "#8fbc8f"))
  385. "Face for block attribute names."
  386. :group 'web-mode-faces)
  387. (defface web-mode-block-attr-value-face
  388. '((t :foreground "#5f9ea0"))
  389. "Face for block attribute values."
  390. :group 'web-mode-faces)
  391. (defface web-mode-variable-name-face
  392. '((t :inherit font-lock-variable-name-face))
  393. "Face for variable names."
  394. :group 'web-mode-faces)
  395. (defface web-mode-css-selector-face
  396. '((t :inherit font-lock-keyword-face))
  397. "Face for CSS rules."
  398. :group 'web-mode-faces)
  399. (defface web-mode-css-pseudo-class-face
  400. '((t :inherit font-lock-builtin-face))
  401. "Face for CSS pseudo-classes."
  402. :group 'web-mode-faces)
  403. (defface web-mode-css-at-rule-face
  404. '((t :inherit font-lock-constant-face))
  405. "Face for CSS at-rules."
  406. :group 'web-mode-faces)
  407. (defface web-mode-css-property-name-face
  408. '((t :inherit font-lock-variable-name-face))
  409. "Face for CSS props."
  410. :group 'web-mode-faces)
  411. (defface web-mode-css-color-face
  412. '((t :inherit font-lock-builtin-face))
  413. "Face for CSS colors (#xxx)."
  414. :group 'web-mode-faces)
  415. (defface web-mode-css-priority-face
  416. '((t :inherit font-lock-builtin-face))
  417. "Face for CSS priority (!important)."
  418. :group 'web-mode-faces)
  419. (defface web-mode-css-function-face
  420. '((t :inherit font-lock-builtin-face))
  421. "Face for CSS functions."
  422. :group 'web-mode-faces)
  423. (defface web-mode-css-variable-face
  424. '((t :inherit web-mode-variable-name-face :slant italic))
  425. "Face for CSS vars."
  426. :group 'web-mode-faces)
  427. (defface web-mode-function-name-face
  428. '((t :inherit font-lock-function-name-face))
  429. "Face for function names."
  430. :group 'web-mode-faces)
  431. (defface web-mode-filter-face
  432. '((t :inherit font-lock-function-name-face))
  433. "Face for function names."
  434. :group 'web-mode-faces)
  435. (defface web-mode-function-call-face
  436. '((t :inherit font-lock-function-name-face))
  437. "Face for function calls."
  438. :group 'web-mode-faces)
  439. (defface web-mode-string-face
  440. '((t :inherit font-lock-string-face))
  441. "Face for strings."
  442. :group 'web-mode-faces)
  443. (defface web-mode-block-string-face
  444. '((t :inherit web-mode-string-face))
  445. "Face for block strings."
  446. :group 'web-mode-faces)
  447. (defface web-mode-part-string-face
  448. '((t :inherit web-mode-string-face))
  449. "Face for part strings."
  450. :group 'web-mode-faces)
  451. (defface web-mode-javascript-string-face
  452. '((t :inherit web-mode-string-face))
  453. "Face for javascript strings."
  454. :group 'web-mode-faces)
  455. (defface web-mode-interpolate-color1-face
  456. '((t :inherit web-mode-string-face))
  457. "Face for element interpolation strings."
  458. :group 'web-mode-faces)
  459. (defface web-mode-interpolate-color2-face
  460. '((t :inherit web-mode-string-face))
  461. "Face for element interpolation strings."
  462. :group 'web-mode-faces)
  463. (defface web-mode-interpolate-color3-face
  464. '((t :inherit web-mode-string-face))
  465. "Face for element interpolation strings."
  466. :group 'web-mode-faces)
  467. (defface web-mode-css-string-face
  468. '((t :inherit web-mode-string-face))
  469. "Face for css strings."
  470. :group 'web-mode-faces)
  471. (defface web-mode-json-key-face
  472. '((t :foreground "plum"))
  473. "Face for json key strings."
  474. :group 'web-mode-faces)
  475. (defface web-mode-json-context-face
  476. '((t :foreground "orchid3"))
  477. "Face for json context strings."
  478. :group 'web-mode-faces)
  479. (defface web-mode-json-string-face
  480. '((t :inherit web-mode-string-face))
  481. "Face for json strings."
  482. :group 'web-mode-faces)
  483. (defface web-mode-comment-face
  484. '((t :inherit font-lock-comment-face))
  485. "Face for comments."
  486. :group 'web-mode-faces)
  487. (defface web-mode-block-comment-face
  488. '((t :inherit web-mode-comment-face))
  489. "Face for server comments."
  490. :group 'web-mode-faces)
  491. (defface web-mode-part-comment-face
  492. '((t :inherit web-mode-comment-face))
  493. "Face for part comments."
  494. :group 'web-mode-faces)
  495. (defface web-mode-json-comment-face
  496. '((t :inherit web-mode-comment-face))
  497. "Face for json comments."
  498. :group 'web-mode-faces)
  499. (defface web-mode-javascript-comment-face
  500. '((t :inherit web-mode-comment-face))
  501. "Face for javascript comments."
  502. :group 'web-mode-faces)
  503. (defface web-mode-css-comment-face
  504. '((t :inherit web-mode-comment-face))
  505. "Face for css comments."
  506. :group 'web-mode-faces)
  507. (defface web-mode-annotation-face
  508. '((t :inherit web-mode-comment-face))
  509. "Face for code annotations."
  510. :group 'web-mode-faces)
  511. (defface web-mode-annotation-tag-face
  512. '((t :inherit web-mode-annotation-face :underline t))
  513. "Face for @tags in code annotations."
  514. :group 'web-mode-faces)
  515. (defface web-mode-annotation-type-face
  516. '((t :inherit web-mode-annotation-face :weight bold))
  517. "Face for types in code annotations."
  518. :group 'web-mode-faces)
  519. (defface web-mode-annotation-value-face
  520. '((t :inherit web-mode-annotation-face :slant italic))
  521. "Face for values in code annotations."
  522. :group 'web-mode-faces)
  523. (defface web-mode-annotation-html-face
  524. '((t :inherit web-mode-annotation-face :slant italic))
  525. "Face for HTML tags in code annotations."
  526. :group 'web-mode-faces)
  527. (defface web-mode-constant-face
  528. '((t :inherit font-lock-constant-face))
  529. "Face for language constants."
  530. :group 'web-mode-faces)
  531. (defface web-mode-type-face
  532. '((t :inherit font-lock-type-face))
  533. "Face for language types."
  534. :group 'web-mode-faces)
  535. (defface web-mode-keyword-face
  536. '((t :inherit font-lock-keyword-face))
  537. "Face for language keywords."
  538. :group 'web-mode-faces)
  539. (defface web-mode-param-name-face
  540. '((t :foreground "Snow3"))
  541. "Face for server attribute names."
  542. :group 'web-mode-faces)
  543. (defface web-mode-whitespace-face
  544. '((t :background "DarkOrchid4"))
  545. "Face for whitespaces."
  546. :group 'web-mode-faces)
  547. (defface web-mode-inlay-face
  548. '((((class color) (min-colors 88) (background dark)) :background "Black")
  549. (((class color) (min-colors 88) (background light)) :background "LightYellow1")
  550. (((class color) (min-colors 16) (background dark)) :background "Brey18")
  551. (((class color) (min-colors 16) (background light)) :background "LightYellow1")
  552. (((class color) (min-colors 8)) :background "Black")
  553. (((type tty) (class mono)) :inverse-video t)
  554. (t :background "Grey"))
  555. "Face for inlays. Must be used in conjunction with web-mode-enable-inlays."
  556. :group 'web-mode-faces)
  557. (defface web-mode-block-face
  558. '((((class color) (min-colors 88) (background dark)) :background "Black")
  559. (((class color) (min-colors 88) (background light)) :background "LightYellow1")
  560. (((class color) (min-colors 16) (background dark)) :background "Grey18")
  561. (((class color) (min-colors 16) (background light)) :background "LightYellow1")
  562. (((class color) (min-colors 8)) :background "Black")
  563. (((type tty) (class mono)) :inverse-video t)
  564. (t :background "Grey"))
  565. "Face for blocks (useful for setting a background for example).
  566. Must be used in conjunction with web-mode-enable-block-face."
  567. :group 'web-mode-faces)
  568. (defface web-mode-part-face
  569. '((t :inherit web-mode-block-face))
  570. "Face for parts."
  571. :group 'web-mode-faces)
  572. (defface web-mode-script-face
  573. '((t :inherit web-mode-part-face))
  574. "Face for javascript inside a script element."
  575. :group 'web-mode-faces)
  576. (defface web-mode-style-face
  577. '((t :inherit web-mode-part-face))
  578. "Face for css inside a style element."
  579. :group 'web-mode-faces)
  580. (defface web-mode-folded-face
  581. '((t :underline t))
  582. "Overlay face for folded."
  583. :group 'web-mode-faces)
  584. (defface web-mode-bold-face
  585. '((t :weight bold))
  586. "bold face."
  587. :group 'web-mode-faces)
  588. (defface web-mode-italic-face
  589. '((t :slant italic))
  590. "bold face."
  591. :group 'web-mode-faces)
  592. (defface web-mode-underline-face
  593. '((t :underline t))
  594. "bold face."
  595. :group 'web-mode-faces)
  596. (defface web-mode-current-element-highlight-face
  597. '((t :background "#000000" :foreground "#ffffff"))
  598. "Overlay face for element highlight."
  599. :group 'web-mode-faces)
  600. (defface web-mode-current-column-highlight-face
  601. '((t :background "#3e3c36"))
  602. "Overlay face for current column."
  603. :group 'web-mode-faces)
  604. (defface web-mode-comment-keyword-face
  605. '((t :weight bold :box t))
  606. "Comment keywords."
  607. :group 'web-mode-faces)
  608. (defface web-mode-sql-keyword-face
  609. '((t :weight bold :slant italic))
  610. "Sql keywords."
  611. :group 'web-mode-faces)
  612. (defface web-mode-html-entity-face
  613. '((t :slant italic))
  614. "Face html entities (e.g. &#8211;, &eacute;)."
  615. :group 'web-mode-faces)
  616. ;; https://material.io/tools/color/#!/?view.left=0&view.right=0
  617. (defface web-mode-jsx-depth-1-face
  618. '((t :background "#000053"))
  619. "jsx depth 1"
  620. :group 'web-mode-faces)
  621. (defface web-mode-jsx-depth-2-face
  622. '((t :background "#001970"))
  623. "jsx"
  624. :group 'web-mode-faces)
  625. (defface web-mode-jsx-depth-3-face
  626. '((t :background "#002984"))
  627. "jsx"
  628. :group 'web-mode-faces)
  629. (defface web-mode-jsx-depth-4-face
  630. '((t :background "#49599a"))
  631. "jsx"
  632. :group 'web-mode-faces)
  633. (defface web-mode-jsx-depth-5-face
  634. '((t :background "#9499b7"))
  635. "jsx"
  636. :group 'web-mode-faces)
  637. ;;---- VARS --------------------------------------------------------------------
  638. ;;(defvar font-lock-beg)
  639. ;;(defvar font-lock-end)
  640. (defvar web-mode-auto-pairs nil)
  641. (defvar web-mode-block-regexp nil)
  642. (defvar web-mode-change-beg nil)
  643. (defvar web-mode-change-end nil)
  644. (defvar web-mode-chunk-length 64)
  645. (defvar web-mode-column-overlays nil)
  646. (defvar web-mode-comments-invisible nil)
  647. (defvar web-mode-content-type "")
  648. (defvar web-mode-engine nil)
  649. ;;(defvar web-mode-engine-attr-regexp nil)
  650. (defvar web-mode-engine-font-lock-keywords nil)
  651. (defvar web-mode-engine-token-regexp nil)
  652. (defvar web-mode-expand-initial-pos nil)
  653. (defvar web-mode-expand-initial-scroll nil)
  654. (defvar web-mode-expand-previous-state "")
  655. ;;(defvar web-mode-font-lock-keywords '(web-mode-font-lock-highlight))
  656. (defvar web-mode-fontification-off nil)
  657. (defvar web-mode-inlay-regexp nil)
  658. (defvar web-mode-is-scratch nil)
  659. (defvar web-mode-jshint-errors 0)
  660. (defvar web-mode-minor-engine nil)
  661. (defvar web-mode-obarray nil)
  662. (defvar web-mode-overlay-tag-start nil)
  663. (defvar web-mode-overlay-tag-end nil)
  664. (defvar web-mode-part-beg nil)
  665. (defvar web-mode-scan-beg nil)
  666. (defvar web-mode-scan-end nil)
  667. (defvar web-mode-snippets nil)
  668. (defvar web-mode-time nil)
  669. (defvar web-mode-offsetless-elements
  670. '())
  671. (defvar web-mode-indentless-elements
  672. '("code" "pre" "textarea"))
  673. (defvar web-mode-indentless-attributes
  674. '("onclick" "onmouseover" "onmouseout" "onsubmit"))
  675. (defvar web-mode-void-elements
  676. '("area" "base" "br" "col" "command" "embed" "hr" "img" "input" "keygen"
  677. "link" "meta" "param" "source" "track" "wbr"))
  678. (defvar web-mode-part-content-types
  679. '("css" "javascript" "json" "jsx" "markdown" "pug" "ruby"
  680. "sass" "sql" "stylus" "typescript"))
  681. (defvar web-mode-javascript-languages '("javascript" "jsx" "ejs"))
  682. ;; NOTE: without 'syntax-table forward-word fails (#377)
  683. (defvar web-mode-scan-properties
  684. (list 'tag-beg 'tag-end 'tag-name 'tag-type
  685. 'tag-attr 'tag-attr-beg 'tag-attr-end
  686. 'part-side 'part-token
  687. 'jsx-beg 'jsx-end 'jsx-depth
  688. 'block-side 'block-token 'block-controls 'block-beg 'block-end
  689. 'syntax-table)
  690. "Text properties used for code regions/tokens and html nodes.")
  691. (defvar web-mode-start-tag-regexp "<\\([[:alpha:]][[:alnum:].:_-]*\\|>\\)"
  692. "Regular expression for HTML/XML start tag.")
  693. (defvar web-mode-tag-regexp "</?\\([[:alpha:]][[:alnum:].:_-]*\\)"
  694. "Regular expression for HTML/XML tag.")
  695. (defvar web-mode-dom-regexp "<\\(/?>\\|/?[[:alpha:]][[:alnum:].:_-]*\\|!--\\|!\\[CDATA\\[\\|!doctype\\|!DOCTYPE\\|\?xml\\)")
  696. (defvar web-mode-whitespaces-regexp
  697. "^[ \t]\\{2,\\}$\\| \t\\|\t \\|[ \t]+$\\|^[ \n\t]+\\'\\|^[ \t]?[\n]\\{2,\\}"
  698. "Regular expression for whitespaces.")
  699. (defvar web-mode-imenu-regexp-list
  700. '(("<\\(h[1-9]\\)\\([^>]*\\)>\\([^<]*\\)" 1 3 ">")
  701. ("^[ \t]*<\\([@a-z]+\\)[^>]*>? *$" 1 "id=\"\\([a-zA-Z0-9_]+\\)\"" "#" ">"))
  702. "Regexps to match imenu items (see http://web-mode.org/doc/imenu.txt)")
  703. ;; https://www.gnu.org/software/emacs/manual/html_node/ccmode/Syntactic-Symbols.html
  704. (defvar web-mode-indentation-params
  705. '(("lineup-args" . t)
  706. ("lineup-calls" . t)
  707. ("lineup-concats" . t)
  708. ("lineup-quotes" . t)
  709. ("lineup-ternary" . t)
  710. ("case-extra-offset" . t)
  711. ))
  712. (defvar web-mode-engines
  713. '(("angular" . ("angularjs"))
  714. ("archibus" . ())
  715. ("artanis" . ())
  716. ("asp" . ())
  717. ("aspx" . ())
  718. ("blade" . ("laravel"))
  719. ("cl-emb" . ())
  720. ("clip" . ())
  721. ("closure" . ("soy"))
  722. ("ctemplate" . ("mustache" "handlebars" "hapax" "ngtemplate" "ember"
  723. "kite" "meteor" "blaze" "ractive" "velvet"))
  724. ("django" . ("dtl" "twig" "swig" "jinja" "jinja2" "erlydtl" "liquid"
  725. "clabango" "selmer" "nunjucks"))
  726. ("dust" . ("dustjs"))
  727. ("ejs" . ())
  728. ("elixir" . ("phoenix"))
  729. ("erb" . ("eruby" "erubis"))
  730. ("expressionengine" . ("ee"))
  731. ("freemarker" . ())
  732. ("go" . ("gtl" "hugo"))
  733. ("hero" . ())
  734. ("json-t" . ())
  735. ("jsp" . ("grails"))
  736. ("mako" . ())
  737. ("marko" . ())
  738. ("mason" . ("poet"))
  739. ("lsp" . ("lisp"))
  740. ("mojolicious" . ())
  741. ("php" . ())
  742. ("python" . ())
  743. ("razor" . ("play" "play2"))
  744. ("riot" . ())
  745. ("smarty" . ())
  746. ("spip" . ())
  747. ("svelte" . ("svelte"))
  748. ("template-toolkit" . ())
  749. ("thymeleaf" . ())
  750. ("underscore" . ("underscore.js"))
  751. ("velocity" . ("vtl" "cheetah" "ssp"))
  752. ("vue" . ("vuejs" "vue.js"))
  753. ("web2py" . ())
  754. ("xoops" . ())
  755. )
  756. "Engine name aliases")
  757. (defvar web-mode-content-types
  758. '(("css" . "\\.\\(s?css\\|css\\.erb\\)\\'")
  759. ("javascript" . "\\.\\(js\\|js\\.erb\\)\\'")
  760. ("typescript" . "\\.\\(ts\\|ts\\.erb\\)\\'")
  761. ("json" . "\\.\\(api\\|json\\|jsonld\\)\\'")
  762. ("jsx" . "\\.[jt]sx\\'")
  763. ("xml" . "\\.xml\\'")
  764. ("html" . "."))
  765. "content types")
  766. (defvar web-mode-engine-attr-regexps
  767. '(("angular" . "ng-")
  768. ("thymeleaf" . "th:")
  769. ("vue" . "v-"))
  770. "Engine custom attributes")
  771. (defvar web-mode-engine-attr-regexp
  772. "^ng[-]\\|^th[:]\\|^v[-]\\|^[@:#(\[*]"
  773. "Engine custom attributes")
  774. (defvar web-mode-last-enabled-feature nil)
  775. (defvar web-mode-features
  776. '(("css-colorization" . web-mode-enable-css-colorization)
  777. ("element-highlight" . web-mode-enable-current-element-highlight)
  778. ("column-highlight" . web-mode-enable-current-column-highlight)
  779. ("whitespace-fontification" . web-mode-enable-whitespace-fontification)
  780. ("element-tag-fontification" . web-mode-enable-element-tag-fontification)
  781. ("block-face" . web-mode-enable-block-face)
  782. ("part-face" . web-mode-enable-part-face)))
  783. (defvar web-mode-comment-prefixing t)
  784. (defvar web-mode-engine-file-regexps
  785. '(("angular" . "\\.component.html\\'")
  786. ("archibus" . "\\.axvw\\'")
  787. ("artanis" . "\\.html\\.tpl\\'")
  788. ("asp" . "\\.asp\\'")
  789. ("aspx" . "\\.as[cp]x\\'")
  790. ("blade" . "\\.blade\\.php\\'")
  791. ("cl-emb" . "\\.clemb\\'")
  792. ("clip" . "\\.ctml\\'")
  793. ("closure" . "\\.soy\\'")
  794. ("ctemplate" . "\\.\\(chtml\\|mustache\\)\\'")
  795. ("django" . "\\.\\(djhtml\\|tmpl\\|dtl\\|liquid\\|j2\\|njk\\)\\'")
  796. ("dust" . "\\.dust\\'")
  797. ("elixir" . "\\.l?eex\\'")
  798. ("ejs" . "\\.ejs\\'")
  799. ("erb" . "\\.\\(erb\\|rhtml\\|erb\\.html\\)\\'")
  800. ("expressionengine" . "\\.ee\\'")
  801. ("freemarker" . "\\.ftl\\'")
  802. ("go" . "\\.go\\(html\\|tmpl\\)\\'")
  803. ("handlebars" . "\\.\\(hb\\.html\\|hbs\\)\\'")
  804. ("hero" . "\\.hero\\'")
  805. ("jinja" . "\\.jinja\\'")
  806. ("jsp" . "\\.[gj]sp\\'")
  807. ("lsp" . "\\.lsp\\'")
  808. ("mako" . "\\.mako?\\'")
  809. ("marko" . "\\.marko\\'")
  810. ("mason" . "\\.mas\\'")
  811. ("mojolicious" . "\\.epl?\\'")
  812. ("php" . "\\.\\(p[hs]p\\|ctp\\|inc\\)\\'")
  813. ("python" . "\\.pml\\'")
  814. ("razor" . "\\.\\(cs\\|vb\\)html\\|\\.razor\\'")
  815. ("riot" . "\\.tag\\'")
  816. ("smarty" . "\\.tpl\\'")
  817. ("svelte" . "\\.svelte\\'")
  818. ("template-toolkit" . "\\.tt.?\\'")
  819. ("thymeleaf" . "\\.thtml\\'")
  820. ("velocity" . "\\.v\\(sl\\|tl\\|m\\)\\'")
  821. ("vue" . "\\.vue\\'")
  822. ("xoops" . "\\.xoops'")
  823. ;; regexp on the path, not just the extension
  824. ("django" . "[st]wig")
  825. ("razor" . "scala")
  826. ("spip" . "spip")
  827. )
  828. "Engine file extensions.")
  829. (defvar web-mode-content-types-alist nil
  830. "A list of filename patterns and corresponding web-mode content types. For example,
  831. (setq web-mode-content-types-alist
  832. '((\"json\" . \"/some/path/.*\\.api\\'\")
  833. (\"jsx\" . \"/some/react/path/.*\\.js[x]?\\'\")))")
  834. (defvar web-mode-engines-alist nil
  835. "A list of filename patterns and corresponding web-mode engine. For example,
  836. (setq web-mode-engines-alist
  837. '((\"php\" . \"\\\\.phtml\\\\'\")
  838. (\"blade\" . \"\\\\.blade\\\\.\")))")
  839. (defvar web-mode-smart-quotes
  840. '("«" . "»")
  841. "Preferred smart quotes")
  842. (defvar web-mode-xml-chars
  843. '((?\& . "&amp;")
  844. (?\< . "&lt;")
  845. (?\> . "&gt;"))
  846. "XML chars")
  847. (defvar web-mode-html-entities
  848. ;; #985
  849. ;; remove ("gt" . 62) ("lt" . 60) ("amp" . 38)
  850. '(("AElig" . 198) ("Aacute" . 193) ("Acirc" . 194) ("Agrave" . 192)
  851. ("Alpha" . 913) ("Aring" . 197) ("Atilde" . 195) ("Auml" . 196)
  852. ("Beta" . 914)
  853. ("Ccedil" . 199) ("Chi" . 935)
  854. ("Dagger" . 8225) ("Delta" . 916)
  855. ("ETH" . 208) ("Eacute" . 201) ("Ecirc" . 202) ("Egrave" . 200)
  856. ("Epsilon" . 917) ("Eta" . 919) ("Euml" . 203)
  857. ("Gamma" . 915)
  858. ("Iacute" . 205) ("Icirc" . 206) ("Igrave" . 204) ("Iota" . 921)
  859. ("Iuml" . 207)
  860. ("Kappa" . 922)
  861. ("Lambda" . 923)
  862. ("Mu" . 924)
  863. ("Ntilde" . 209) ("Nu" . 925)
  864. ("OElig" . 338) ("Oacute" . 211) ("Ocirc" . 212) ("Ograve" . 210)
  865. ("Omega" . 937) ("Omicron" . 927) ("Oslash" . 216) ("Otilde" . 213)
  866. ("Ouml" . 214)
  867. ("Phi" . 934) ("Pi" . 928) ("Prime" . 8243) ("Psi" . 936)
  868. ("Rho" . 929)
  869. ("Scaron" . 352) ("Sigma" . 931)
  870. ("THORN" . 222) ("Tau" . 932) ("Theta" . 920)
  871. ("UArr" . 8657) ("Uacute" . 218) ("Uacute" . 250) ("Ucirc" . 219)
  872. ("Ugrave" . 217) ("Upsih" . 978)
  873. ("Upsilon" . 933) ("Uuml" . 220) ("Uuml" . 252)
  874. ("Xi" . 926)
  875. ("Yacute" . 221) ("Yuml" . 376)
  876. ("Zeta" . 918)
  877. ("aacute" . 225) ("acirc" . 226) ("acute" . 180) ("aelig" . 230)
  878. ("agrave" . 224) ("alefsym" . 8501) ("alpha" . 945)
  879. ("ang" . 8736) ("apos" . 39) ("aring" . 229) ("asymp" . 8776)
  880. ("atilde" . 227) ("auml" . 228)
  881. ("bdquo" . 8222) ("beta" . 946) ("brvbar" . 166) ("bull" . 8226)
  882. ("cap" . 8745) ("ccedil" . 231) ("cedil" . 184) ("cent" . 162)
  883. ("chi" . 967) ("circ" . 710) ("clubs" . 9827) ("cong" . 8773)
  884. ("copy" . 169) ("crarr" . 8629) ("cup" . 8746) ("curren" . 164)
  885. ("dArr" . 8659) ("dagger" . 8224) ("darr" . 8595) ("deg" . 176)
  886. ("delta" . 948) ("diams" . 9830) ("divide" . 247)
  887. ("eacute" . 233) ("ecirc" . 234) ("egrave" . 232) ("empty" . 8709)
  888. ("emsp" . 8195) ("ensp" . 8194) ("epsilon" . 949) ("equiv" . 8801)
  889. ("eta" . 951) ("eth" . 240) ("euml" . 235) ("euro" . 8364) ("exist" . 8707)
  890. ("fnof" . 402) ("forall" . 8704) ("frac12" . 189) ("frac14" . 188)
  891. ("frac34" . 190) ("frasl" . 8260)
  892. ("gamma" . 947) ("ge" . 8805)
  893. ("hArr" . 8660) ("harr" . 8596) ("hearts" . 9829) ("hellip" . 8230)
  894. ("iacute" . 237) ("icirc" . 238) ("iexcl" . 161) ("igrave" . 236)
  895. ("image" . 8465) ("infin" . 8734) ("int" . 8747) ("iota" . 953)
  896. ("iquest" . 191) ("isin" . 8712) ("iuml" . 239)
  897. ("kappa" . 954)
  898. ("lArr" . 8656) ("lambda" . 955) ("lang" . 9001) ("laquo" . 171)
  899. ("larr" . 8592) ("lceil" . 8968) ("ldquo" . 8220) ("le" . 8804)
  900. ("lfloor" . 8970) ("lowast" . 8727) ("loz" . 9674) ("lrm" . 8206)
  901. ("lsaquo" . 8249) ("lsquo" . 8249)
  902. ("macr" . 175) ("mdash" . 8212) ("micro" . 181) ("middot" . 183)
  903. ("minus" . 8722) ("mu" . 956)
  904. ("nabla" . 8711) ("nbsp" . 160) ("ndash" . 8211) ("ne" . 8800)
  905. ("ni" . 8715) ("not" . 172) ("notin" . 8713) ("nsub" . 8836)
  906. ("ntilde" . 241) ("nu" . 957) ("oacute" . 243) ("ocirc" . 244)
  907. ("oelig" . 339) ("ograve" . 242) ("oline" . 8254) ("omega" . 969)
  908. ("omicron" . 959) ("oplus" . 8853) ("or" . 8744) ("ordf" . 170)
  909. ("ordm" . 186) ("oslash" . 248) ("otilde" . 245) ("otimes" . 8855)
  910. ("ouml" . 246)
  911. ("para" . 182) ("part" . 8706) ("permil" . 8240) ("perp" . 8869)
  912. ("phi" . 966) ("pi" . 960) ("piv" . 982) ("plusmn" . 177) ("pound" . 163)
  913. ("prime" . 8242) ("prod" . 8719) ("prop" . 8733) ("psi" . 968)
  914. ("quot" . 34)
  915. ("rArr" . 8658) ("radic" . 8730) ("rang" . 9002) ("raquo" . 187)
  916. ("rarr" . 8594) ("rceil" . 8969) ("rdquo" . 8221) ("real" . 8476)
  917. ("reg" . 174) ("rfloor" . 8971) ("rho" . 961) ("rlm" . 8207)
  918. ("rsaquo" . 8250) ("rsquo" . 8250) ("sbquo" . 8218)
  919. ("scaron" . 353) ("sdot" . 8901) ("sect" . 167) ("shy" . 173)
  920. ("sigma" . 963) ("sigmaf" . 962) ("sim" . 8764) ("spades" . 9824)
  921. ("sub" . 8834) ("sube" . 8838) ("sum" . 8721) ("sup" . 8835)
  922. ("sup1" . 185) ("sup2" . 178) ("sup3" . 179) ("supe" . 8839)
  923. ("szlig" . 223)
  924. ("tau" . 964) ("there4" . 8756) ("theta" . 952) ("thetasym" . 977)
  925. ("thinsp" . 8201) ("thorn" . 254) ("tilde" . 732) ("times" . 215)
  926. ("trade" . 8482)
  927. ("uarr" . 8593) ("ucirc" . 251) ("ugrave" . 249) ("uml" . 168)
  928. ("upsilon" . 965)
  929. ("weierp" . 8472)
  930. ("xi" . 958)
  931. ("yacute" . 253) ("yen" . 165) ("yuml" . 255)
  932. ("zeta" . 950) ("zwj" . 8205) ("zwnj" . 8204)))
  933. ;; http://webdesign.about.com/od/localization/l/blhtmlcodes-ascii.htm
  934. (defvar web-mode-display-table
  935. (let ((table (make-display-table)))
  936. (aset table 9 (vector ?\xBB ?\t))
  937. (aset table 10 (vector ?\xB6 ?\n))
  938. (aset table 32 (vector ?\xB7))
  939. table)
  940. "Display table used when switching to the whitespace visualization.")
  941. (defvar web-mode-expanders
  942. '(("a/" . "<a href=\"|\"></a>")
  943. ("b/" . "<table><tbody><tr><td>|</td><td></td></tr></tbody></table>")
  944. ("c/" . "<div class=\"|\"></div>")
  945. ("d/" . "<div>|</div>")
  946. ("e/" . "<em>|</em>")
  947. ("f/" . "<form>|</form>")
  948. ("g/" . "<strong>|</strong>")
  949. ("h/" . "<h1>|</h1>")
  950. ("i/" . "<img src=\"|\" />")
  951. ("j/" . "<script>|</script>")
  952. ("l/" . "<li>|</li>")
  953. ("m/" . "<main>|</main>")
  954. ("n/" . "<input type=\"|\" />")
  955. ("p/" . "<p>|</p>")
  956. ("q/" . "<quote>|</quote>")
  957. ("s/" . "<span>|</span>")
  958. ("t/" . "<td>|</td>")
  959. ("u/" . "<ul><li>|</li><li></li></ul>")
  960. ("x/" . "<textarea>|</textarea>")
  961. ("2/" . "<h2>|</h2>")
  962. ("3/" . "<h3>|</h3>")
  963. ("?/" . "<?php | ?>")))
  964. (defvar web-mode-engines-auto-pairs
  965. '(("angular" . (("{{ " . " }}")))
  966. ("artanis" . (("<% " . " %>")
  967. ("<%=" . " | %>")
  968. ("<@css" . " | %>")
  969. ("<@icon" . " | %>")
  970. ("<@include" . " | %>")
  971. ("<@js" . " | %>")))
  972. ("asp" . (("<% " . " %>")))
  973. ("aspx" . (("<% " . " %>")
  974. ("<%=" . "%>")
  975. ("<%#" . "%>")
  976. ("<%$" . "%>")
  977. ("<%@" . "%>")
  978. ("<%:" . "%>")
  979. ("<%-" . "- | --%>")))
  980. ("blade" . (("{{{" . " | }}}")
  981. ("{{ " . " }}")
  982. ("{!!" . " | !!}")
  983. ("@{{" . " | }}")
  984. ("{{-" . "- | --}}")))
  985. ("cl-emb" . (("<% " . " %>")
  986. ("<%=" . " | %>")
  987. ("<%#" . " | %>")))
  988. ("ctemplate" . (("{{ " . "| }}")
  989. ("{{{" . " | }}}")
  990. ("{~{" . " | }}")
  991. ("{{~" . "{ | }}}")
  992. ("{{!" . "-- | --}}")
  993. ("{{^" . "}}")
  994. ("{{/" . "}}")
  995. ("{{#" . "}}")))
  996. ("django" . (("{{ " . " }}")
  997. ("{% " . " %}")
  998. ("{%-" . " | %}")
  999. ("{# " . " #}")))
  1000. ("elixir" . (("<% " . " %>")
  1001. ("<%=" . " | %>")
  1002. ("<%%" . " | %>")
  1003. ("<%#" . " | %>")))
  1004. ("ejs" . (("<% " . " %>")
  1005. ("<%=" . "%>")
  1006. ("<%#" . "%>")
  1007. ("<%-" . "%>")))
  1008. ("erb" . (("<% " . " %>")
  1009. ("<%=" . " %>")
  1010. ("<%#" . "%>")
  1011. ("<%-" . " %>")))
  1012. ("freemarker" . (("<% " . " %>")
  1013. ("<#-" . "- | -->")
  1014. ("${ " . " }")
  1015. ("[% " . " %]")
  1016. ("[# " . " #]")
  1017. ("[#-" . "- | --]")))
  1018. ("go" . (("{{ " . " }}")
  1019. ("{{-" . " | -}}")))
  1020. ("hero" . (("<% " . " %>")
  1021. ("<%=" . " | %>")
  1022. ("<%!" . " | %>")
  1023. ("<%:" . " | %>")
  1024. ("<%#" . " | %>")
  1025. ("<%@" . " | %>")
  1026. ("<%~" . " | %>")
  1027. ("<%+" . " | %>")))
  1028. ("jsp" . (("<% " . " %>")
  1029. ("<%-" . "- | --%>")
  1030. ("<%=" . "%>")
  1031. ("<%!" . "%>")
  1032. ("<%@" . "%>")
  1033. ("${ " . " }")))
  1034. ("lsp" . (("<% " . " %>")
  1035. ("<%%" . " | %>")
  1036. ("<%#" . " | %>")))
  1037. ("mako" . (("<% " . " %>")
  1038. ("<%!" . " | %>")
  1039. ("${ " . " }")))
  1040. ("marko" . (("${ " . " }")))
  1041. ("mason" . (("<% " . " %>")
  1042. ("<& " . " &>")))
  1043. ("mojolicious" . (("<% " . " %>")
  1044. ("<%=" . " | %>")
  1045. ("<%%" . " | %>")
  1046. ("<%#" . " | %>")))
  1047. ("php" . (("<?p" . "hp | ?>")
  1048. ("<? " . " ?>")
  1049. ("<?=" . "?>")))
  1050. ("template-toolkit" . (("[% " . " %]")
  1051. ("[%-" . " | %]")
  1052. ("[%#" . " | %]")))
  1053. ("riot" . (("={ " . " }")))
  1054. ("underscore" . (("<% " . " %>")))
  1055. ("vue" . (("{{ " . " }}")))
  1056. ("web2py" . (("{{ " . " }}")
  1057. ("{{=" . "}}")))
  1058. (nil . (("<!-" . "- | -->")))
  1059. ))
  1060. (defvar web-mode-engines-snippets
  1061. '(("artanis" . (("if" . "<% (if (|) %>\n\n<% ) %>")
  1062. ("when" . "<% (when (|) %>\n\n<% ) %>")
  1063. ("unless" . "<% (unless (|) %>\n\n<% ) %>")
  1064. ("cond" . "<% (cond %>\n<% [(|) %>\n\n<% ] %>\n<% [else %>\n\n<% ] %>\n<% ) %>")
  1065. ("let" . "<% (let ([|]) %>\n\n<% ) %>")
  1066. ("let*" . "<% (let* ([|]) %>\n\n<% ) %>")
  1067. ("do" . "<% (do ([|]) %>\n<% [()] %>\n\n<% ) %>")
  1068. ("for-each" . "<% (for-each %>\n|\n\n<% ) %>")
  1069. ("case" . "<% (case | %>\n<% [() %>\n\n<% ] %>\n<% [() %>\n\n<% ] %>\n<% ) %>")))
  1070. ("ejs" . (("for" . "<% for (|) { %>\n\n<% } %>")
  1071. ("if" . "<% if (|) { %>\n\n<% } %>")))
  1072. ("erb" . (("each" . "<% |.each do %>\n\n<% end %>")
  1073. ("if" . "<% if | %>\n\n<% end %>")
  1074. ("when" . "<% when | %>\n\n<% end %>")
  1075. ("unless" . "<% unless | %>\n\n<% end %>")))
  1076. ("php" . (("if" . "<?php if (|): ?>\n\n<?php endif; ?>")
  1077. ("while" . "<?php while (|): ?>\n\n<?php endwhile; ?>")
  1078. ("for" . "<?php for (| ; ; ): ?>\n\n<?php endfor; ?>")
  1079. ("foreach" . "<?php foreach (| as ): ?>\n\n<?php endforeach; ?>")
  1080. ("each" . "<?php foreach (| as ): ?>\n\n<?php endforeach; ?>")
  1081. ("switch" . "<?php switch (|): ?>\n<?php case 1: ?>\n\n<?php break ;?>\n<?php case 2: ?>\n\n<?php break ;?>\n<?php endswitch;?>")))
  1082. ("django" . (("block" . "{% block | %}\n\n{% endblock %}")
  1083. ("comment" . "{% comment | %}\n\n{% endcomment %}")
  1084. ("css" . "{% stylesheet %}\n\n{% endstylesheet %}")
  1085. ("cycle" . "{% cycle | as %}\n\n{% endcycle %}")
  1086. ("filter" . "{% filter | %}\n\n{% endfilter %}")
  1087. ("for" . "{% for | in %}\n\n{% endfor %}")
  1088. ("if" . "{% if | %}\n\n{% endif %}")
  1089. ("ifequal" . "{% ifequal | %}\n\n{% endifequal %}")
  1090. ("ifnotequal" . "{% ifnotequal | %}\n\n{% endifnotequal %}")
  1091. ("js" . "{% javascript | %}\n\n{% endjavascript %}")
  1092. ("schema" . "{% javascript | %}\n\n{% endschema %}")
  1093. ("safe" . "{% safe | %}\n\n{% endsafe %}")))
  1094. ("mako" . (("if" . "% if |:\n% endif")
  1095. ("for" . "% for | in :\n% endfor")
  1096. ("doc" . "<%doc>\n|\n</%doc>")
  1097. ("inherit" . "<%inherit file=\"|\" />")
  1098. ("namespace" . "<%namespace name=\"|\" file=\"\" import=\"\"/>")
  1099. ("block" . "<%block name=\"|\">\n</%block>")))
  1100. ("template-toolkit" . (("if" . "[% IF | %]\n\n[% END %]")))
  1101. (nil . (("html5" . "<!doctype html>\n<html>\n<head>\n<title></title>\n<meta charset=\"utf-8\" />\n</head>\n<body>\n|\n</body>\n</html>")
  1102. ("table" . "<table><tbody>\n<tr>\n<td>|</td>\n<td></td>\n</tr>\n</tbody></table>")
  1103. ("ul" . "<ul>\n<li>|</li>\n<li></li>\n</ul>")))
  1104. ))
  1105. (defvar web-mode-engine-token-regexps
  1106. (list
  1107. '("artanis" . "\"\\|#|\\|;")
  1108. '("asp" . "//\\|/\\*\\|\"\\|'")
  1109. '("ejs" . "//\\|/\\*\\|\"\\|'")
  1110. '("erb" . "\"\\|'\\|#\\|<<[-]?['\"]?\\([[:alnum:]_]+\\)['\"]?")
  1111. '("lsp" . "\"\\|#|\\|;")
  1112. '("mako" . "\"\\|'\\|#")
  1113. '("mason" . "\"\\|'\\|#")
  1114. '("mojolicious" . "\"\\|'")
  1115. '("php" . "//\\|/\\*\\|#\\|\"\\|'\\|<<<['\"]?\\([[:alnum:]]+\\)['\"]?")
  1116. '("python" . "\"\\|'\\|#")
  1117. '("web2py" . "\"\\|'"))
  1118. "Engine regexps used to identify tokens (strings / comments) in blocks.")
  1119. (defvar web-mode-engine-open-delimiter-regexps
  1120. (list
  1121. '("angular" . "{{")
  1122. '("artanis" . "<%\\|<@\\(css\\|icon\\|include\\|js\\)")
  1123. '("asp" . "<%\\|</?[[:alpha:]]+:[[:alpha:]]+\\|</?[[:alpha:]]+Template")
  1124. '("aspx" . "<%.")
  1125. '("blade" . "{{.\\|{!!\\|@{{\\|@[[:alpha:]]")
  1126. '("cl-emb" . "<%")
  1127. '("closure" . "{.\\|/\\*\\| //")
  1128. '("clip" . "</?c:[[:alpha:]-]+")
  1129. '("ctemplate" . "[$]?{[{~].")
  1130. '("django" . "{[#{%]")
  1131. '("dust" . "{.")
  1132. '("elixir" . "<%")
  1133. '("ejs" . "<%")
  1134. '("erb" . "<%\\|^%.")
  1135. '("expressionengine" . "{.")
  1136. '("freemarker" . "<%\\|${\\|</?[[:alpha:]]+:[[:alpha:]]\\|</?[@#]\\|\\[/?[@#].")
  1137. '("go" . "{{.")
  1138. '("hero" . "<%")
  1139. '("jsp" . "<%\\|${")
  1140. '("lsp" . "<%")
  1141. '("mako" . "</?%\\|${\\|^[ \t]*%.\\|^[ \t]*##")
  1142. '("marko" . "${")
  1143. '("mason" . "</?[&%]\\|^%.")
  1144. '("mojolicious" . "<%\\|^[ \t]*%.")
  1145. '("php" . "<\\?")
  1146. '("python" . "<\\?")
  1147. '("razor" . "@.\\|^[ \t]*}")
  1148. '("riot" . "{.\\|/// begin script")
  1149. '("smarty" . "{[[:alpha:]#$/*\"]")
  1150. '("spip" . "\\[(#REM)\\|(\\|#[A-Z0-9_]\\|{\\|<:")
  1151. '("template-toolkit" . "\\[%.\\|%%#")
  1152. '("underscore" . "<%")
  1153. '("velocity" . "#[[:alpha:]#*]\\|$[[:alpha:]!{]")
  1154. '("vue" . "{{\\|[:@][-[:alpha:]]+=\"")
  1155. '("web2py" . "{{")
  1156. '("xoops" . "<{[[:alpha:]#$/*\"]")
  1157. '("svelte" . "{.")
  1158. )
  1159. "Engine regexps used to identify blocks.")
  1160. (defvar web-mode-normalization-rules
  1161. '(("tag-case" . "lower-case")
  1162. ("attr-case" . "lower-case")
  1163. ("special-chars" . "unicode") ;"unicode" "entities"
  1164. ("css-indentation" . t)
  1165. ("smart-apostrophes" . t)
  1166. ("smart-quotes" . t)
  1167. ("whitespaces" . t)
  1168. ("indentation" . t))
  1169. "Normalization rules")
  1170. (defvar web-mode-element-tag-faces
  1171. (list
  1172. '("h1" . web-mode-underline-face)
  1173. '("h2" . web-mode-underline-face)
  1174. '("h3" . web-mode-underline-face)
  1175. '("h4" . web-mode-underline-face)
  1176. '("title" . web-mode-underline-face)
  1177. '("em" . web-mode-italic-face)
  1178. '("strong" . web-mode-bold-face)
  1179. ))
  1180. (defvar web-mode-element-content-faces
  1181. (list
  1182. '("h1" . web-mode-underline-face)
  1183. '("h2" . web-mode-underline-face)
  1184. '("h3" . web-mode-underline-face)
  1185. '("h4" . web-mode-underline-face)
  1186. '("title" . web-mode-underline-face)
  1187. '("em" . web-mode-italic-face)
  1188. '("strong" . web-mode-bold-face)
  1189. ))
  1190. (defvar web-mode-comment-keywords
  1191. (regexp-opt
  1192. (append
  1193. (cdr (assoc "comment" web-mode-extra-keywords))
  1194. '("FIXME" "TODO" "BUG" "KLUDGE" "WORKAROUND" "OPTIMIZE" "HACK" "REFACTOR" "REVIEW"))))
  1195. (defvar web-mode-links
  1196. '(("\\.\\(png\\|jpe?g\\|gif\\|webp\\)$" "<img src=\"%s\" alt=\"\" />" nil 4)
  1197. ("\\.svg$" "<object data=\"%s\" type=\"image/svg+xml\"></object>" nil 0)
  1198. ("\\.js$" "<script type=\"text/javascript\" src=\"%s\"></script>" t 0)
  1199. ("\\.css$" "<link rel=\"stylesheet\" type=\"text/css\" href=\"%s\" />" t 0)
  1200. ("\\.html?$" "<a href=\"%s\"></a>" nil 4))
  1201. "List of elements and extensions for `web-mode-file-link'. It
  1202. consists of a string that contains the regular expression that
  1203. matches the appropriate files, a format string with element that
  1204. contains the link (%s should be put where the path goes,) a bool
  1205. that tells if the element belongs in the <head> element, and
  1206. number of characters to move back if needed (or 0 if point
  1207. shouldn't be moved back.)")
  1208. (defvar web-mode-sql-queries
  1209. (regexp-opt
  1210. '("SELECT" "INSERT" "UPDATE" "DELETE" "select" "insert" "update" "delete")))
  1211. (defvar web-mode-sql-keywords
  1212. (regexp-opt
  1213. (append
  1214. (cdr (assoc "sql" web-mode-extra-keywords))
  1215. '("SELECT" "INSERT" "UPDATE" "DELETE"
  1216. "FROM" "WHERE" "GROUP BY" "LIKE" "LIMIT" "HAVING" "JOIN" "LEFT" "INNER"
  1217. "FULL" "OUTER" "VALUES" "ORDER BY" "SEPARATOR" "ASC" "DESC"
  1218. "AND" "OR" "ON" "WHEN" "ELSE" "END" "THEN"))))
  1219. (defvar web-mode-python-constants
  1220. (regexp-opt
  1221. (append
  1222. (cdr (assoc "python" web-mode-extra-constants))
  1223. '("True" "False" "None" "__debug__" "NotImplemented" "Ellipsis"))))
  1224. (defvar web-mode-erlang-constants
  1225. (regexp-opt
  1226. (append
  1227. (cdr (assoc "erlang" web-mode-extra-constants))
  1228. '("true" "false"))))
  1229. (defvar web-mode-erlang-keywords
  1230. (regexp-opt
  1231. (append
  1232. (cdr (assoc "erlang" web-mode-extra-keywords))
  1233. '("else" "if" "do" "end"))))
  1234. (defvar web-mode-cl-emb-constants
  1235. (regexp-opt
  1236. '("nil" "t" "raw" "escape")))
  1237. (defvar web-mode-cl-emb-keywords
  1238. (regexp-opt
  1239. '("if" "else" "endif" "unless" "endunless" "var" "repeat"
  1240. "endrepeat" "loop" "endloop" "include" "call" "with"
  1241. "endwith" "set" "genloop" "endgenloop" "insert")))
  1242. (defvar web-mode-artanis-constants
  1243. (regexp-opt
  1244. '("#f" "#t")))
  1245. (defvar web-mode-artanis-keywords
  1246. (regexp-opt
  1247. (append
  1248. (cdr (assoc "artanis" web-mode-extra-keywords))
  1249. '("begin" "cut" "cute" "if" "when" "unless" "cond" "case"
  1250. "do" "quote" "syntax" "lambda" "lambda*" "and" "and-let*"
  1251. "or" "else" "delay" "receive" "use-modules" "match"
  1252. "match-lambda" "match-lambda*" "match-let" "match-let*"
  1253. "match-letrec" "let" "let*" "letrec" "letrec*" "and-let*"
  1254. "let-syntax" "letrec-syntax" "syntax-rules" "syntax-case"
  1255. "define" "define-syntax" "define-macro"
  1256. "define-condition-type" "define-immutable-record-type"
  1257. "define-record-type" "define-values" "parameterize" "for-each"
  1258. "require-extension" "set!" "test-approximate" "test-assert"
  1259. "test-begin" "test-end" "test-eq" "test-equal" "test-eqv"
  1260. "test-error" "test-group" "test-group-with-cleanup" "test-with-runner"))))
  1261. (defvar web-mode-lsp-constants
  1262. (regexp-opt
  1263. '("nil" "t")))
  1264. (defvar web-mode-lsp-keywords
  1265. (regexp-opt
  1266. '("dolist" "let" "while" "cond" "when" "progn" "if"
  1267. "dotimes" "unless" "lambda"
  1268. "loop" "for" "and" "or" "in" "do" "defun")))
  1269. (defvar web-mode-php-constants
  1270. (regexp-opt
  1271. (append
  1272. (cdr (assoc "php" web-mode-extra-constants))
  1273. '("TRUE" "FALSE" "NULL" "true" "false" "null"
  1274. "STR_PAD_LEFT" "STR_PAD_RIGHT"
  1275. "ENT_COMPAT" "ENT_QUOTES" "ENT_NOQUOTES" "ENT_IGNORE"
  1276. "ENT_SUBSTITUTE" "ENT_DISALLOWED" "ENT_HTML401" "ENT_XML1"
  1277. "ENT_XHTML" "ENT_HTML5" "JSON_PRETTY_PRINT"
  1278. "LIBXML_NOBLANKS"))))
  1279. (defvar web-mode-php-keywords
  1280. (regexp-opt
  1281. (append
  1282. (cdr (assoc "php" web-mode-extra-keywords))
  1283. '("abstract" "and" "array" "as" "break" "case" "catch" "class" "clone"
  1284. "const" "continue" "declare" "default" "die" "do" "echo" "else" "elseif"
  1285. "empty" "enddeclare" "endfor" "endforeach" "endif" "endswitch" "endwhile"
  1286. "eval" "exit" "extends" "final" "finally" "fn" "for" "foreach" "function"
  1287. "global" "goto" "if" "implements" "include" "include_once" "instanceof"
  1288. "insteadof" "interface" "isset" "list" "namespace" "new" "or" "parent"
  1289. "print" "private" "protected" "public" "require" "require_once" "return"
  1290. "self" "static" "switch" "trait" "try" "throw" "unset" "use" "var"
  1291. "while" "xor" "yield" "yield from"))))
  1292. (defvar web-mode-php-types
  1293. (eval-when-compile
  1294. (regexp-opt
  1295. '("array" "bool" "boolean" "callable" "float" "int" "integer"
  1296. "iterable" "mixed" "object" "resource" "string" "void"))))
  1297. (defvar web-mode-css-at-rules
  1298. (eval-when-compile
  1299. (regexp-opt
  1300. '("charset" "import" "media" "page" "font-face"
  1301. "namespace" "supports" "document"
  1302. "keyframes" "-moz-keyframes" "-webkit-keyframes"
  1303. "mixin" "viewport"))))
  1304. (defvar web-mode-css-pseudo-classes
  1305. (eval-when-compile
  1306. (regexp-opt
  1307. '("active" "after" "before" "checked" "disabled" "empty" "enabled"
  1308. "first" "first-child" "first-letter" "first-line" "first-of-type" "focus"
  1309. "hover" "lang" "last-child" "last-of-type" "left" "link"
  1310. "not" "nth-child" "nth-last-child" "nth-last-of-type" "nth-of-type"
  1311. "only-child" "only-of-type"
  1312. "right" "root" "selection" "target" "visited"))))
  1313. (defvar web-mode-python-keywords
  1314. (regexp-opt
  1315. (append
  1316. (cdr (assoc "python" web-mode-extra-keywords))
  1317. '("and" "as" "assert" "break" "class" "continue" "def" "del"
  1318. "elif" "else" "except" "finally" "for" "from" "global"
  1319. "if" "import" "in" "is" "lambda" "nonlocal" "not" "or" "pass"
  1320. "raise" "return" "try" "while" "with" "yield"))))
  1321. (defvar web-mode-jsp-keywords
  1322. (regexp-opt
  1323. (append
  1324. (cdr (assoc "jsp" web-mode-extra-keywords))
  1325. '("case" "catch" "do" "else" "end" "false" "for" "function"
  1326. "if" "in" "include"
  1327. "new" "package" "page" "private" "protected" "public"
  1328. "return" "tag" "taglib" "throw" "throws" "true" "try" "void" "while"))))
  1329. (defvar web-mode-erb-keywords
  1330. (regexp-opt
  1331. (append
  1332. (cdr (assoc "erb" web-mode-extra-keywords))
  1333. '("alias" "and" "begin" "break" "case" "class" "def" "defined?" "do"
  1334. "elsif" "else" "end" "ensure" "fail" "for" "if" "in"
  1335. "module" "next" "not" "or" "redo" "rescue" "retry" "return"
  1336. "then" "super" "unless" "undef" "until" "when" "while" "yield"
  1337. "__ENCODING__" "__FILE__" "__LINE__"))))
  1338. (defvar web-mode-mason-keywords
  1339. (regexp-opt
  1340. (append
  1341. (cdr (assoc "mason" web-mode-extra-keywords))
  1342. '("and" "base" "close" "die" "each" "else" "elsif" "eval" "exists"
  1343. "foreach" "grep" "if" "length" "local" "my" "next" "open" "or"
  1344. "package" "pop" "ref" "return" "stat" "sub" "tie"
  1345. "undef" "unless" "use" "while"))))
  1346. (defvar web-mode-erb-builtins
  1347. (regexp-opt
  1348. (append
  1349. (cdr (assoc "erb" web-mode-extra-builtins))
  1350. '("__callee__" "__dir__" "__method__"
  1351. "abort" "at_exit" "autoload" "autoload?"
  1352. "binding" "block_given?" "caller" "catch"
  1353. "eval" "exec" "exit" "exit!" "fail" "fork" "format"
  1354. "lambda" "load" "loop" "open"
  1355. "p" "print" "printf" "proc" "putc" "puts"
  1356. "raise" "rand" "readline" "readlines" "require" "require_relative"
  1357. "sleep" "spawn" "sprintf" "srand" "syscall" "system"
  1358. "throw" "trap" "warn"
  1359. "alias_method" "attr" "attr_accessor" "attr_reader" "attr_writer"
  1360. "define_method" "extend" "include" "module_function"
  1361. "prepend" "private" "protected" "public"
  1362. "refine" "using"
  1363. "error_message_on" "error_messages_for" "form" "input"
  1364. "auto_discovery_link_tag" "image_tag" "javascript_include_tag"
  1365. "stylesheet_link_tag" "image_path" "path_to_image"" "
  1366. "javascript_path" "path_to_javascript" "register_javascript_expansion"
  1367. "register_javascript_include_default" "register_stylesheet_expansion"
  1368. "stylesheet_path" "path_to_stylesheet" "atom_feed" "entry" "updated"
  1369. "benchmark" "cache" "capture" "content_for" "distance_of_time_in_words"
  1370. "distance_of_time_in_words_to_now" "time_ago_in_words" "date_select"
  1371. "datetime_select" "time_select" "select_date" "select_datetime"
  1372. "select_day" "select_hour" "select_minute" "select_month" "select_second"
  1373. "select_time" "select_year" "debug"
  1374. "check_box" "fields_for" "file_field" "form_for" "hidden_field"
  1375. "label" "password_field" "radio_button" "text_area" "text_field"
  1376. "check_box_tag" "field_set_tag" "file_field_tag" "form_tag"
  1377. "hidden_field_tag" "image_submit_tag" "label_tag" "password_field_tag"
  1378. "radio_button_tag" "select_tag" "submit_tag" "text_area_tag"
  1379. "text_field_tag"
  1380. "collection_select" "country_options_for_select" "country_select"
  1381. "option_groups_from_collection_for_select" "options_for_select"
  1382. "options_from_collection_for_select" "select"
  1383. "time_zone_options_for_select"
  1384. "time_zone_select" "button_to_function" "define_javascript_functions"
  1385. "escape_javascript" "javascript_tag" "link_to_function"" "
  1386. "number_to_currency" "number_to_human_size" "number_to_percentage"
  1387. "number_to_phone" "number_with_delimiter" "number_with_precision"
  1388. "evaluate_remote_response" "form_remote_for" "form_remote_tag"
  1389. "link_to_remote" "observe_field" "observe_field"
  1390. "periodically_call_remote"
  1391. "remote_form_for" "remote_function" "submit_to_remote" "update_page"
  1392. "update_page_tag" "dom_class" "dom_id" "partial_path" "sanitize"
  1393. "sanitize_css" "strip_links" "strip_tags"
  1394. "cdata_section" "content_tag" "escape_once" "tag"
  1395. "auto_link" "concat" "cycle" "excerpt" "highlight" "markdown" "pluralize"
  1396. "reset_cycle" "simple_format" "textilize" "textilize_without_paragraph"
  1397. "truncate" "word_wrap" "button_to" "current_page?" "link_to" "link_to_if"
  1398. "link_to_unless" "link_to_unless_current" "mail_to" "url_for"
  1399. "action_name" "atom_feed" "audio_path" "audio_tag"
  1400. "content_tag_for" "controller" "controller_name" "action_name"
  1401. "controller_path" "convert_to_model" "cookies" "csrf_meta_tag"
  1402. "csrf_meta_tags" "headers"
  1403. "current_cycle" "div_for" "email_field" "email_field_tag"
  1404. "favicon_link_tag" "flash" "l" "button_tag"
  1405. "grouped_collection_select" "grouped_options_for_select"
  1406. "image_alt" "j" "javascript_cdata_section"
  1407. "localize" "logger" "number_field"
  1408. "number_field_tag" "number_to_human" "params" "path_to_audio"
  1409. "path_to_video" "phone_field" "phone_field_tag" "provide"
  1410. "range_field" "range_field_tag" "raw" "render" "request"
  1411. "request_forgery_protection_token" "response" "safe_concat"
  1412. "safe_join" "search_field" "search_field_tag"
  1413. "session" "t" "telephone_field" "telephone_field_tag"
  1414. "time_tag" "translate" "url_field" "url_field_tag"
  1415. "url_options" "video_path" "video_tag" "simple_form_for"
  1416. "javascript_pack_tag" "stylesheet_pack_tag" "csp_meta_tag"
  1417. ))))
  1418. (defvar web-mode-asp-constants
  1419. (regexp-opt
  1420. (append
  1421. (cdr (assoc "asp" web-mode-extra-constants))
  1422. '("adAsyncExecute" "adAsyncFetch" "adAsyncFetchNonBlocking" "adCmdFile"
  1423. "adCmdStoredProc" "adCmdTable" "adCmdTableDirect" "adCmdText" "adCmdUnknown"
  1424. "adCmdUnspecified" "adExecuteNoRecords" "adExecuteRecord" "adExecuteStream"
  1425. "adLockBatchOptimistic" "adLockOptimistic" "adLockPessimistic"
  1426. "adLockReadOnly" "adLockUnspecified" "adOpenDynamic" "adOpenForwardOnly"
  1427. "adOpenKeyset" "adOpenStatic" "adOpenUnspecified" "adOptionUnspecified"
  1428. "Empty" "Nothing" "Null" "True" "False"
  1429. "vbBack" "vbCr" "vbCrLf" "vbFormFeed" "vbLf" "vbNewLine" "vbNullChar"
  1430. "vbNullString" "vbObjectError" "vbScript" "vbTab" "vbVerticalTab"))))
  1431. (defvar web-mode-asp-keywords
  1432. (regexp-opt
  1433. (append
  1434. (cdr (assoc "asp" web-mode-extra-keywords))
  1435. '("Abs" "And" "Array" "Asc" "Atn"
  1436. "CBool" "CByte" "CCur" "CDate" "CDbl" "CInt" "CLng" "CSng" "CStr"
  1437. "Call" "Case" "Chr" "Class" "Const" "Cos" "CreateObject"
  1438. "Date" "DateAdd" "DateDiff" "DatePart" "DateSerial" "DateValue"
  1439. "Day" "Dim" "Do"
  1440. "Each" "Else" "ElseIf" "End" "Erase" "Err" "Eval" "Exit" "Exp"
  1441. "Explicit"
  1442. "Filter" "Fix" "For" "FormatCurrency" "FormatDateTime"
  1443. "FormatNumber" "FormatPercent" "Function"
  1444. "GetLocale" "GetObject" "GetRef" "Hex" "Hour"
  1445. "If" "In" "InStr" "InStrRev" "InputBox" "Int" "IsArray" "IsDate"
  1446. "IsEmpty" "IsNull" "IsNumeric" "IsObject" "Join"
  1447. "LBound" "LCase" "LTrim" "Language" "Left" "Len" "Let"
  1448. "LoadPicture" "Log" "Loop"
  1449. "Mid" "Minute" "Month" "MonthName" "MsgBox"
  1450. "New" "Next" "Not" "Now"
  1451. "Oct" "On" "Option" "Or" "Preserve" "Private" "Public"
  1452. "RGB" "RTrim" "Redim" "Rem" "Replace" "Right" "Rnd" "Round"
  1453. "ScriptEngine" "ScriptEngineBuildVersion"
  1454. "ScriptEngineMajorVersion" "ScriptEngineMinorVersion"
  1455. "Second" "Select" "Set" "SetLocale" "Sgn" "Sin" "Space" "Split"
  1456. "Sqr" "StrComp" "StrReverse" "String" "Sub"
  1457. "Tan" "Then" "Time" "TimeSerial" "TimeValue" "Timer" "To" "Trim"
  1458. "TypeName"
  1459. "UBound" "UCase" "Until" "VarType"
  1460. "Weekday" "WeekdayName" "Wend" "With" "While" "Year"))))
  1461. (defvar web-mode-asp-types
  1462. (regexp-opt
  1463. (append
  1464. (cdr (assoc "asp" web-mode-extra-types))
  1465. '("Application" "ASPError" "Request" "Response" "Server" "Session"))))
  1466. (defvar web-mode-aspx-keywords
  1467. (regexp-opt
  1468. (append
  1469. (cdr (assoc "aspx" web-mode-extra-keywords))
  1470. '("case" "catch" "do" "else" "end" "for" "foreach" "function"
  1471. "if" "in" "include" "new" "package" "page" "return"
  1472. "tag" "throw" "throws" "try" "while"))))
  1473. (defvar web-mode-smarty-keywords
  1474. (regexp-opt '("as")))
  1475. (defvar web-mode-velocity-keywords
  1476. (eval-when-compile
  1477. (regexp-opt '("in" "true" "false"))))
  1478. (defvar web-mode-freemarker-keywords
  1479. (eval-when-compile
  1480. (regexp-opt '("as" "list"))))
  1481. (defvar web-mode-go-keywords
  1482. (eval-when-compile
  1483. (regexp-opt
  1484. '("const" "define" "else" "end"
  1485. "for" "func" "if" "import"
  1486. "pipeline" "range" "return" "struct"
  1487. "template" "type" "var" "with"))))
  1488. (defvar web-mode-go-functions
  1489. (eval-when-compile
  1490. (regexp-opt
  1491. '("and" "call" "ge" "html" "index" "js" "len" "not" "or"
  1492. "print" "printf" "println" "urlquery" "where"))))
  1493. (defvar web-mode-go-types
  1494. (regexp-opt
  1495. (append
  1496. (cdr (assoc "go" web-mode-extra-types))
  1497. '("int" "string"))))
  1498. (defvar web-mode-closure-keywords
  1499. (eval-when-compile
  1500. (regexp-opt '("in" "and" "not" "or"))))
  1501. (defvar web-mode-svelte-keywords
  1502. (regexp-opt '("as")))
  1503. (defvar web-mode-django-control-blocks
  1504. (append
  1505. (cdr (assoc "django" web-mode-extra-control-blocks))
  1506. '(
  1507. "assets" "autoescape"
  1508. "block" "blocktrans"
  1509. "cache" "call" "capture" "comment"
  1510. "draw"
  1511. "embed"
  1512. "filter" "for" "foreach" "form"
  1513. "if" "ifchanged" "ifequal" "ifnotequal"
  1514. "macro"
  1515. "random" "raw"
  1516. "safe" "sandbox" "spaceless"
  1517. "tablerow"
  1518. "unless"
  1519. "verbatim"
  1520. "with"
  1521. "endassets" "endautoescape"
  1522. "endblock" "endblocktrans"
  1523. "endcache" "endcall" "endcapture" "endcomment"
  1524. "draw"
  1525. "endembed"
  1526. "endfilter" "endfor" "endforeach" "endform"
  1527. "endif" "endifchanged" "endifequal" "endifnotequal"
  1528. "endmacro"
  1529. "endrandom" "endraw"
  1530. "endsafe" "endsandbox" "endspaceless"
  1531. "endtablerow"
  1532. "endunless"
  1533. "endverbatim"
  1534. "endwith"
  1535. ;; "set" "endset" ;#504
  1536. "csrf_token" "cycle" "debug"
  1537. "elif" "else" "elseif" "elsif" "empty" "extends"
  1538. "firstof" "include" "load" "lorem" "now" "regroup" "ssi"
  1539. "trans" "templatetag" "url" "widthratio"
  1540. ;; #805
  1541. "graph" "endgraph"
  1542. "javascript" "endjavascript"
  1543. "schema" "endschema"
  1544. "stylesheet" "endstylesheet"
  1545. )))
  1546. (defvar web-mode-django-control-blocks-regexp
  1547. (regexp-opt web-mode-django-control-blocks t))
  1548. (defvar web-mode-django-keywords
  1549. (eval-when-compile
  1550. (regexp-opt
  1551. '("and" "as" "assign"
  1552. "break"
  1553. "cache" "call" "case" "context" "continue"
  1554. "do"
  1555. "flush" "from"
  1556. "ignore" "import" "in" "is"
  1557. "layout" "load"
  1558. "missing"
  1559. "none" "not"
  1560. "or"
  1561. "pluralize"
  1562. "random"
  1563. "set" ;#504
  1564. "unless" "use"
  1565. "var"
  1566. ))))
  1567. (defvar web-mode-django-types
  1568. (eval-when-compile
  1569. (regexp-opt '("null" "false" "true"))))
  1570. (defvar web-mode-blade-control-blocks
  1571. (append
  1572. (cdr (assoc "blade" web-mode-extra-control-blocks))
  1573. '("component" "foreach" "forelse" "for" "if" "section" "slot" "switch" "unless" "while")
  1574. ))
  1575. (defvar web-mode-blade-control-blocks-regexp
  1576. (regexp-opt web-mode-blade-control-blocks t))
  1577. (defvar web-mode-directives
  1578. (eval-when-compile
  1579. (regexp-opt
  1580. '("include" "page" "taglib"
  1581. "Assembly" "Control" "Implements" "Import"
  1582. "Master" "OutputCache" "Page" "Reference" "Register"))))
  1583. (defvar web-mode-template-toolkit-keywords
  1584. (regexp-opt
  1585. '("block" "call" "case" "catch" "clear" "default" "do"
  1586. "else" "elsif" "end" "filter" "final" "for"
  1587. "foreach" "get" "if" "in" "include" "insert" "is" "last"
  1588. "macro" "meta" "or" "perl" "process" "rawperl" "return"
  1589. "set" "stop" "switch" "tags" "throw" "try"
  1590. "unless" "use" "while" "wrapper")))
  1591. (defvar web-mode-perl-keywords
  1592. (regexp-opt
  1593. '("__DATA__" "__END__" "__FILE__" "__LINE__" "__PACKAGE__"
  1594. "and" "cmp" "continue" "CORE" "do" "else" "elsif" "eq" "exp"
  1595. "for" "foreach" "ge" "gt" "if" "le" "lock" "lt" "m" "ne" "no"
  1596. "or" "package" "q" "qq" "qr" "qw" "qx" "s" "sub"
  1597. "tr" "unless" "until" "while" "xor" "y"
  1598. "my" "use" "print" "say")))
  1599. (defvar web-mode-javascript-keywords
  1600. (regexp-opt
  1601. (append
  1602. (cdr (assoc "javascript" web-mode-extra-keywords))
  1603. '("as" "async" "await" "break" "case" "catch" "class" "const" "continue"
  1604. "debugger" "default" "delete" "do" "else" "enum" "eval"
  1605. "export" "extends" "finally" "for" "from" "function" "get" "if"
  1606. "implements" "import" "in" "instanceof" "interface" "let"
  1607. "new" "of" "package" "private" "protected" "public"
  1608. "return" "set" "static" "super" "switch"
  1609. "throw" "try" "type" "typeof" "var" "void" "while" "with" "yield"))))
  1610. (defvar web-mode-javascript-constants
  1611. (regexp-opt
  1612. '("false" "null" "undefined" "Infinity" "NaN" "true" "arguments" "this")))
  1613. (defvar web-mode-razor-keywords
  1614. (regexp-opt
  1615. (append
  1616. (cdr (assoc "razor" web-mode-extra-keywords))
  1617. '("false" "true" "foreach" "if" "else" "in" "var" "for" "display"
  1618. "match" "case" "to"
  1619. "Html"))))
  1620. (defvar web-mode-selector-font-lock-keywords
  1621. (list
  1622. '("$[[:alnum:]-]+" 0 'web-mode-css-variable-face)
  1623. (cons (concat "@\\(" web-mode-css-at-rules "\\)\\_>")
  1624. '(0 'web-mode-css-at-rule-face))
  1625. '("\\_<\\(all\|braille\\|embossed\\|handheld\\|print\\|projection\\|screen\\|speech\\|tty\\|tv\\|and\\|or\\)\\_>"
  1626. 1 'web-mode-keyword-face)
  1627. '("[^,]+" 0 'web-mode-css-selector-face)
  1628. (cons (concat ":\\([ ]*[[:alpha:]][^,{]*\\)") '(0 'web-mode-css-pseudo-class-face t t))
  1629. ))
  1630. (defvar web-mode-declaration-font-lock-keywords
  1631. (list
  1632. '("--[[:alnum:]-]+" 0 'web-mode-css-variable-face)
  1633. '("$[[:alnum:]-]+" 0 'web-mode-css-variable-face)
  1634. (cons (concat "@\\(" web-mode-css-at-rules "\\)\\_>") '(1 'web-mode-css-at-rule-face))
  1635. '("\\([[:alpha:]-]+\\)[ ]?:" 0 'web-mode-css-property-name-face)
  1636. '("\\([[:alpha:]-]+\\)[ ]?(" 1 'web-mode-css-function-face)
  1637. '("#[[:alnum:]]\\{1,6\\}" 0 'web-mode-css-color-face t t)
  1638. '("![ ]?important" 0 'web-mode-css-priority-face t t)
  1639. '("\\([^,]+\\)[ ]+{" 1 'web-mode-css-selector-face)
  1640. '("'[^']*'\\|\"[^\"]*\"" 0 'web-mode-string-face t t)
  1641. ))
  1642. (defvar web-mode-html-font-lock-keywords
  1643. (list
  1644. '("</?[[:alnum:]]+[ >]\\|>" 0 'web-mode-html-tag-face t)
  1645. '(" \\([[:alnum:]-]+=\\)\\(\"[^\"]+\"\\)"
  1646. (1 'web-mode-html-attr-name-face)
  1647. (2 'web-mode-html-attr-value-face))
  1648. ))
  1649. ;; voir https://www.gnu.org/software/emacs/manual/html_node/elisp/Search_002dbased-Fontification.html
  1650. (defvar web-mode-javascript-font-lock-keywords
  1651. (list
  1652. '("@\\([[:alnum:]_]+\\)\\_>" 0 'web-mode-keyword-face)
  1653. '("\\([[:alnum:]]+\\)[`]" 0 'web-mode-preprocessor-face)
  1654. (cons (concat "\\_<\\(function\\*\\)\\_>") '(1 'web-mode-keyword-face))
  1655. (cons (concat "\\([ \t}{(]\\|^\\)\\(" web-mode-javascript-keywords "\\)\\_>") '(2 'web-mode-keyword-face))
  1656. (cons (concat "\\_<\\(" web-mode-javascript-constants "\\)\\_>") '(0 'web-mode-constant-face))
  1657. '("\\_<\\([$]\\)(" 1 'web-mode-type-face)
  1658. '("\\_<\\(new\\|instanceof\\|class\\|extends\\) \\([[:alnum:]_.]+\\)\\_>" 2 'web-mode-type-face)
  1659. '("\\_<\\([[:alnum:]_]+\\):[ ]*function[ ]*(" 1 'web-mode-function-name-face)
  1660. '("\\_<\\(function\\|get\\|set\\)[ ]+\\([[:alnum:]_]+\\)"
  1661. (1 'web-mode-keyword-face)
  1662. (2 'web-mode-function-name-face))
  1663. '("\\([[:alnum:]_]+\\)[ ]*([^)]*)[ \n]*{" 1 'web-mode-function-name-face)
  1664. '("([ ]*\\([[:alnum:]_]+\\)[ ]*=>" 1 'web-mode-function-name-face)
  1665. '("[ ]*\\([[:alnum:]_]+\\)[ ]*=[ ]*([^)]*)[ ]*=>[ ]*{" 1 'web-mode-function-name-face)
  1666. '("\\_<\\(var\\|let\\|const\\)[ ]+\\([[:alnum:]_]+\\)" 2 'web-mode-variable-name-face)
  1667. '("({" "\\([[:alnum:]_]+\\)[, }]+" nil nil (1 'web-mode-variable-name-face)) ;#738
  1668. '("\\([[:alnum:]_]+\\)[ ]*=> [{(]" 1 'web-mode-variable-name-face)
  1669. ;; #989
  1670. ;; '("\\(function\\|[,=]\\|^\\)[ ]*("
  1671. ;; ("\\([[:alnum:]_]+\\)\\([ ]*=[^,)]*\\)?[,)]" nil nil (1 'web-mode-variable-name-face)))
  1672. '("\\([[:alnum:]_]+\\):" 1 'web-mode-variable-name-face)
  1673. '("\\_<\\([[:alnum:]_-]+\\)[ ]?(" 1 'web-mode-function-call-face)
  1674. '("[a-zA-Z]<\\([a-zA-Z]+\\)[,>]" 1 'web-mode-type-face)
  1675. ))
  1676. (defvar web-mode-stylus-font-lock-keywords
  1677. (list
  1678. '("^[ \t]*\\([[:alnum:]().-]+\\)$" 1 'web-mode-css-selector-face)
  1679. '("^[ \t]*\\([[:alnum:]-]+[ ]*:\\)" 1 'web-mode-css-property-name-face)
  1680. ))
  1681. (defvar web-mode-sass-font-lock-keywords
  1682. (list
  1683. '("^[ \t]*\\([[:alnum:]().-]+\\|&:\\(before\\|after\\)\\)$" 1 'web-mode-css-selector-face)
  1684. '("^[ \t]*\\([[:alnum:]-]+[ ]*:\\)" 1 'web-mode-css-property-name-face)
  1685. ))
  1686. (defvar web-mode-pug-font-lock-keywords
  1687. (list
  1688. '("#[[:alnum:]-]+" 0 'web-mode-css-selector-face)
  1689. '(" \\([@:]?\\sw+[ ]?=\\)" 1 'web-mode-param-name-face)
  1690. ))
  1691. (defvar web-mode-sql-font-lock-keywords
  1692. (list
  1693. (cons (concat "\\_<\\(" web-mode-sql-keywords "\\)\\_>") '(0 'web-mode-keyword-face))
  1694. '("\\_<\\([[:alnum:]_-]+\\)[ ]?(" 1 'web-mode-function-call-face)
  1695. ))
  1696. (defvar web-mode-markdown-font-lock-keywords
  1697. (list
  1698. '("^[ ]*[*].*$" 0 'web-mode-variable-name-face)
  1699. '("^[ ]*#.*$" 0 'web-mode-comment-face)
  1700. ))
  1701. (defvar web-mode-html-tag-font-lock-keywords
  1702. (list
  1703. '("\\(</?\\)\\([[:alnum:]]+\\)"
  1704. (1 'web-mode-html-tag-bracket-face)
  1705. (2 'web-mode-html-tag-face))
  1706. '("\"[^\"]*\"" 0 'web-mode-html-attr-value-face)
  1707. '("\\([[:alnum:]]+\\)" 1 'web-mode-html-attr-name-face)
  1708. '("/?>" 0 'web-mode-html-tag-bracket-face)
  1709. ))
  1710. (defvar web-mode-dust-font-lock-keywords
  1711. (list
  1712. '("{[#:/?@><+^]\\([[:alpha:]_.]+\\)" 1 'web-mode-block-control-face)
  1713. '(":\\([[:alpha:]]+\\)" 1 'web-mode-keyword-face)
  1714. '("\\_<\\([[:alnum:]_]+=\\)\\(\"[^\"]*\"\\|[[:alnum:]_]*\\)"
  1715. (1 'web-mode-block-attr-name-face)
  1716. (2 'web-mode-block-attr-value-face))
  1717. '("\\\([[:alnum:]_.]+\\)" 0 'web-mode-variable-name-face)
  1718. ))
  1719. (defvar web-mode-expressionengine-font-lock-keywords
  1720. (list
  1721. '("{/?\\([[:alpha:]_]+:[[:alpha:]_:]+\\|if\\)" 1 'web-mode-block-control-face)
  1722. '(":\\([[:alpha:]_]+\\)" 1 'web-mode-keyword-face)
  1723. '(" {\\([[:alpha:]_]+\\)}" 1 'web-mode-keyword-face t)
  1724. '("\\_<\\([[:alnum:]_]+=\\)\\(\"[^\"]*\"\\|[[:alnum:]_]*\\)"
  1725. (1 'web-mode-block-attr-name-face)
  1726. (2 'web-mode-block-attr-value-face))
  1727. '("\\\([[:alnum:]_.]+\\)" 0 'web-mode-variable-name-face)
  1728. ))
  1729. (defvar web-mode-svelte-font-lock-keywords
  1730. (list
  1731. (cons (concat "[ ]\\(" web-mode-svelte-keywords "\\)[ ]") '(1 'web-mode-keyword-face))
  1732. '("{[#:/@]\\([[:alpha:]_.]+\\)" 1 'web-mode-block-control-face)
  1733. '("\\_<\\([[:alnum:]_]+=\\)\\(\"[^\"]*\"\\|[[:alnum:]_]*\\)"
  1734. (1 'web-mode-block-attr-name-face)
  1735. (2 'web-mode-block-attr-value-face))
  1736. '("\\\([[:alnum:]_.]+\\)" 0 'web-mode-variable-name-face)
  1737. '("\\_<\\([$]\\)\\([[:alnum:]_]+\\)" (1 'web-mode-constant-face) (2 'web-mode-variable-name-face))
  1738. ))
  1739. (defvar web-mode-template-toolkit-font-lock-keywords
  1740. (list
  1741. (cons (concat "\\_<\\(" web-mode-template-toolkit-keywords "\\)\\_>") '(1 'web-mode-keyword-face))
  1742. '("\\\([[:alpha:]][[:alnum:]_]+\\)[ ]?(" 1 'web-mode-function-call-face)
  1743. '("\\\([[:alpha:]][[:alnum:]_]+\\)" 0 'web-mode-variable-name-face)
  1744. ))
  1745. (defvar web-mode-smarty-font-lock-keywords
  1746. (list
  1747. (cons (concat "[ ]\\(" web-mode-smarty-keywords "\\)[ ]") '(1 'web-mode-keyword-face))
  1748. '("{/?\\([[:alpha:]_]+\\)" 1 'web-mode-block-control-face)
  1749. '("\\([}{]\\)" 0 'web-mode-block-delimiter-face)
  1750. '("\\_<\\([$]\\)\\([[:alnum:]_]+\\)" (1 nil) (2 'web-mode-variable-name-face))
  1751. '("\\_<\\(\\sw+\\)[ ]?(" 1 'web-mode-function-call-face)
  1752. '(" \\(\\sw+[ ]?=\\)" 1 'web-mode-param-name-face)
  1753. '(" \\(\\sw+\\)[ }]" 1 'web-mode-param-name-face)
  1754. '("|\\([[:alnum:]_]+\\)" 1 'web-mode-function-call-face)
  1755. '("\\(->\\)\\(\\sw+\\)" (1 nil) (2 'web-mode-variable-name-face))
  1756. '("[.]\\([[:alnum:]_-]+\\)[ ]?(" 1 'web-mode-function-call-face)
  1757. '("[.]\\([[:alnum:]_]+\\)" 1 'web-mode-variable-name-face)
  1758. '("#\\([[:alnum:]_]+\\)#" 1 'web-mode-variable-name-face)
  1759. ))
  1760. (defvar web-mode-velocity-font-lock-keywords
  1761. (list
  1762. '("#{?\\([[:alpha:]_]+\\)\\_>" (1 'web-mode-block-control-face))
  1763. (cons (concat "\\_<\\(" web-mode-velocity-keywords "\\)\\_>") '(1 'web-mode-keyword-face t t))
  1764. '("#macro([ ]*\\([[:alpha:]]+\\)[ ]+" 1 'web-mode-function-name-face)
  1765. '("\\(def\\|define\\) \\([[:alnum:]_-]+\\)(" 2 'web-mode-function-name-face)
  1766. '("[.]\\([[:alnum:]_-]+\\)" 1 'web-mode-variable-name-face)
  1767. '("\\_<\\($[!]?[{]?\\)\\([[:alnum:]_-]+\\)[}]?" (1 nil) (2 'web-mode-variable-name-face))
  1768. ))
  1769. (defvar web-mode-mako-tag-font-lock-keywords
  1770. (list
  1771. '("</?%\\([[:alpha:]:]+\\)" 1 'web-mode-block-control-face)
  1772. '("\\_<\\([[:alpha:]]+=\\)\\(\"[^\"]*\"\\)"
  1773. (1 'web-mode-block-attr-name-face t t)
  1774. (2 'web-mode-block-attr-value-face t t))
  1775. ))
  1776. (defvar web-mode-mako-block-font-lock-keywords
  1777. (list
  1778. '("\\_<\\(\\sw+\\)[ ]?(" 1 'web-mode-function-call-face)
  1779. (cons (concat "\\_<\\(" web-mode-python-constants "\\)\\_>") '(1 'web-mode-constant-face))
  1780. (cons (concat "\\_<\\(" web-mode-python-keywords "\\)\\_>") '(1 'web-mode-keyword-face))
  1781. (cons (concat "\\_<\\(endfor\\|endif\\|endwhile\\)\\_>") '(1 'web-mode-keyword-face))
  1782. ))
  1783. (defvar web-mode-web2py-font-lock-keywords
  1784. (list
  1785. '("\\_<\\(\\sw+\\)[ ]?(" 1 'web-mode-function-call-face)
  1786. (cons (concat "\\_<\\(" web-mode-python-constants "\\)\\_>") '(1 'web-mode-constant-face))
  1787. (cons (concat "\\_<\\(" web-mode-python-keywords "\\)\\_>") '(1 'web-mode-keyword-face))
  1788. (cons (concat "\\_<\\(block\\|extend\\|super\\|end\\|include\\)\\_>") '(1 'web-mode-keyword-face))
  1789. ))
  1790. (defvar web-mode-django-expr-font-lock-keywords
  1791. (list
  1792. '("|[ ]?\\([[:alpha:]_]+\\)\\_>" 1 'web-mode-filter-face)
  1793. (cons (concat "\\_<\\(" web-mode-django-types "\\)\\_>") '(1 'web-mode-type-face))
  1794. '("\\_<\\([[:alpha:]_]+\\)[ ]?(" 1 'web-mode-function-call-face)
  1795. '("[[:alnum:]_]+" 0 'web-mode-variable-name-face)
  1796. ))
  1797. (defvar web-mode-django-code-font-lock-keywords
  1798. (list
  1799. (cons (concat "{%[ ]*\\(" web-mode-django-control-blocks-regexp "\\)[ %]") '(1 'web-mode-block-control-face))
  1800. '("{%[ ]*\\(end[[:alpha:]]+\\)\\_>" 1 'web-mode-block-control-face) ;#504
  1801. (cons (concat "\\_<\\(" web-mode-django-keywords "\\)\\_>") '(1 'web-mode-keyword-face))
  1802. (cons (concat "\\_<\\(" web-mode-django-types "\\)\\_>") '(1 'web-mode-type-face))
  1803. '("|[ ]?\\([[:alpha:]_]+\\)\\_>" 1 'web-mode-function-call-face)
  1804. '("\\_<\\([[:alpha:]_]+\\)[ ]?(" 1 'web-mode-function-call-face)
  1805. '("[[:alnum:]_.]+" 0 'web-mode-variable-name-face)
  1806. '("[[:alnum:]_]+\\([.][[:alnum:]_]+\\)+" 0 'web-mode-variable-name-face t t)
  1807. ))
  1808. (defvar web-mode-ctemplate-font-lock-keywords
  1809. (list
  1810. '("{[~]?{[#/>^]?[ ]*\\([[:alnum:]_.-]+\\)" 1 'web-mode-block-control-face)
  1811. '("[ \t]+\\([[:alnum:]_-]+\\)="
  1812. (1 'web-mode-block-attr-name-face))
  1813. '("\"[^\"]+\"" 0 'web-mode-block-string-face)
  1814. ))
  1815. (defvar web-mode-razor-font-lock-keywords
  1816. (list
  1817. '("@\\([[:alnum:]_.]+\\)[ ]*[({]" 1 'web-mode-block-control-face)
  1818. (cons (concat "\\_<\\(" web-mode-razor-keywords "\\)\\_>") '(1 'web-mode-keyword-face))
  1819. '("\\_<\\(String\\)\\_>" 1 'web-mode-type-face)
  1820. '("\\([[:alnum:]]+:\\)" 1 'web-mode-symbol-face)
  1821. '("\\(@[[:alnum:]_.]+\\)" 1 'web-mode-variable-name-face)
  1822. ))
  1823. (defvar web-mode-riot-font-lock-keywords
  1824. (list
  1825. '("\\(parent\\|opts\\|tags\\|this\\)\\.\\([[:alnum:]_.]+\\)"
  1826. (1 'web-mode-constant-face)
  1827. (2 'web-mode-variable-name-face))
  1828. '("\\([[:alnum:]_.]+\\)" 0 'web-mode-variable-name-face)
  1829. ))
  1830. (defvar web-mode-closure-font-lock-keywords
  1831. (list
  1832. '("{\\([@/]?[[:alpha:]]+[?]?\\)" 1 'web-mode-block-control-face)
  1833. '("{[@]?param[?]?[ ]+\\([[:alnum:]]+[:]?\\)" 1 'web-mode-symbol-face)
  1834. '("\\_<\\(true\\|false\\|null\\)\\_>" 1 'web-mode-type-face)
  1835. '("\\\_<[[:alpha:]]+:[ ]+\\([[:alpha:]]+\\)" 1 'web-mode-type-face)
  1836. (cons (concat "\\_<\\(" web-mode-closure-keywords "\\)\\_>") '(1 'web-mode-keyword-face))
  1837. '("{\\(alias\\|call\\|delcall\\|delpackage\\|deltemplate\\|namespace\\|template\\)[ ]+\\([[:alnum:].]+\\)" 2 'web-mode-constant-face)
  1838. '("\\(allowemptydefault\\|data\\|desc\\|meaning\\|autoescape\\|private\\|variant\\)=" 0 'web-mode-block-attr-name-face)
  1839. '("|\\([[:alpha:]]+\\)" 1 'web-mode-function-call-face)
  1840. '("\\_<\\([[:alnum:]]+\\)[ ]?(" 1 'web-mode-function-call-face)
  1841. '("$\\([[:alnum:]._]+\\)" 1 'web-mode-variable-name-face)
  1842. ))
  1843. (defvar web-mode-go-font-lock-keywords
  1844. (list
  1845. '("{{[-]?[ ]*\\([[:alpha:]]+\\)" 1 'web-mode-block-control-face)
  1846. '("\\_<func \\([[:alnum:]]+\\)" 1 'web-mode-function-name-face)
  1847. '("\\_<type \\([[:alnum:]]+\\)" 1 'web-mode-type-face)
  1848. (cons (concat "\\_<\\(" web-mode-go-types "\\)\\_>") '(0 'web-mode-type-face))
  1849. (cons (concat "\\_<\\(" web-mode-go-keywords "\\)\\_>") '(1 'web-mode-keyword-face))
  1850. (cons (concat "\\_<\\(" web-mode-go-functions "\\)\\_>") '(1 'web-mode-function-call-face))
  1851. '("[$.]\\([[:alnum:]_]+\\)" 1 'web-mode-variable-name-face t t)
  1852. '("|[ ]?\\([[:alpha:]_]+\\)\\_>" 1 'web-mode-filter-face)
  1853. ))
  1854. (defvar web-mode-expression-font-lock-keywords
  1855. (list
  1856. '("[[:alpha:]_]" 0 'web-mode-variable-name-face)
  1857. ))
  1858. (defvar web-mode-angular-font-lock-keywords
  1859. (list
  1860. '("[[:alpha:]_]" 0 'web-mode-variable-name-face)
  1861. ))
  1862. (defvar web-mode-underscore-font-lock-keywords
  1863. (list
  1864. (cons (concat "\\_<\\(" web-mode-javascript-keywords "\\)\\_>") '(0 'web-mode-keyword-face))
  1865. '("\\_<\\(_\.[[:alpha:]]+\\)(" 1 'web-mode-function-call-face)
  1866. '("\\_<new \\([[:alnum:]_.]+\\)\\_>" 1 'web-mode-type-face)
  1867. '("\\_<\\([[:alnum:]_]+\\):[ ]*function[ ]*(" 1 'web-mode-function-name-face)
  1868. '("\\_<\\(var\\)\\_>[ ]+\\([[:alnum:]_]+\\)"
  1869. (1 'web-mode-keyword-face)
  1870. (2 'web-mode-variable-name-face))
  1871. ))
  1872. (defvar web-mode-vue-font-lock-keywords
  1873. (list
  1874. '("\\_<\\([[:alnum:]_-]+\\)[ ]?(" 1 'web-mode-function-call-face)
  1875. '("[[:alpha:]_]" 0 'web-mode-variable-name-face)
  1876. ))
  1877. (defvar web-mode-engine-tag-font-lock-keywords
  1878. (list
  1879. '("</?\\([[:alpha:]]+\\(?:Template\\|[:.][[:alpha:]-]+\\)\\)" 1 'web-mode-block-control-face)
  1880. '("\\_<\\([[:alpha:]-]+=\\)\\(\"[^\"]*\"\\)"
  1881. (1 'web-mode-block-attr-name-face t t)
  1882. (2 'web-mode-block-attr-value-face t t))
  1883. '("\\_<\\([[:alpha:]-]+=\\)\\('[^']*\'\\)"
  1884. (1 'web-mode-block-attr-name-face t t)
  1885. (2 'web-mode-block-attr-value-face t t))
  1886. ))
  1887. (defvar web-mode-jsp-font-lock-keywords
  1888. (list
  1889. '("\\(throws\\|new\\|extends\\)[ ]+\\([[:alnum:].]+\\)" 2 'web-mode-type-face)
  1890. (cons (concat "\\_<\\(" web-mode-jsp-keywords "\\)\\_>") '(0 'web-mode-keyword-face))
  1891. '("\\(public\\|private\\)[ ]+\\([[:alpha:]]+\\)[ ]+\\([[:alnum:]._]+\\)[ ]?("
  1892. (2 'web-mode-type-face)
  1893. (3 'web-mode-function-name-face))
  1894. '("\\_<\\([[:alnum:]._]+\\)[ ]?(" 1 'web-mode-function-call-face)
  1895. '("@\\(\\sw*\\)" 1 'web-mode-variable-name-face)
  1896. '("\\_<\\([[:alnum:].]+\\)[ ]+[{[:alpha:]]+" 1 'web-mode-type-face)
  1897. ))
  1898. (defvar web-mode-asp-font-lock-keywords
  1899. (list
  1900. (cons (concat "\\_<\\(" web-mode-asp-keywords "\\)\\_>") '(0 'web-mode-keyword-face))
  1901. (cons (concat "\\_<\\(" web-mode-asp-types "\\)\\_>") '(0 'web-mode-type-face))
  1902. (cons (concat "\\_<\\(" web-mode-asp-constants "\\)\\_>") '(0 'web-mode-constant-face))
  1903. '("\\(Class\\|new\\) \\([[:alnum:]_]+\\)" 2 'web-mode-type-face)
  1904. '("Const \\([[:alnum:]_]+\\)" 1 'web-mode-constant-face)
  1905. '("\\_<dim\\_>"
  1906. (0 'web-mode-keyword-face)
  1907. ("[[:alnum:]_]+" nil nil (0 'web-mode-variable-name-face)))
  1908. '("\\_<\\(public\\|private\\|sub\\|function\\)\\_> \\([[:alnum:]_]+\\)[ ]*(" 2 'web-mode-function-name-face)
  1909. '("\\_<\\(public\\|private\\|dim\\)\\_> \\([[:alnum:]_]+\\)" 2 'web-mode-variable-name-face)
  1910. ))
  1911. (defvar web-mode-aspx-font-lock-keywords
  1912. (list
  1913. (cons (concat "\\_<\\(" web-mode-aspx-keywords "\\)\\_>") '(0 'web-mode-keyword-face))
  1914. '("\\_<\\([[:alnum:].]+\\)[ ]+[[:alpha:]]+" 1 'web-mode-type-face)
  1915. ))
  1916. (defvar web-mode-uel-font-lock-keywords
  1917. (list
  1918. '("[$#{]{\\|}" 0 'web-mode-preprocessor-face)
  1919. '("\\([[:alpha:]_]+\\)[ ]?(" 1 'web-mode-function-call-face)
  1920. '("|[ ]*\\(trim\\|x\\|u\\)" 1 'web-mode-function-call-face)
  1921. '("[[:alpha:]_]" 0 'web-mode-variable-name-face)
  1922. ))
  1923. (defvar web-mode-php-var-interpolation-font-lock-keywords
  1924. (list
  1925. '("[[:alpha:]_]" 0 'web-mode-variable-name-face)
  1926. '("\".+\"\\|'.*'" 0 'web-mode-string-face)
  1927. ))
  1928. (defvar web-mode-marko-font-lock-keywords
  1929. (list
  1930. '("[[:alnum:]_]+" 0 'web-mode-variable-name-face)
  1931. ))
  1932. (defvar web-mode-freemarker-square-font-lock-keywords
  1933. (list
  1934. '("\\[/?[#@]\\([[:alpha:]_.]*\\)" 1 'web-mode-block-control-face)
  1935. '("#\\(macro\\|function\\) \\([[:alpha:]]+\\)" 2 'web-mode-function-name-face)
  1936. (cons (concat "\\_<\\(" web-mode-freemarker-keywords "\\)\\_>") '(1 'web-mode-keyword-face))
  1937. '("\\_<\\([[:alnum:]._]+\\)[ ]?(" 1 'web-mode-function-call-face)
  1938. '("[[:alpha:]]\\([[:alnum:]_]+\\)?" 0 'web-mode-variable-name-face)
  1939. ))
  1940. (defvar web-mode-freemarker-font-lock-keywords
  1941. (list
  1942. '("</?[#@]\\([[:alpha:]_.]*\\)" 1 'web-mode-block-control-face)
  1943. '("#\\(macro\\|function\\) \\([[:alpha:]]+\\)" 2 'web-mode-function-name-face)
  1944. (cons (concat "\\_<\\(" web-mode-freemarker-keywords "\\)\\_>") '(1 'web-mode-keyword-face))
  1945. '("\\_<\\([[:alnum:]._]+\\)[ ]?(" 1 'web-mode-function-call-face)
  1946. '("[[:alpha:]]\\([[:alnum:]_]+\\)?" 0 'web-mode-variable-name-face)
  1947. ))
  1948. (defvar web-mode-directive-font-lock-keywords
  1949. (list
  1950. '("<%@[ ]*\\([[:alpha:]]+\\)[ ]+" 1 'web-mode-block-control-face)
  1951. '("\\_<\\([[:alpha:]]+=\\)\\(\"[^\"]*\"\\)"
  1952. (1 'web-mode-block-attr-name-face t t)
  1953. (2 'web-mode-block-attr-value-face t t))
  1954. ))
  1955. (defvar web-mode-erb-font-lock-keywords
  1956. (list
  1957. '("[^:]\\(:[[:alnum:]_]+\\)" 1 'web-mode-symbol-face)
  1958. '("\\([[:alnum:]_]+:\\)[ ]+" 1 'web-mode-symbol-face)
  1959. (cons (concat "\\_<\\(" web-mode-erb-builtins "\\)\\_>") '(0 'web-mode-builtin-face))
  1960. (cons (concat "\\_<\\(" web-mode-erb-keywords "\\)\\_>") '(0 'web-mode-keyword-face))
  1961. '("\\_<\\(self\\|true\\|false\\|nil\\)\\_>" 0 'web-mode-variable-name-face)
  1962. '("[@$]@?\\([[:alnum:]_]+\\)" 0 'web-mode-variable-name-face)
  1963. '("class[ ]+\\([[:alnum:]_]+\\)" 1 'web-mode-type-face)
  1964. '("def[ ]+\\([[:alnum:]_]+\\)" 1 'web-mode-function-name-face)
  1965. '("\\(?:\\_<\\|::\\)\\([A-Z]+[[:alnum:]_]+\\)" 1 (unless (eq (char-after) ?\() 'web-mode-type-face))
  1966. '("/[^/]+/" 0 'web-mode-string-face)
  1967. ))
  1968. (defvar web-mode-ejs-font-lock-keywords
  1969. web-mode-javascript-font-lock-keywords)
  1970. (defvar web-mode-python-font-lock-keywords
  1971. (list
  1972. (cons (concat "\\_<\\(" web-mode-python-keywords "\\)\\_>") '(0 'web-mode-keyword-face))
  1973. ))
  1974. (defvar web-mode-erlang-font-lock-keywords
  1975. (list
  1976. (cons (concat "\\_<\\(" web-mode-erlang-keywords "\\)\\_>") '(0 'web-mode-keyword-face))
  1977. (cons (concat "\\_<\\(" web-mode-erlang-constants "\\)\\_>") '(0 'web-mode-constant-face))
  1978. '("@\\([[:alnum:]_]+\\)" 0 'web-mode-variable-name-face)
  1979. '("[ ]\\(:[[:alnum:]-_]+\\)" 1 'web-mode-symbol-face)
  1980. ))
  1981. (defvar web-mode-mason-code-font-lock-keywords
  1982. (list
  1983. (cons (concat "\\_<\\(" web-mode-mason-keywords "\\)\\_>") '(0 'web-mode-keyword-face))
  1984. '("sub[ ]+\\([[:alnum:]_]+\\)" 1 'web-mode-function-name-face)
  1985. '("\\_<\\([[:alnum:]_]+\\)[ ]?::" 1 'web-mode-type-face)
  1986. '("\\([@]\\)\\([[:alnum:]#_]*\\)" (1 nil) (2 'web-mode-variable-name-face))
  1987. '("\\_<\\([$%]\\)\\([[:alnum:]@#_]*\\)" (1 nil) (2 'web-mode-variable-name-face))
  1988. '("{\\([[:alnum:]_]+\\)}" 1 'web-mode-variable-name-face)
  1989. '("\\_<\\(\\sw+\\)[ ]?(" 1 'web-mode-function-call-face)
  1990. '("[[:alnum:]_][ ]?::[ ]?\\([[:alnum:]_]+\\)" 1 'web-mode-variable-name-face)
  1991. '("->[ ]?\\([[:alnum:]_]+\\)" 1 'web-mode-variable-name-face)
  1992. '("\\(?:method\\|def\\) \\([[:alnum:]._]+\\)" 1 'web-mode-function-name-face)
  1993. '("|[ ]*\\([[:alnum:],]+\\)[ ]*%>" 1 'web-mode-filter-face)
  1994. ))
  1995. (defvar web-mode-mason-block-font-lock-keywords
  1996. (list
  1997. '("<[/]?%\\([[:alpha:]]+\\)" 1 'web-mode-block-control-face)
  1998. '("[[:alpha:]]" 0 'web-mode-block-attr-value-face)
  1999. ))
  2000. (defvar web-mode-mojolicious-font-lock-keywords
  2001. (list
  2002. (cons (concat "\\_<\\(" web-mode-perl-keywords "\\)\\_>") '(0 'web-mode-keyword-face))
  2003. '("\\_<\\(begin\\|end\\)\\_>" 1 'web-mode-constant-face)
  2004. '("\\_<\\([$]\\)\\([[:alnum:]_]*\\)" (1 nil) (2 'web-mode-variable-name-face))
  2005. ))
  2006. (defvar web-mode-lsp-font-lock-keywords
  2007. (list
  2008. (cons (concat "\\_<\\(" web-mode-lsp-keywords "\\)\\_>") '(0 'web-mode-keyword-face))
  2009. (cons (concat "\\_<\\(" web-mode-lsp-constants "\\)\\_>") '(1 'web-mode-constant-face))
  2010. '("[ ]\\(:[[:alnum:]-_]+\\)" 1 'web-mode-symbol-face)
  2011. '("(defun \\([[:alnum:]-:]+\\)" 1 'web-mode-function-name-face)
  2012. '("(defvar \\([[:alnum:]-:]+\\)" 1 'web-mode-variable-name-face)
  2013. ))
  2014. (defvar web-mode-cl-emb-font-lock-keywords
  2015. (list
  2016. (cons (concat "\\_<\\(" web-mode-cl-emb-keywords "\\)\\_>") '(0 'web-mode-keyword-face))
  2017. (cons (concat "\\_<\\(" web-mode-cl-emb-constants "\\)\\_>") '(0 'web-mode-constant-face))
  2018. '("\\(@\\)" 1 'web-mode-function-call-face)
  2019. (list (concat "\\(@" web-mode-cl-emb-keywords "\\)[ ]+\\([[:alnum:]_]+\\)")
  2020. '(1 'web-mode-keyword-face)
  2021. '(2 'web-mode-variable-name-face))
  2022. ))
  2023. (defvar web-mode-artanis-font-lock-keywords
  2024. (list
  2025. (cons (concat "\\_<\\(" web-mode-artanis-keywords "\\)\\_>") '(0 'web-mode-keyword-face))
  2026. (cons (concat "\\_<\\(" web-mode-artanis-constants "\\)\\_>") '(0 'web-mode-constant-face))
  2027. '("(define[*]? (\\([[:alnum:]-:_!#$%^&*=+/?<>.]+\\)" 1 'web-mode-function-name-face)
  2028. '("\\(#:[[:alnum:]-:_!#$%^&*=+/?<>.]+\\)" 1 'web-mode-builtin-face)
  2029. ))
  2030. (defvar web-mode-php-font-lock-keywords
  2031. (list
  2032. (cons (concat "\\_<\\(" web-mode-php-keywords "\\)\\_>") '(0 'web-mode-keyword-face))
  2033. (cons (concat "(\\_<\\(" web-mode-php-types "\\)\\_>") '(1 'web-mode-type-face))
  2034. (cons (concat "\\_<\\(" web-mode-php-constants "\\)\\_>") '(0 'web-mode-constant-face))
  2035. '("function[ ]+\\([[:alnum:]_]+\\)" 1 'web-mode-function-name-face)
  2036. '("\\_<\\([[:alnum:]_]+\\)[ ]?(" 1 'web-mode-function-call-face)
  2037. '("[[:alnum:]_][ ]?::[ ]?\\([[:alnum:]_]+\\)" 1 'web-mode-constant-face)
  2038. '("->[ ]?\\([[:alnum:]_]+\\)" 1 'web-mode-variable-name-face)
  2039. '("\\_<\\([[:alnum:]_]+\\)[ ]?::" 1 'web-mode-type-face)
  2040. '("\\_<\\(instanceof\\|class\\|extends\\|new\\)[ ]+\\([[:alnum:]_]+\\)" 2 'web-mode-type-face)
  2041. '("\\(\\_<\\|[+-]\\)\\([$]\\)\\([[:alnum:]_]*\\)" (2 nil) (3 'web-mode-variable-name-face))
  2042. ))
  2043. (defvar web-mode-spip-font-lock-keywords
  2044. (list
  2045. '("<:.+:>" 0 'web-mode-block-string-face)
  2046. '("#[A-Z0-9_]+" 0 'web-mode-variable-name-face)
  2047. '("|[a-z0-9_=!?<>]+" 0 'web-mode-function-call-face)
  2048. '("(\\([[:alnum:]_ ]+\\))" 1 'web-mode-constant-face)
  2049. ))
  2050. (defvar web-mode-latex-font-lock-keywords
  2051. (list
  2052. '("[[:alnum:]_]+" 0 'web-mode-function-name-face t t)
  2053. ))
  2054. (defvar web-mode-blade-font-lock-keywords
  2055. (append
  2056. (list
  2057. '("@\\([[:alpha:]_]+\\)" (1 'web-mode-block-control-face)))
  2058. web-mode-php-font-lock-keywords))
  2059. (defvar web-mode-engines-font-lock-keywords
  2060. '(("angular" . web-mode-angular-font-lock-keywords)
  2061. ("artanis" . web-mode-artanis-font-lock-keywords)
  2062. ("blade" . web-mode-blade-font-lock-keywords)
  2063. ("cl-emb" . web-mode-cl-emb-font-lock-keywords)
  2064. ("closure" . web-mode-closure-font-lock-keywords)
  2065. ("ctemplate" . web-mode-ctemplate-font-lock-keywords)
  2066. ("dust" . web-mode-dust-font-lock-keywords)
  2067. ("elixir" . web-mode-erlang-font-lock-keywords)
  2068. ("ejs" . web-mode-ejs-font-lock-keywords)
  2069. ("erb" . web-mode-erb-font-lock-keywords)
  2070. ("expressionengine" . web-mode-expressionengine-font-lock-keywords)
  2071. ("go" . web-mode-go-font-lock-keywords)
  2072. ("hero" . web-mode-go-font-lock-keywords)
  2073. ("lsp" . web-mode-lsp-font-lock-keywords)
  2074. ("marko" . web-mode-marko-font-lock-keywords)
  2075. ("mojolicious" . web-mode-mojolicious-font-lock-keywords)
  2076. ("php" . web-mode-php-font-lock-keywords)
  2077. ("python" . web-mode-python-font-lock-keywords)
  2078. ("razor" . web-mode-razor-font-lock-keywords)
  2079. ("riot" . web-mode-riot-font-lock-keywords)
  2080. ("smarty" . web-mode-smarty-font-lock-keywords)
  2081. ("spip" . web-mode-spip-font-lock-keywords)
  2082. ("template-toolkit" . web-mode-template-toolkit-font-lock-keywords)
  2083. ("underscore" . web-mode-underscore-font-lock-keywords)
  2084. ("web2py" . web-mode-web2py-font-lock-keywords)
  2085. ("velocity" . web-mode-velocity-font-lock-keywords)
  2086. ("vue" . web-mode-vue-font-lock-keywords)
  2087. ("xoops" . web-mode-smarty-font-lock-keywords)
  2088. ("svelte" . web-mode-svelte-font-lock-keywords)
  2089. )
  2090. "Engines font-lock keywords")
  2091. (defvar web-mode-prettify-symbols-alist
  2092. '(("=>" . 8658)
  2093. (">=" . 8805)
  2094. ("<=" . 8804)))
  2095. (defvar web-mode-before-auto-complete-hooks nil
  2096. "List of functions to run before triggering the auto-complete library.
  2097. Auto-complete sources will sometimes need some tweaking to work
  2098. nicely with web-mode. This hook gives users the chance to adjust
  2099. the environment as needed for ac-sources, right before they're used.")
  2100. (defvar web-mode-ignore-ac-start-advice nil
  2101. "If not nil 'defadvice' for 'ac-start' will be ignored.
  2102. Can be set inside a hook in 'web-mode-before-auto-complete-hooks' to
  2103. non nil to ignore the defadvice which sets ac-sources according to current
  2104. language. This is needed if the corresponding auto-completion triggers
  2105. another auto-completion with different ac-sources (e.g. ac-php)")
  2106. (defvar web-mode-ac-sources-alist nil
  2107. "alist mapping language names to ac-sources for that language.")
  2108. (defvar web-mode-syntax-table
  2109. (let ((table (make-syntax-table)))
  2110. (modify-syntax-entry ?- "_" table)
  2111. (modify-syntax-entry ?_ "_" table) ;#563
  2112. (modify-syntax-entry ?< "." table)
  2113. (modify-syntax-entry ?> "." table)
  2114. (modify-syntax-entry ?& "." table)
  2115. (modify-syntax-entry ?/ "." table)
  2116. (modify-syntax-entry ?= "." table)
  2117. (modify-syntax-entry ?% "." table)
  2118. table)
  2119. "Syntax table used to reveal whitespaces.")
  2120. (defvar web-mode-map
  2121. (let ((map (make-sparse-keymap)))
  2122. (define-key map [menu-bar wm] (cons "Web-Mode" (make-sparse-keymap)))
  2123. (define-key map [menu-bar wm dom] (cons "Dom" (make-sparse-keymap)))
  2124. (define-key map [menu-bar wm blk] (cons "Block" (make-sparse-keymap)))
  2125. (define-key map [menu-bar wm attr] (cons "Html Attr" (make-sparse-keymap)))
  2126. (define-key map [menu-bar wm tag] (cons "Html Tag" (make-sparse-keymap)))
  2127. (define-key map [menu-bar wm elt] (cons "Html Element" (make-sparse-keymap)))
  2128. (define-key map [menu-bar wm sep-1] '(menu-item "--"))
  2129. (define-key map [menu-bar wm dom dom-xpa] '(menu-item "XPath" web-mode-dom-xpath))
  2130. (define-key map [menu-bar wm dom dom-tra] '(menu-item "Traverse" web-mode-dom-traverse))
  2131. (define-key map [menu-bar wm dom dom-err] '(menu-item "Show error(s)" web-mode-dom-errors-show))
  2132. (define-key map [menu-bar wm dom dom-ent] '(menu-item "Replace html entities" web-mode-dom-entities-replace))
  2133. (define-key map [menu-bar wm dom dom-quo] '(menu-item "Replace dumb quotes" web-mode-dom-quotes-replace))
  2134. (define-key map [menu-bar wm dom dom-apo] '(menu-item "Replace apostrophes" web-mode-dom-apostrophes-replace))
  2135. (define-key map [menu-bar wm dom dom-nor] '(menu-item "Normalize" web-mode-dom-normalize))
  2136. (define-key map [menu-bar wm blk blk-sel] '(menu-item "Select" web-mode-block-select))
  2137. (define-key map [menu-bar wm blk blk-pre] '(menu-item "Previous" web-mode-block-previous))
  2138. (define-key map [menu-bar wm blk blk-nex] '(menu-item "Next" web-mode-block-next))
  2139. (define-key map [menu-bar wm blk blk-kil] '(menu-item "Kill" web-mode-block-kill))
  2140. (define-key map [menu-bar wm blk blk-end] '(menu-item "End" web-mode-block-end))
  2141. (define-key map [menu-bar wm blk blk-clo] '(menu-item "Close" web-mode-block-close))
  2142. (define-key map [menu-bar wm blk blk-beg] '(menu-item "Beginning" web-mode-block-beginning))
  2143. (define-key map [menu-bar wm attr attr-ins] '(menu-item "Insert" web-mode-attribute-insert))
  2144. (define-key map [menu-bar wm attr attr-end] '(menu-item "End" web-mode-attribute-end))
  2145. (define-key map [menu-bar wm attr attr-beg] '(menu-item "Beginning" web-mode-attribute-beginning))
  2146. (define-key map [menu-bar wm attr attr-sel] '(menu-item "Select" web-mode-attribute-select))
  2147. (define-key map [menu-bar wm attr attr-kil] '(menu-item "Kill" web-mode-attribute-kill))
  2148. (define-key map [menu-bar wm attr attr-nex] '(menu-item "Next" web-mode-attribute-next))
  2149. (define-key map [menu-bar wm attr attr-pre] '(menu-item "Previous" web-mode-attribute-previous))
  2150. (define-key map [menu-bar wm attr attr-tra] '(menu-item "Transpose" web-mode-attribute-transpose))
  2151. (define-key map [menu-bar wm tag tag-beg] '(menu-item "Sort Attributes" web-mode-tag-attributes-sort))
  2152. (define-key map [menu-bar wm tag tag-sel] '(menu-item "Select" web-mode-tag-select))
  2153. (define-key map [menu-bar wm tag tag-pre] '(menu-item "Previous" web-mode-tag-previous))
  2154. (define-key map [menu-bar wm tag tag-nex] '(menu-item "Next" web-mode-tag-next))
  2155. (define-key map [menu-bar wm tag tag-end] '(menu-item "End" web-mode-tag-end))
  2156. (define-key map [menu-bar wm tag tag-beg] '(menu-item "Beginning" web-mode-tag-beginning))
  2157. (define-key map [menu-bar wm elt elt-con] '(menu-item "Contract" web-mode-element-contract))
  2158. (define-key map [menu-bar wm elt elt-ext] '(menu-item "Extract" web-mode-element-extract))
  2159. (define-key map [menu-bar wm elt elt-van] '(menu-item "Vanish" web-mode-element-vanish))
  2160. (define-key map [menu-bar wm elt elt-exc] '(menu-item "Transpose" web-mode-element-transpose))
  2161. (define-key map [menu-bar wm elt elt-sel] '(menu-item "Select" web-mode-element-select))
  2162. (define-key map [menu-bar wm elt elt-ren] '(menu-item "Rename" web-mode-element-rename))
  2163. (define-key map [menu-bar wm elt elt-pre] '(menu-item "Previous" web-mode-element-previous))
  2164. (define-key map [menu-bar wm elt elt-par] '(menu-item "Parent" web-mode-element-parent))
  2165. (define-key map [menu-bar wm elt elt-nex] '(menu-item "Next" web-mode-element-next))
  2166. (define-key map [menu-bar wm elt elt-mut] '(menu-item "Mute blanks" web-mode-element-mute-blanks))
  2167. (define-key map [menu-bar wm elt elt-del] '(menu-item "Kill" web-mode-element-kill))
  2168. (define-key map [menu-bar wm elt elt-end] '(menu-item "End" web-mode-element-end))
  2169. (define-key map [menu-bar wm elt elt-inn] '(menu-item "Content (select)" web-mode-element-content-select))
  2170. (define-key map [menu-bar wm elt elt-clo] '(menu-item "Close" web-mode-element-close))
  2171. (define-key map [menu-bar wm elt elt-ins] '(menu-item "Insert" web-mode-element-insert))
  2172. (define-key map [menu-bar wm elt elt-ins] '(menu-item "Word to tag" web-mode-element-insert-at-point))
  2173. (define-key map [menu-bar wm elt elt-dup] '(menu-item "Clone" web-mode-element-clone))
  2174. (define-key map [menu-bar wm elt elt-cfo] '(menu-item "Children fold" web-mode-element-children-fold-or-unfold))
  2175. (define-key map [menu-bar wm elt elt-chi] '(menu-item "Child" web-mode-element-child))
  2176. (define-key map [menu-bar wm elt elt-beg] '(menu-item "Beginning" web-mode-element-beginning))
  2177. (define-key map [menu-bar wm fol] '(menu-item "Fold/Unfold" web-mode-fold-or-unfold))
  2178. (define-key map [menu-bar wm hig] '(menu-item "Fontify buffer" web-mode-buffer-fontify))
  2179. (define-key map [menu-bar wm ind] '(menu-item "Indent buffer" web-mode-buffer-indent))
  2180. (define-key map [menu-bar wm nav] '(menu-item "Tag/Block navigation" web-mode-navigate))
  2181. (define-key map [menu-bar wm exp] '(menu-item "Mark and Expand" web-mode-mark-and-expand))
  2182. (define-key map [menu-bar wm spa] '(menu-item "Toggle whitespaces" web-mode-whitespaces-show))
  2183. (define-key map [menu-bar wm sni] '(menu-item "Insert snippet" web-mode-snippet-insert))
  2184. ;;--------------------------------------------------------------------------
  2185. ;; "C-c <LETTER>" are reserved for users
  2186. (define-key map (kbd "C-c C-a b") 'web-mode-attribute-beginning)
  2187. (define-key map (kbd "C-c C-a e") 'web-mode-attribute-end)
  2188. (define-key map (kbd "C-c C-a i") 'web-mode-attribute-insert)
  2189. (define-key map (kbd "C-c C-a n") 'web-mode-attribute-next)
  2190. (define-key map (kbd "C-c C-a s") 'web-mode-attribute-select)
  2191. (define-key map (kbd "C-c C-a k") 'web-mode-attribute-kill)
  2192. (define-key map (kbd "C-c C-a p") 'web-mode-attribute-previous)
  2193. (define-key map (kbd "C-c C-a t") 'web-mode-attribute-transpose)
  2194. (define-key map (kbd "C-c C-b b") 'web-mode-block-beginning)
  2195. (define-key map (kbd "C-c C-b c") 'web-mode-block-close)
  2196. (define-key map (kbd "C-c C-b e") 'web-mode-block-end)
  2197. (define-key map (kbd "C-c C-b k") 'web-mode-block-kill)
  2198. (define-key map (kbd "C-c C-b n") 'web-mode-block-next)
  2199. (define-key map (kbd "C-c C-b p") 'web-mode-block-previous)
  2200. (define-key map (kbd "C-c C-b s") 'web-mode-block-select)
  2201. (define-key map (kbd "C-c C-d a") 'web-mode-dom-apostrophes-replace)
  2202. (define-key map (kbd "C-c C-d d") 'web-mode-dom-errors-show)
  2203. (define-key map (kbd "C-c C-d e") 'web-mode-dom-entities-replace)
  2204. (define-key map (kbd "C-c C-d n") 'web-mode-dom-normalize)
  2205. (define-key map (kbd "C-c C-d q") 'web-mode-dom-quotes-replace)
  2206. (define-key map (kbd "C-c C-d t") 'web-mode-dom-traverse)
  2207. (define-key map (kbd "C-c C-d x") 'web-mode-dom-xpath)
  2208. (define-key map (kbd "C-c C-e /") 'web-mode-element-close)
  2209. (define-key map (kbd "C-c C-e a") 'web-mode-element-content-select)
  2210. (define-key map (kbd "C-c C-e b") 'web-mode-element-beginning)
  2211. (define-key map (kbd "C-c C-e c") 'web-mode-element-clone)
  2212. (define-key map (kbd "C-c C-e d") 'web-mode-element-child)
  2213. (define-key map (kbd "C-c C-e e") 'web-mode-element-end)
  2214. (define-key map (kbd "C-c C-e f") 'web-mode-element-children-fold-or-unfold)
  2215. (define-key map (kbd "C-c C-e i") 'web-mode-element-insert)
  2216. (define-key map (kbd "C-c C-e I") 'web-mode-element-insert-at-point)
  2217. (define-key map (kbd "C-c C-e k") 'web-mode-element-kill)
  2218. (define-key map (kbd "C-c C-e m") 'web-mode-element-mute-blanks)
  2219. (define-key map (kbd "C-c C-e n") 'web-mode-element-next)
  2220. (define-key map (kbd "C-c C-e p") 'web-mode-element-previous)
  2221. (define-key map (kbd "C-c C-e r") 'web-mode-element-rename)
  2222. (define-key map (kbd "C-c C-e s") 'web-mode-element-select)
  2223. (define-key map (kbd "C-c C-e t") 'web-mode-element-transpose)
  2224. (define-key map (kbd "C-c C-e u") 'web-mode-element-parent)
  2225. (define-key map (kbd "C-c C-e v") 'web-mode-element-vanish)
  2226. (define-key map (kbd "C-c C-e w") 'web-mode-element-wrap)
  2227. (define-key map (kbd "C-c C-e +") 'web-mode-element-extract)
  2228. (define-key map (kbd "C-c C-e -") 'web-mode-element-contract)
  2229. (define-key map (kbd "C-c C-t a") 'web-mode-tag-attributes-sort)
  2230. (define-key map (kbd "C-c C-t b") 'web-mode-tag-beginning)
  2231. (define-key map (kbd "C-c C-t e") 'web-mode-tag-end)
  2232. (define-key map (kbd "C-c C-t m") 'web-mode-tag-match)
  2233. (define-key map (kbd "C-c C-t n") 'web-mode-tag-next)
  2234. (define-key map (kbd "C-c C-t p") 'web-mode-tag-previous)
  2235. (define-key map (kbd "C-c C-t s") 'web-mode-tag-select)
  2236. ;;--------------------------------------------------------------------------
  2237. ;;(define-key map (kbd "M-q") 'fill-paragraph)
  2238. (define-key map (kbd "M-;") 'web-mode-comment-or-uncomment)
  2239. ;;C-c C-a : attribute
  2240. ;;C-c C-b : block
  2241. ;;C-c C-d : dom
  2242. ;;C-c C-e : element
  2243. (define-key map (kbd "C-c C-f") 'web-mode-fold-or-unfold)
  2244. (define-key map (kbd "C-c C-h") 'web-mode-buffer-fontify)
  2245. (define-key map (kbd "C-c C-i") 'web-mode-buffer-indent)
  2246. (define-key map (kbd "C-c C-j") 'web-mode-jshint)
  2247. (define-key map (kbd "C-c C-l") 'web-mode-file-link)
  2248. (define-key map (kbd "C-c C-m") 'web-mode-mark-and-expand)
  2249. (define-key map (kbd "C-c C-n") 'web-mode-navigate)
  2250. (define-key map (kbd "C-c C-r") 'web-mode-reload)
  2251. (define-key map (kbd "C-c C-s") 'web-mode-snippet-insert)
  2252. ;;C-c C-t : tag
  2253. (define-key map (kbd "C-c C-w") 'web-mode-whitespaces-show)
  2254. map)
  2255. "Keymap for `web-mode'.")
  2256. ;;---- COMPATIBILITY -----------------------------------------------------------
  2257. (eval-and-compile
  2258. ;; compatibility with emacs < 23
  2259. (defun web-mode-string-match-p (regexp string &optional start)
  2260. "Same as `string-match' except it does not change the match data."
  2261. (let ((inhibit-changing-match-data t))
  2262. (string-match regexp string start)))
  2263. (unless (fboundp 'string-match-p)
  2264. (fset 'string-match-p (symbol-function 'web-mode-string-match-p)))
  2265. ;; compatibility with emacs < 23.3
  2266. (if (fboundp 'with-silent-modifications)
  2267. (defalias 'web-mode-with-silent-modifications 'with-silent-modifications)
  2268. (defmacro web-mode-with-silent-modifications (&rest body)
  2269. `(let ((old-modified-p (buffer-modified-p))
  2270. (inhibit-modification-hooks t)
  2271. (buffer-undo-list t))
  2272. (unwind-protect
  2273. ,@body
  2274. (set-buffer-modified-p old-modified-p)))))
  2275. ;; compatibility with emacs < 24.3
  2276. (defun web-mode-buffer-narrowed-p ()
  2277. (if (fboundp 'buffer-narrowed-p)
  2278. (buffer-narrowed-p)
  2279. (/= (- (point-max) (point-min)) (buffer-size))))
  2280. ;; compatibility with emacs < 24
  2281. (defalias 'web-mode-prog-mode
  2282. (if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode))
  2283. ;; compatibility with emacs < 24.3
  2284. (unless (fboundp 'setq-local)
  2285. (defmacro setq-local (var val)
  2286. `(set (make-local-variable ',var) ,val)))
  2287. ;; compatability with emacs < 24.4
  2288. (defun web-mode-string-suffix-p (suffix string)
  2289. "Return t if STRING ends with SUFFIX."
  2290. (and (string-match (rx-to-string `(: ,suffix eos) t)
  2291. string)
  2292. t))
  2293. (unless (fboundp 'string-suffix-p)
  2294. (fset 'string-suffix-p (symbol-function 'web-mode-string-suffix-p)))
  2295. (unless (fboundp 'seq-some)
  2296. (defun seq-some (pred seq)
  2297. (unless (null seq)
  2298. (or (funcall pred (car seq))
  2299. (seq-some pred (cdr seq))))))
  2300. ) ;eval-and-compile
  2301. ;;---- MAJOR MODE --------------------------------------------------------------
  2302. ;;;###autoload
  2303. (define-derived-mode web-mode web-mode-prog-mode "Web"
  2304. "Major mode for editing web templates."
  2305. (make-local-variable 'web-mode-attr-indent-offset)
  2306. (make-local-variable 'web-mode-attr-value-indent-offset)
  2307. (make-local-variable 'web-mode-auto-pairs)
  2308. (make-local-variable 'web-mode-block-regexp)
  2309. (make-local-variable 'web-mode-change-beg)
  2310. (make-local-variable 'web-mode-change-end)
  2311. (make-local-variable 'web-mode-code-indent-offset)
  2312. (make-local-variable 'web-mode-column-overlays)
  2313. (make-local-variable 'web-mode-comment-formats)
  2314. (make-local-variable 'web-mode-comment-style)
  2315. (make-local-variable 'web-mode-content-type)
  2316. (make-local-variable 'web-mode-css-indent-offset)
  2317. (make-local-variable 'web-mode-display-table)
  2318. (make-local-variable 'web-mode-django-control-blocks)
  2319. (make-local-variable 'web-mode-django-control-blocks-regexp)
  2320. (make-local-variable 'web-mode-enable-block-face)
  2321. (make-local-variable 'web-mode-enable-inlays)
  2322. (make-local-variable 'web-mode-enable-part-face)
  2323. (make-local-variable 'web-mode-enable-sexp-functions)
  2324. (make-local-variable 'web-mode-engine)
  2325. (make-local-variable 'web-mode-engine-attr-regexp)
  2326. (make-local-variable 'web-mode-engine-file-regexps)
  2327. (make-local-variable 'web-mode-engine-open-delimiter-regexps)
  2328. (make-local-variable 'web-mode-engine-token-regexp)
  2329. (make-local-variable 'web-mode-expand-initial-pos)
  2330. (make-local-variable 'web-mode-expand-initial-scroll)
  2331. (make-local-variable 'web-mode-expand-previous-state)
  2332. (make-local-variable 'web-mode-indent-style)
  2333. (make-local-variable 'web-mode-indentless-attributes)
  2334. (make-local-variable 'web-mode-indentless-elements)
  2335. (make-local-variable 'web-mode-is-scratch)
  2336. (make-local-variable 'web-mode-fontification-off)
  2337. (make-local-variable 'web-mode-jshint-errors)
  2338. (make-local-variable 'web-mode-last-enabled-feature)
  2339. (make-local-variable 'web-mode-markup-indent-offset)
  2340. (make-local-variable 'web-mode-minor-engine)
  2341. (make-local-variable 'web-mode-overlay-tag-end)
  2342. (make-local-variable 'web-mode-overlay-tag-start)
  2343. (make-local-variable 'web-mode-part-beg)
  2344. (make-local-variable 'web-mode-scan-beg)
  2345. (make-local-variable 'web-mode-scan-end)
  2346. (make-local-variable 'web-mode-sql-indent-offset)
  2347. (make-local-variable 'web-mode-time)
  2348. ;;(make-local-variable 'font-lock-beg)
  2349. ;;(make-local-variable 'font-lock-end)
  2350. (make-local-variable 'comment-end)
  2351. (make-local-variable 'comment-region-function)
  2352. (make-local-variable 'comment-start)
  2353. (make-local-variable 'fill-paragraph-function)
  2354. (make-local-variable 'font-lock-defaults)
  2355. (make-local-variable 'font-lock-extend-region-functions)
  2356. (make-local-variable 'font-lock-support-mode)
  2357. (make-local-variable 'font-lock-unfontify-region-function)
  2358. (make-local-variable 'imenu-case-fold-search)
  2359. (make-local-variable 'imenu-create-index-function)
  2360. (make-local-variable 'imenu-generic-expression)
  2361. (make-local-variable 'indent-line-function)
  2362. (make-local-variable 'parse-sexp-lookup-properties)
  2363. (make-local-variable 'uncomment-region-function)
  2364. (make-local-variable 'yank-excluded-properties)
  2365. (setq web-mode-time (current-time))
  2366. (setq comment-end "-->"
  2367. comment-region-function 'web-mode-comment-or-uncomment-region
  2368. comment-start "<!--"
  2369. fill-paragraph-function 'web-mode-fill-paragraph
  2370. ;;font-lock-defaults '(web-mode-font-lock-keywords t)
  2371. font-lock-defaults '('(web-mode-fontify) t)
  2372. font-lock-extend-region-functions '(web-mode-extend-region)
  2373. font-lock-support-mode nil
  2374. font-lock-unfontify-region-function 'web-mode-unfontify-region
  2375. imenu-case-fold-search t
  2376. imenu-create-index-function 'web-mode-imenu-index
  2377. indent-line-function 'web-mode-indent-line
  2378. parse-sexp-lookup-properties t
  2379. yank-excluded-properties t
  2380. uncomment-region-function 'web-mode-comment-or-uncomment-region
  2381. prettify-symbols-alist web-mode-prettify-symbols-alist)
  2382. (substitute-key-definition 'indent-new-comment-line
  2383. 'web-mode-comment-indent-new-line
  2384. web-mode-map global-map)
  2385. (add-hook 'after-change-functions 'web-mode-on-after-change nil t)
  2386. (add-hook 'after-save-hook 'web-mode-on-after-save t t)
  2387. (add-hook 'change-major-mode-hook 'web-mode-on-exit nil t)
  2388. (add-hook 'post-command-hook 'web-mode-on-post-command nil t)
  2389. (cond
  2390. ((boundp 'yas-after-exit-snippet-hook)
  2391. (add-hook 'yas-after-exit-snippet-hook
  2392. 'web-mode-yasnippet-exit-hook
  2393. t t))
  2394. ((boundp 'yas/after-exit-snippet-hook)
  2395. (add-hook 'yas/after-exit-snippet-hook
  2396. 'web-mode-yasnippet-exit-hook
  2397. t t))
  2398. )
  2399. (when web-mode-enable-whitespace-fontification
  2400. (web-mode-whitespaces-on))
  2401. (when web-mode-enable-sexp-functions
  2402. (setq-local forward-sexp-function 'web-mode-forward-sexp))
  2403. (web-mode-guess-engine-and-content-type)
  2404. (setq web-mode-change-beg (point-min)
  2405. web-mode-change-end (point-max))
  2406. (when (> (point-max) 256000)
  2407. (web-mode-buffer-fontify))
  2408. (when (and (boundp 'hs-special-modes-alist)
  2409. (not (assoc major-mode hs-special-modes-alist)))
  2410. (add-to-list 'hs-special-modes-alist '(web-mode "{" "}" "/[*/]" web-mode-forward-sexp nil))
  2411. ) ;when
  2412. ;; compatibility with emacs < 24
  2413. (if (fboundp 'prog-mode)
  2414. (put 'web-mode 'derived-mode-parent 'prog-mode))
  2415. (cond
  2416. ((not (buffer-file-name))
  2417. )
  2418. ((string-match-p "web-mode-benchmark.html" (buffer-file-name))
  2419. (web-mode-trace "end"))
  2420. ) ;cond
  2421. )
  2422. ;;---- INVALIDATION ------------------------------------------------------------
  2423. (defun web-mode-scan (&optional beg end)
  2424. (unless beg (setq beg web-mode-change-beg))
  2425. (unless end (setq end web-mode-change-end))
  2426. ;;(message "%S %S" web-mode-content-type (get-text-property beg 'part-side))
  2427. ;;(message "propertize: beg(%S) end(%S)" web-mode-change-beg web-mode-change-end)
  2428. ;;(message "%S %S" (get-text-property beg 'part-side) (get-text-property end 'part-side))
  2429. (when (and end (> end (point-max)))
  2430. (setq end (point-max)))
  2431. (setq web-mode-change-beg nil
  2432. web-mode-change-end nil)
  2433. (cond
  2434. ((or (null beg) (null end))
  2435. nil)
  2436. ((and (member web-mode-engine '("php" "asp"))
  2437. (get-text-property beg 'block-side)
  2438. (get-text-property end 'block-side)
  2439. (> beg (point-min))
  2440. (not (eq (get-text-property (1- beg) 'block-token) 'delimiter-beg))
  2441. (not (eq (get-text-property end 'block-token) 'delimiter-end)))
  2442. ;;(message "invalidate block (%S > %S)" beg end)
  2443. (web-mode-invalidate-block-region beg end))
  2444. ((and (or (member web-mode-content-type
  2445. '("css" "javascript" "json" "jsx" "sass" "stylus"
  2446. "typescript"))
  2447. (and (get-text-property beg 'part-side)
  2448. (get-text-property end 'part-side)
  2449. (> beg (point-min))
  2450. (get-text-property (1- beg) 'part-side))
  2451. ))
  2452. ;;(message "invalidate part (%S > %S)" beg end)
  2453. (web-mode-invalidate-part-region beg end))
  2454. (t
  2455. ;;(message "invalidate default (%S > %S)" beg end)
  2456. (web-mode-invalidate-region beg end))
  2457. ) ;cond
  2458. )
  2459. (defun web-mode-invalidate-region (reg-beg reg-end)
  2460. ;;(message "%S | reg-beg(%S) reg-end(%S)" (point) reg-beg reg-end)
  2461. (setq reg-beg (web-mode-invalidate-region-beginning-position reg-beg)
  2462. reg-end (web-mode-invalidate-region-end-position reg-end))
  2463. ;;(message "invalidate-region: reg-beg(%S) reg-end(%S)" reg-beg reg-end)
  2464. (web-mode-scan-region reg-beg reg-end))
  2465. ;; NOTE: il est important d'identifier des caractères en fin de ligne
  2466. ;; web-mode-block-tokenize travaille en effet sur les fins de lignes pour
  2467. ;; les commentaires de type //
  2468. (defun web-mode-invalidate-block-region (pos-beg pos-end)
  2469. ;; (message "pos-beg(%S) pos-end(%S)" pos-beg pos-end)
  2470. (save-excursion
  2471. (let (beg end code-beg code-end)
  2472. ;;(message "invalidate-block-region: pos-beg(%S)=%S" pos-beg (get-text-property pos 'block-side))
  2473. ;;(message "code-beg(%S) code-end(%S) pos-beg(%S) pos-end(%S)" code-beg code-end pos-beg pos-end)
  2474. (cond
  2475. ((not (and (setq code-beg (web-mode-block-code-beginning-position pos-beg))
  2476. (setq code-end (web-mode-block-code-end-position pos-beg))
  2477. (>= pos-beg code-beg)
  2478. (<= pos-end code-end)
  2479. (> code-end code-beg)))
  2480. (web-mode-invalidate-region pos-beg pos-end))
  2481. ((member web-mode-engine '("asp"))
  2482. (goto-char pos-beg)
  2483. (forward-line -1)
  2484. (setq beg (line-beginning-position))
  2485. (when (> code-beg beg)
  2486. (setq beg code-beg))
  2487. (goto-char pos-beg)
  2488. (forward-line)
  2489. (setq end (line-end-position))
  2490. (when (< code-end end)
  2491. (setq end code-end))
  2492. ;; ?? pas de (web-mode-block-tokenize beg end) ?
  2493. (cons beg end)
  2494. ) ;asp
  2495. (t
  2496. (goto-char pos-beg)
  2497. (when (string= web-mode-engine "php")
  2498. (cond
  2499. ((and (looking-back "\*" (point-min))
  2500. (looking-at-p "/"))
  2501. (search-backward "/*" code-beg))
  2502. ) ;cond
  2503. )
  2504. (if (web-mode-block-rsb "[;{}(][ ]*\n" code-beg)
  2505. (setq beg (match-end 0))
  2506. (setq beg code-beg))
  2507. (goto-char pos-end)
  2508. (if (web-mode-block-rsf "[;{})][ ]*\n" code-end)
  2509. (setq end (1- (match-end 0)))
  2510. (setq end code-end))
  2511. (web-mode-block-tokenize beg end)
  2512. ;;(message "beg(%S) end(%S)" beg end)
  2513. (cons beg end)
  2514. )
  2515. ) ;cond
  2516. )))
  2517. (defun web-mode-invalidate-part-region (pos-beg pos-end)
  2518. (save-excursion
  2519. (let (beg end part-beg part-end language)
  2520. (if (member web-mode-content-type web-mode-part-content-types)
  2521. (setq language web-mode-content-type)
  2522. (setq language (symbol-name (get-text-property pos-beg 'part-side))))
  2523. (setq part-beg (web-mode-part-beginning-position pos-beg)
  2524. part-end (web-mode-part-end-position pos-beg))
  2525. ;;(message "language(%S) pos-beg(%S) pos-end(%S) part-beg(%S) part-end(%S)"
  2526. ;; language pos-beg pos-end part-beg part-end)
  2527. (goto-char pos-beg)
  2528. (cond
  2529. ((not (and part-beg part-end
  2530. (>= pos-beg part-beg)
  2531. (<= pos-end part-end)
  2532. (> part-end part-beg)))
  2533. (web-mode-invalidate-region pos-beg pos-end))
  2534. ((member language '("javascript" "json" "jsx" "typescript"))
  2535. (if (web-mode-javascript-rsb "[;{}(][ ]*\n" part-beg)
  2536. (setq beg (match-end 0))
  2537. (setq beg part-beg))
  2538. (goto-char pos-end)
  2539. (if (web-mode-javascript-rsf "[;{})][ ]*\n" part-end)
  2540. (setq end (match-end 0))
  2541. (setq end part-end))
  2542. (web-mode-scan-region beg end language))
  2543. ((member language '("css" "sass"))
  2544. (let (rule1 rule2)
  2545. (setq rule1 (web-mode-css-rule-current pos-beg))
  2546. (setq rule2 rule1)
  2547. (when (> pos-end (cdr rule1))
  2548. (setq rule2 (web-mode-css-rule-current pos-end)))
  2549. (setq beg (car rule1)
  2550. end (cdr rule2))
  2551. )
  2552. (web-mode-scan-region beg end language))
  2553. (t
  2554. (setq beg part-beg
  2555. end part-end)
  2556. (web-mode-scan-region beg end language))
  2557. ) ;cond
  2558. )))
  2559. (defun web-mode-invalidate-region-beginning-position (pos)
  2560. (save-excursion
  2561. (goto-char pos)
  2562. (when (and (bolp) (not (bobp)))
  2563. (backward-char))
  2564. (beginning-of-line)
  2565. ;;(message "pos=%S %S" (point) (text-properties-at (point)))
  2566. (setq pos (point-min))
  2567. (let ((continue (not (bobp))))
  2568. (while continue
  2569. (cond
  2570. ((bobp)
  2571. (setq continue nil))
  2572. ;; NOTE: Going back to the previous start tag is necessary
  2573. ;; when inserting a part endtag (e.g. </script>).
  2574. ;; Indeed, parts must be identified asap.
  2575. ((and (progn (back-to-indentation) t)
  2576. (get-text-property (point) 'tag-beg)
  2577. (eq (get-text-property (point) 'tag-type) 'start))
  2578. (setq pos (point)
  2579. continue nil))
  2580. (t
  2581. (forward-line -1))
  2582. ) ;cond
  2583. ) ;while
  2584. ;;(message "pos=%S" pos)
  2585. pos)))
  2586. (defun web-mode-invalidate-region-end-position (pos)
  2587. (save-excursion
  2588. (goto-char pos)
  2589. ;;(message "pos=%S %S" pos (get-text-property pos 'block-token))
  2590. (when (string= web-mode-engine "jsp")
  2591. (cond
  2592. ((and (looking-back "<%" (point-min))
  2593. (looking-at-p "--"))
  2594. (search-forward "--%>"))
  2595. ((and (looking-back "-- %" (point-min))
  2596. (looking-at-p ">"))
  2597. (search-forward "--%>"))
  2598. ) ;cond
  2599. ) ;when
  2600. (setq pos (point-max))
  2601. (let ((continue (not (eobp))))
  2602. (while continue
  2603. (end-of-line)
  2604. ;;(message "%S %S" (point) (get-text-property (point) 'block-token))
  2605. (cond
  2606. ((eobp)
  2607. (setq continue nil))
  2608. ((and (not (get-text-property (point) 'tag-type))
  2609. (not (get-text-property (point) 'part-side))
  2610. (not (get-text-property (point) 'block-side)))
  2611. (setq pos (point)
  2612. continue nil))
  2613. (t
  2614. (forward-line))
  2615. ) ;cond
  2616. ) ;while
  2617. pos)))
  2618. (defun web-mode-buffer-scan ()
  2619. "Scan entine buffer."
  2620. (interactive)
  2621. (web-mode-scan-region (point-min) (point-max)))
  2622. (defun web-mode-scan-region (beg end &optional content-type)
  2623. "Identify nodes/parts/blocks and syntactic symbols (strings/comments/etc.)."
  2624. ;;(message "scan-region: beg(%d) end(%d) content-type(%S)" beg end content-type)
  2625. (setq web-mode-scan-beg beg
  2626. web-mode-scan-end end)
  2627. (web-mode-with-silent-modifications
  2628. (save-excursion
  2629. (save-restriction
  2630. (save-match-data
  2631. (let ((inhibit-point-motion-hooks t)
  2632. (inhibit-quit t))
  2633. (remove-list-of-text-properties beg end web-mode-scan-properties)
  2634. (cond
  2635. ((and content-type (string= content-type "php"))
  2636. )
  2637. ((and content-type (member content-type web-mode-part-content-types))
  2638. (put-text-property beg end 'part-side
  2639. (cond
  2640. ((string= content-type "javascript") 'javascript)
  2641. ((string= content-type "json") 'json)
  2642. ((string= content-type "jsx") 'jsx)
  2643. ((string= content-type "css") 'css)
  2644. ((string= content-type "sql") 'sql)
  2645. ((string= content-type "pug") 'pug)
  2646. ((string= content-type "sass") 'sass)
  2647. ((string= content-type "stylus") 'stylus)
  2648. ((string= content-type "markdown") 'markdown)
  2649. ((string= content-type "ruby") 'ruby)
  2650. ((string= content-type "typescript") 'typescript)
  2651. ))
  2652. (web-mode-scan-blocks beg end)
  2653. (web-mode-part-scan beg end content-type))
  2654. ((member web-mode-content-type web-mode-part-content-types)
  2655. (web-mode-scan-blocks beg end)
  2656. (web-mode-part-scan beg end))
  2657. ((string= web-mode-engine "riot")
  2658. (web-mode-scan-elements beg end)
  2659. (web-mode-scan-blocks beg end)
  2660. (web-mode-part-foreach beg end 'web-mode-part-scan))
  2661. (t
  2662. (web-mode-scan-blocks beg end)
  2663. (web-mode-scan-elements beg end)
  2664. (web-mode-part-foreach beg end 'web-mode-part-scan))
  2665. ) ;cond
  2666. (cons beg end)
  2667. ))))))
  2668. ;;---- LEXER BLOCKS ------------------------------------------------------------
  2669. (defun web-mode-scan-blocks (reg-beg reg-end)
  2670. "Identifies blocks (with block-side, block-beg, block-end text properties)."
  2671. (save-excursion
  2672. (let ((i 0) open close closing-string start sub1 sub2 pos tagopen tmp delim-open delim-close part-beg part-end tagclose)
  2673. (goto-char reg-beg)
  2674. ;;(message "%S: %Sx%S" (point) reg-beg reg-end)
  2675. ;;(message "regexp=%S" web-mode-block-regexp)
  2676. (while (and (< i 2000)
  2677. (> reg-end (point))
  2678. web-mode-block-regexp
  2679. (re-search-forward web-mode-block-regexp reg-end t)
  2680. (not (eobp)))
  2681. (setq i (1+ i)
  2682. closing-string nil
  2683. close nil
  2684. tagopen (match-string 0)
  2685. open (match-beginning 0)
  2686. delim-open nil
  2687. delim-close nil
  2688. pos nil)
  2689. (let ((l (length tagopen)))
  2690. (when (member (string-to-char tagopen) '(?\s ?\t))
  2691. (setq tagopen (replace-regexp-in-string "\\`[ \t]*" "" tagopen))
  2692. (setq open (+ open (- l (length tagopen))))
  2693. (setq l (length tagopen))
  2694. )
  2695. (setq sub1 (substring tagopen 0 1)
  2696. sub2 (substring tagopen 0 (if (>= l 2) 2 1)))
  2697. )
  2698. ;;(message " found block #(%S) at pos=(%S), part-type=(%S)" i open (get-text-property open 'part-side))
  2699. (cond
  2700. ((string= web-mode-engine "php")
  2701. (unless (member (char-after) '(?x ?X))
  2702. (setq closing-string '("<\\?". "\\?>")))
  2703. (cond
  2704. ((looking-at-p "<?php")
  2705. (setq delim-open "<?php"))
  2706. ((eq (char-after) ?\=)
  2707. (setq delim-open "<?="))
  2708. (t
  2709. (setq delim-open "<?"))
  2710. ) ;cond
  2711. (setq delim-close "?>")
  2712. ) ;php
  2713. ((string= web-mode-engine "erb")
  2714. (cond
  2715. ((string= sub2 "<%")
  2716. (setq closing-string '("<%". "%>")
  2717. delim-open "<%[=-]?"
  2718. delim-close "[-]?%>"))
  2719. (t
  2720. (setq closing-string "EOL"
  2721. delim-open "%"))
  2722. )
  2723. ) ;erb
  2724. ((string= web-mode-engine "django")
  2725. (cond
  2726. ((string= sub2 "{{")
  2727. (setq closing-string "EODQ"
  2728. ;;(setq closing-string '("{{" . "}}")
  2729. delim-open "{{"
  2730. delim-close "}}"))
  2731. ((string= sub2 "{%")
  2732. (setq closing-string "%}"
  2733. delim-open "{%[+-]?"
  2734. delim-close "[-]?%}"))
  2735. (t
  2736. (setq closing-string "#}"))
  2737. )
  2738. ) ;django
  2739. ((string= web-mode-engine "ejs")
  2740. (setq closing-string "%>"
  2741. delim-open "<%[=-]?"
  2742. delim-close "[-]?%>")
  2743. ) ;ejs
  2744. ((string= web-mode-engine "lsp")
  2745. (setq closing-string "%>"
  2746. delim-open "<%[%#]?"
  2747. delim-close "%>")
  2748. ) ;lsp
  2749. ((string= web-mode-engine "mako")
  2750. (cond
  2751. ((and (string= tagopen "<%")
  2752. (member (char-after) '(?\s ?\n ?\!)))
  2753. (setq closing-string "%>"
  2754. delim-open "<%[!]?"
  2755. delim-close "%>"))
  2756. ((member sub2 '("<%" "</"))
  2757. (setq closing-string ">"
  2758. delim-open "</?%"
  2759. delim-close "/?>"))
  2760. ((string= sub2 "${")
  2761. (setq closing-string "}"
  2762. delim-open "${"
  2763. delim-close "}"))
  2764. (t
  2765. (setq closing-string "EOL"
  2766. delim-open "%"))
  2767. )
  2768. ) ;mako
  2769. ((string= web-mode-engine "cl-emb")
  2770. (cond
  2771. ((string= tagopen "<%#")
  2772. (setq closing-string "#%>"))
  2773. ((string= sub2 "<%")
  2774. (setq closing-string "%>"
  2775. delim-open "<%[=%]?"
  2776. delim-close "%>"))
  2777. )
  2778. ) ;cl-emb
  2779. ((string= web-mode-engine "artanis")
  2780. (cond
  2781. ((string= tagopen "<%;")
  2782. (setq closing-string "%>"))
  2783. ((string= tagopen "<%#|")
  2784. (setq closing-string "|#%>"))
  2785. ((string= sub2 "<@")
  2786. (setq closing-string "%>"
  2787. delim-open "<@\\(css\\|icon\\|include\\|js\\)"
  2788. delim-close "%>"))
  2789. ((string= sub2 "<%")
  2790. (setq closing-string "%>"
  2791. delim-open "<%[=]?"
  2792. delim-close "%>"))
  2793. )
  2794. ) ;artanis
  2795. ((string= web-mode-engine "elixir")
  2796. (cond
  2797. ((member (char-after) '(?\#))
  2798. (setq closing-string "%>"))
  2799. (t
  2800. (setq closing-string "%>"
  2801. delim-open "<%[=%]?"
  2802. delim-close "%>"))
  2803. )
  2804. ) ;elixir
  2805. ((string= web-mode-engine "mojolicious")
  2806. (cond
  2807. ((string= tagopen "<%#")
  2808. (setq closing-string "%>"))
  2809. ((string= sub2 "<%")
  2810. (setq closing-string "%>"
  2811. delim-open "<%\\(==\\|[=%]\\)?"
  2812. delim-close "%>"))
  2813. ((string= sub2 "%#")
  2814. (setq closing-string "EOL"))
  2815. (t
  2816. (setq closing-string "EOL"
  2817. delim-open "%\\(==\\|[=%]\\)?"))
  2818. )
  2819. ) ;mojolicious
  2820. ((string= web-mode-engine "ctemplate")
  2821. (cond
  2822. ((member tagopen '("{{{" "{{~"))
  2823. (setq closing-string "}~?}}"
  2824. delim-open "{{~?{"
  2825. delim-close "}~?}}")
  2826. )
  2827. ((string= tagopen "{~{")
  2828. (setq closing-string "}~?}"
  2829. delim-open "{~{"
  2830. delim-close "}~?}")
  2831. )
  2832. ((string= tagopen "{{!")
  2833. (setq closing-string (if (looking-at-p "--") "--}}" "}}"))
  2834. )
  2835. ((string= sub2 "{{")
  2836. (setq closing-string "}~?}"
  2837. delim-open "{{[>#/%^&]?"
  2838. delim-close "}~?}"))
  2839. (t
  2840. (setq closing-string "}}"
  2841. delim-open "${{"
  2842. delim-close "}}"))
  2843. )
  2844. ) ;ctemplate
  2845. ((string= web-mode-engine "aspx")
  2846. (setq closing-string "%>"
  2847. delim-open "<%[:=#@$]?"
  2848. delim-close "%>")
  2849. ) ;aspx
  2850. ((string= web-mode-engine "asp")
  2851. (cond
  2852. ((string= sub2 "<%")
  2853. (setq closing-string "%>"
  2854. delim-open "<%[:=#@$]?"
  2855. delim-close "%>"))
  2856. (t
  2857. (setq closing-string ">"
  2858. delim-open "</?"
  2859. delim-close "/?>"))
  2860. )
  2861. ) ;asp
  2862. ((string= web-mode-engine "jsp")
  2863. (cond
  2864. ((looking-at-p "--")
  2865. (setq closing-string "--%>"))
  2866. ((string= sub2 "<%")
  2867. (setq closing-string "%>"
  2868. delim-open "<%\\([!=@]\\|#=\\)?"
  2869. delim-close "[-]?%>"))
  2870. ((string= sub2 "${")
  2871. (setq closing-string "}"
  2872. delim-open "${"
  2873. delim-close "}"))
  2874. )
  2875. ) ;jsp
  2876. ((string= web-mode-engine "clip")
  2877. (setq closing-string ">"
  2878. delim-open "</?"
  2879. delim-close "/?>")
  2880. ) ;clip
  2881. ((string= web-mode-engine "blade")
  2882. (cond
  2883. ((string= tagopen "{{-")
  2884. (setq closing-string "--}}"))
  2885. ((string= tagopen "{!!")
  2886. (setq closing-string "!!}"
  2887. delim-open "{!!"
  2888. delim-close "!!}"))
  2889. ((string= tagopen "@{{")
  2890. (setq closing-string nil))
  2891. ((string= tagopen "{{{")
  2892. (setq closing-string "}}}"
  2893. delim-open "{{{"
  2894. delim-close "}}}"))
  2895. ((string= sub2 "{{")
  2896. (setq closing-string "}}"
  2897. delim-open "{{"
  2898. delim-close "}}"))
  2899. ((looking-at-p "[[:alnum:]]+\\.[[:alpha:]]+")
  2900. )
  2901. ((looking-at-p "[[:alnum:]]+(")
  2902. (setq closing-string ")"
  2903. delim-open "@"))
  2904. ((string= sub1 "@")
  2905. (setq closing-string "EOB"
  2906. delim-open "@"))
  2907. )
  2908. ) ;blade
  2909. ((string= web-mode-engine "smarty")
  2910. (cond
  2911. ((string= tagopen "{*")
  2912. (setq closing-string "*}")
  2913. )
  2914. ((string= tagopen "{#")
  2915. (setq closing-string "#}"
  2916. delim-open "{#"
  2917. delim-close "#}")
  2918. )
  2919. (t
  2920. (setq closing-string (cons "{" "}")
  2921. delim-open "{/?"
  2922. delim-close "}")
  2923. ) ;t
  2924. ) ;cond
  2925. ) ;smarty
  2926. ((string= web-mode-engine "hero")
  2927. (setq closing-string "%>"
  2928. delim-open "<%==?\\([biufsv]\\|bs\\)?\\|<%[:~@+!]?"
  2929. delim-close "%>")
  2930. ) ;hero
  2931. ((string= web-mode-engine "xoops")
  2932. (cond
  2933. ((string= tagopen "<{*")
  2934. (setq closing-string "*}>")
  2935. )
  2936. ((string= tagopen "<{#")
  2937. (setq closing-string "#}>"
  2938. delim-open "<{#"
  2939. delim-close "#}>")
  2940. )
  2941. (t
  2942. (setq closing-string (cons "<{" "}>")
  2943. delim-open "<{/?"
  2944. delim-close "}>")
  2945. ) ;t
  2946. ) ;cond
  2947. ) ;xoops
  2948. ((string= web-mode-engine "web2py")
  2949. (setq closing-string "}}"
  2950. delim-open "{{[=]?"
  2951. delim-close "}}")
  2952. ) ;web2py
  2953. ((string= web-mode-engine "expressionengine")
  2954. (cond
  2955. ((string= sub2 "{!--")
  2956. (setq closing-string "--}"))
  2957. (t
  2958. (setq closing-string '("{". "}")
  2959. delim-open "{/?"
  2960. delim-close "}")
  2961. )
  2962. )
  2963. ) ;expressionengine
  2964. ((string= web-mode-engine "dust")
  2965. (cond
  2966. ((string= sub2 "{!")
  2967. (setq closing-string "!}"))
  2968. (t
  2969. (setq closing-string '("{". "}")
  2970. delim-open "{[#/:?@><+^]?"
  2971. delim-close "/?}")
  2972. )
  2973. )
  2974. ) ;dust
  2975. ((string= web-mode-engine "svelte")
  2976. (cond
  2977. ((string= sub2 "{!")
  2978. (setq closing-string "!}"))
  2979. (t
  2980. (setq closing-string '("{". "}")
  2981. delim-open "{[#/:?@><+^]?"
  2982. delim-close "/?}")
  2983. )
  2984. )
  2985. ) ;svelte
  2986. ((string= web-mode-engine "closure")
  2987. (cond
  2988. ((string= sub2 "//")
  2989. (setq closing-string "EOL")
  2990. )
  2991. ((string= sub2 "/*")
  2992. (setq closing-string "*/")
  2993. )
  2994. (t
  2995. (setq closing-string "}"
  2996. delim-open "{/?"
  2997. delim-close "/?}")
  2998. )
  2999. )
  3000. ) ;closure
  3001. ((string= web-mode-engine "go")
  3002. (setq closing-string "}}"
  3003. delim-open "{{-?"
  3004. delim-close "-?}}")
  3005. ) ;go
  3006. ((string= web-mode-engine "angular")
  3007. (setq closing-string "}}"
  3008. delim-open "{{"
  3009. delim-close "}}")
  3010. ) ;angular
  3011. ((string= web-mode-engine "vue")
  3012. (cond
  3013. ((string-match-p "[:@][-[:alpha:]]+=\"" tagopen)
  3014. (setq closing-string "\""
  3015. delim-open tagopen
  3016. delim-close "\""))
  3017. ((string= tagopen "{{")
  3018. (setq closing-string "}}"
  3019. delim-open "{{"
  3020. delim-close "}}")))
  3021. ) ;vue
  3022. ((string= web-mode-engine "mason")
  3023. (cond
  3024. ((and (member sub2 '("<%" "</"))
  3025. (looking-at "[[:alpha:]]+"))
  3026. (if (member (match-string-no-properties 0) '("after" "around" "augment" "before" "def" "filter" "method" "override"))
  3027. (setq closing-string ">"
  3028. delim-open "<[/]?%"
  3029. delim-close ">")
  3030. (setq closing-string (concat "</%" (match-string-no-properties 0) ">")
  3031. delim-open "<[^>]+>"
  3032. delim-close "<[^>]+>")
  3033. ) ;if
  3034. )
  3035. ((and (string= sub2 "<%")
  3036. (eq (char-after) ?\s))
  3037. (setq closing-string "%>"
  3038. delim-open "<%"
  3039. delim-close "%>"))
  3040. ((string= tagopen "</&")
  3041. (setq closing-string ">"
  3042. delim-open "</&"
  3043. delim-close ">")
  3044. )
  3045. ((string= sub2 "<&")
  3046. (setq closing-string "&>"
  3047. delim-open "<&[|]?"
  3048. delim-close "&>"))
  3049. (t
  3050. (setq closing-string "EOL"
  3051. delim-open "%"))
  3052. )
  3053. ) ;mason
  3054. ((string= web-mode-engine "underscore")
  3055. (setq closing-string "%>"
  3056. delim-open "<%"
  3057. delim-close "%>")
  3058. ) ;underscore
  3059. ((string= web-mode-engine "template-toolkit")
  3060. (cond
  3061. ((string= tagopen "%%#")
  3062. (setq closing-string "EOL"))
  3063. ((string= tagopen "[%#")
  3064. (setq closing-string "%]"))
  3065. (t
  3066. (setq closing-string "%]"
  3067. delim-open "\\[%[-+]?"
  3068. delim-close "[-=+]?%\\]"))
  3069. )
  3070. ) ;template-toolkit
  3071. ((string= web-mode-engine "freemarker")
  3072. (cond
  3073. ((and (string= sub2 "<#") (eq (char-after) ?\-))
  3074. (setq closing-string "-->"))
  3075. ((string= sub1 "<")
  3076. (setq closing-string ">"
  3077. delim-open "</?[#@]"
  3078. delim-close "/?>"))
  3079. ((string= sub1 "[")
  3080. (setq closing-string "]"
  3081. delim-open "\\[/?[#@]"
  3082. delim-close "/?\\]"))
  3083. (t
  3084. (setq closing-string "}"
  3085. delim-open "${"
  3086. delim-close "}"))
  3087. )
  3088. ) ;freemarker
  3089. ((string= web-mode-engine "velocity")
  3090. (cond
  3091. ((string= sub2 "##")
  3092. (setq closing-string "EOL"))
  3093. ((string= sub2 "#*")
  3094. (setq closing-string "*#"))
  3095. (t
  3096. (setq closing-string "EOV"
  3097. delim-open "#"))
  3098. )
  3099. ) ;velocity
  3100. ((string= web-mode-engine "razor")
  3101. (cond
  3102. ((string= sub2 "@@")
  3103. (forward-char 2)
  3104. (setq closing-string nil))
  3105. ((string= sub2 "@*")
  3106. (setq closing-string "*@"))
  3107. ((string= sub1 "@")
  3108. (setq closing-string "EOR"
  3109. delim-open "@"))
  3110. ((and (string= sub1 "}")
  3111. (looking-at-p "[ ]*\n"))
  3112. ;;(setq closing-string "EOC")
  3113. (save-excursion
  3114. (let (paren-pos)
  3115. (setq paren-pos (web-mode-part-opening-paren-position (1- (point))))
  3116. (if (and paren-pos (get-text-property paren-pos 'block-side))
  3117. (setq closing-string "EOC")
  3118. (setq closing-string nil)
  3119. ) ;if
  3120. ) ;let
  3121. ) ;save-excursion
  3122. ;;(message "%s %S %S" sub2 (point) (get-text-property (point) 'part-side))
  3123. )
  3124. ((string= sub1 "}")
  3125. ;;(message "%s: %s" (point) sub1)
  3126. (save-excursion
  3127. (let (paren-pos)
  3128. (setq paren-pos (web-mode-part-opening-paren-position (1- (point))))
  3129. (if (and paren-pos (get-text-property paren-pos 'block-side))
  3130. (setq closing-string "EOR")
  3131. (setq closing-string nil)
  3132. ) ;if
  3133. ) ;let
  3134. ) ;save-excursion
  3135. ) ;case }
  3136. ) ;cond
  3137. ) ;razor
  3138. ((and (string= web-mode-engine "riot")
  3139. (not (get-text-property open 'part-side)))
  3140. (setq closing-string (if (string= tagopen "{") "}" "/// end script")
  3141. delim-open "{"
  3142. delim-close "}")
  3143. ) ;riot
  3144. ((string= web-mode-engine "spip")
  3145. (cond
  3146. ((and (string= sub1 "#")
  3147. (looking-at "[A-Z0-9_]+"))
  3148. (setq closing-string (match-string-no-properties 0)))
  3149. ((string= sub1 "(")
  3150. (setq closing-string '("(" . ")")))
  3151. ((string= sub1 "{")
  3152. (setq closing-string '("{" . "}")))
  3153. ((string= sub2 "<:")
  3154. (setq closing-string ":>"))
  3155. (t
  3156. (setq closing-string "]"))
  3157. ))
  3158. ((string= web-mode-engine "marko")
  3159. (setq closing-string "}"
  3160. delim-open "${"
  3161. delim-close "}")
  3162. ) ;marko
  3163. ) ;cond
  3164. (when closing-string
  3165. (cond
  3166. ((listp closing-string)
  3167. (cond
  3168. ((web-mode-rsf-balanced (car closing-string) (cdr closing-string) reg-end t)
  3169. (setq close (match-end 0)
  3170. pos (point))
  3171. )
  3172. ((and (string= web-mode-engine "php")
  3173. (string= "<?" sub2))
  3174. (if (or (text-property-not-all (1+ open) (point-max) 'tag-beg nil)
  3175. (text-property-not-all (1+ open) (point-max) 'block-beg nil)
  3176. (looking-at-p "[ \t\n]*<"))
  3177. (setq close nil
  3178. delim-close nil
  3179. pos (point))
  3180. (setq close (point-max)
  3181. delim-close nil
  3182. pos (point-max))
  3183. ) ;if
  3184. ) ;case
  3185. ) ;cond
  3186. ) ;case listp
  3187. ((and (string= web-mode-engine "smarty")
  3188. (string= closing-string "}"))
  3189. (goto-char open)
  3190. (setq tmp (web-mode-closing-delimiter-position
  3191. "}"
  3192. (point)
  3193. (line-end-position)))
  3194. (if tmp
  3195. (setq tmp (1+ tmp))
  3196. (setq tmp (line-end-position)))
  3197. (goto-char tmp)
  3198. (setq close (point)
  3199. pos (point))
  3200. )
  3201. ((and (member web-mode-engine '("closure"))
  3202. (string= closing-string "}"))
  3203. (when (web-mode-closure-skip reg-beg reg-end)
  3204. (setq close (point)
  3205. pos (point))
  3206. ;;(message "close=%S pos=%S" close pos)
  3207. ) ;when
  3208. )
  3209. ((string= closing-string "EOB")
  3210. (web-mode-blade-skip open)
  3211. (setq close (point)
  3212. pos (point)))
  3213. ((string= closing-string "EOL")
  3214. (end-of-line)
  3215. (setq close (point)
  3216. pos (point)))
  3217. ((string= closing-string "EOC")
  3218. (setq close (point)
  3219. pos (point)))
  3220. ((string= closing-string "EODQ")
  3221. (when (web-mode-django-skip reg-beg reg-end)
  3222. (setq close (point)
  3223. pos (point))
  3224. ))
  3225. ((string= closing-string "EOR")
  3226. (web-mode-razor-skip open)
  3227. (setq close (if (> (point) reg-end) reg-end (point))
  3228. pos (if (> (point) reg-end) reg-end (point)))
  3229. (goto-char pos))
  3230. ((string= closing-string "EOV")
  3231. (web-mode-velocity-skip open)
  3232. (setq close (point)
  3233. pos (point)))
  3234. ((and (member web-mode-engine '("ctemplate"))
  3235. (re-search-forward closing-string reg-end t))
  3236. (setq close (match-end 0)
  3237. pos (point)))
  3238. ((search-forward closing-string reg-end t)
  3239. (setq close (match-end 0)
  3240. pos (point)))
  3241. ) ;cond
  3242. (when (and close (>= reg-end pos))
  3243. ;;(message "pos(%S) : open(%S) close(%S)" pos open close)
  3244. (put-text-property open (1+ open) 'block-beg 0)
  3245. (put-text-property open (1+ open) 'block-controls 0)
  3246. (put-text-property open close 'block-side t)
  3247. (put-text-property (1- close) close 'block-end t)
  3248. (when delim-open
  3249. (web-mode-block-delimiters-set open close delim-open delim-close))
  3250. (web-mode-block-scan open close)
  3251. (cond
  3252. ((and (string= web-mode-engine "erb")
  3253. (looking-at-p "<%= javascript_tag do %>"))
  3254. (setq tagopen "<%= javascript_tag do %>"))
  3255. ((and (string= web-mode-engine "mojolicious")
  3256. (looking-at-p "%= javascript begin"))
  3257. (setq tagopen "%= javascript begin"))
  3258. ((and (string= web-mode-engine "mako")
  3259. (looking-at-p "<%block filter=\"collect_js\">"))
  3260. (setq tagopen "<%block filter=\"collect_js\">"))
  3261. ((and (string= web-mode-engine "mako")
  3262. (looking-at-p "<%block filter=\"collect_css\">"))
  3263. (setq tagopen "<%block filter=\"collect_css\">"))
  3264. ((and (string= web-mode-engine "django")
  3265. (looking-at-p "{% javascript %}"))
  3266. (setq tagopen "{% javascript %}"))
  3267. ((and (string= web-mode-engine "django")
  3268. (looking-at-p "{% schema %}"))
  3269. (setq tagopen "{% schema %}"))
  3270. ((and (string= web-mode-engine "django")
  3271. (looking-at-p "{% stylesheet %}"))
  3272. (setq tagopen "{% stylesheet %}"))
  3273. )
  3274. ;;(message "%S %s" (point) tagopen)
  3275. (when (and (member tagopen '("<r:script" "<r:style"
  3276. "<c:js" "<c:css"
  3277. "<%= javascript_tag do %>"
  3278. "<%block filter=\"collect_js\">"
  3279. "<%block filter=\"collect_css\">"
  3280. "{% javascript %}"
  3281. "{% schema %}"
  3282. "{% stylesheet %}"
  3283. "%= javascript begin"))
  3284. (setq part-beg close)
  3285. (setq tagclose
  3286. (cond
  3287. ((string= tagopen "<r:script") "</r:script")
  3288. ((string= tagopen "<r:style") "</r:style")
  3289. ((string= tagopen "<c:js") "</c:js")
  3290. ((string= tagopen "<c:css") "</c:css")
  3291. ((string= tagopen "{% javascript %}") "{% endjavascript %}")
  3292. ((string= tagopen "{% schema %}") "{% endschema %}")
  3293. ((string= tagopen "{% stylesheet %}") "{% endstylesheet %}")
  3294. ((string= tagopen "%= javascript begin") "% end")
  3295. ((string= tagopen "<%= javascript_tag do %>") "<% end %>")
  3296. ((member tagopen '("<%block filter=\"collect_js\">"
  3297. "<%block filter=\"collect_css\">")) "</%block")
  3298. ))
  3299. (web-mode-sf tagclose)
  3300. (setq part-end (match-beginning 0))
  3301. (> part-end part-beg))
  3302. ;;(message "end=%S" (point))
  3303. (put-text-property part-beg part-end
  3304. 'part-side
  3305. (cond
  3306. ((member tagopen '("<r:style" "<c:css" "<%block filter=\"collect_css\">" "{% stylesheet %}")) 'css)
  3307. (t 'javascript)))
  3308. (setq pos part-beg
  3309. part-beg nil
  3310. part-end nil)
  3311. ) ;when
  3312. ) ;when close
  3313. (if pos (goto-char pos))
  3314. ) ;when closing-string
  3315. ) ;while
  3316. (cond
  3317. ((>= i 2000)
  3318. (message "scan-blocks ** warning (%S) **" i))
  3319. ((string= web-mode-engine "razor")
  3320. (web-mode-block-foreach reg-beg reg-end 'web-mode-block-scan))
  3321. ((string= web-mode-engine "django")
  3322. (web-mode-scan-engine-comments reg-beg reg-end
  3323. "{% comment %}" "{% endcomment %}"))
  3324. ((string= web-mode-engine "mako")
  3325. (web-mode-scan-engine-comments reg-beg reg-end
  3326. "<%doc>" "</%doc>"))
  3327. ((string= web-mode-engine "mason")
  3328. (web-mode-scan-engine-comments reg-beg reg-end
  3329. "<%doc>" "</%doc>"))
  3330. ) ;cond
  3331. )))
  3332. (defun web-mode-scan-engine-comments (reg-beg reg-end tag-start tag-end)
  3333. "Scan engine comments (mako, django)."
  3334. (save-excursion
  3335. (let (beg end (continue t))
  3336. (goto-char reg-beg)
  3337. (while (and continue
  3338. (< (point) reg-end)
  3339. (re-search-forward tag-start reg-end t))
  3340. (goto-char (match-beginning 0))
  3341. (setq beg (point))
  3342. (if (not (re-search-forward tag-end reg-end t))
  3343. (setq continue nil)
  3344. (setq end (point))
  3345. (remove-list-of-text-properties beg end web-mode-scan-properties)
  3346. (add-text-properties beg end '(block-side t block-token comment))
  3347. (put-text-property beg (1+ beg) 'block-beg 0)
  3348. (put-text-property (1- end) end 'block-end t)
  3349. ) ;if
  3350. ) ;while
  3351. )))
  3352. (defun web-mode-closure-skip (reg-beg reg-end)
  3353. (let (regexp char pos inc continue found)
  3354. (setq regexp "[\"'{}]"
  3355. inc 0)
  3356. (while (and (not found) (re-search-forward regexp reg-end t))
  3357. (setq char (char-before))
  3358. (cond
  3359. ((get-text-property (point) 'block-side)
  3360. (setq found t))
  3361. ((eq char ?\{)
  3362. (setq inc (1+ inc)))
  3363. ((eq char ?\})
  3364. (cond
  3365. ((and (not (eobp))
  3366. (< inc 1))
  3367. (setq found t
  3368. pos (point)))
  3369. ((> inc 0)
  3370. (setq inc (1- inc)))
  3371. )
  3372. )
  3373. ((eq char ?\')
  3374. (setq continue t)
  3375. (while (and continue (search-forward "'" reg-end t))
  3376. (setq continue (web-mode-string-continue-p reg-beg))
  3377. )
  3378. )
  3379. ((eq char ?\")
  3380. (setq continue t)
  3381. (while (and continue (search-forward "\"" reg-end t))
  3382. (setq continue (web-mode-string-continue-p reg-beg))
  3383. )
  3384. )
  3385. ) ;cond
  3386. ) ;while
  3387. pos))
  3388. (defun web-mode-django-skip (reg-beg reg-end)
  3389. (let (regexp char pos inc continue found)
  3390. (setq regexp "[\"'{}]"
  3391. inc 0)
  3392. (while (and (not found) (re-search-forward regexp reg-end t))
  3393. (setq char (char-before))
  3394. (cond
  3395. ((get-text-property (point) 'block-side)
  3396. (setq found t))
  3397. ((eq char ?\{)
  3398. (setq inc (1+ inc)))
  3399. ((eq char ?\})
  3400. (cond
  3401. ((and (not (eobp))
  3402. (eq (char-after) ?\})
  3403. (< inc 2))
  3404. (forward-char)
  3405. (setq found t
  3406. pos (1+ (point))))
  3407. ((> inc 0)
  3408. (setq inc (1- inc)))
  3409. )
  3410. )
  3411. ((eq char ?\')
  3412. (setq continue t)
  3413. (while (and continue (search-forward "'" reg-end t))
  3414. (setq continue (web-mode-string-continue-p reg-beg))
  3415. )
  3416. )
  3417. ((eq char ?\")
  3418. (setq continue t)
  3419. (while (and continue (search-forward "\"" reg-end t))
  3420. (setq continue (web-mode-string-continue-p reg-beg))
  3421. )
  3422. )
  3423. ) ;cond
  3424. ) ;while
  3425. pos))
  3426. (defun web-mode-blade-skip (pos)
  3427. (goto-char pos)
  3428. (forward-char)
  3429. (skip-chars-forward "a-zA-Z0-9_-"))
  3430. (defun web-mode-velocity-skip (pos)
  3431. (goto-char pos)
  3432. (let ((continue t) (i 0))
  3433. (when (eq ?\# (char-after))
  3434. (forward-char))
  3435. (when (member (char-after) '(?\$ ?\@))
  3436. (forward-char))
  3437. (when (member (char-after) '(?\!))
  3438. (forward-char))
  3439. (cond
  3440. ((member (char-after) '(?\{))
  3441. (search-forward "}" nil t))
  3442. ((looking-at-p "def \\|define ")
  3443. (search-forward ")" (line-end-position) t))
  3444. (t
  3445. (setq continue t)
  3446. (while continue
  3447. (skip-chars-forward "a-zA-Z0-9_-")
  3448. (when (> (setq i (1+ i)) 500)
  3449. (message "velocity-skip ** warning (%S) **" pos)
  3450. (setq continue nil))
  3451. (when (member (char-after) '(?\())
  3452. (search-forward ")" nil t))
  3453. (if (member (char-after) '(?\.))
  3454. (forward-char)
  3455. (setq continue nil))
  3456. ) ;while
  3457. ) ;t
  3458. ) ;cond
  3459. ))
  3460. (defun web-mode-razor-skip (pos)
  3461. (goto-char pos)
  3462. (let ((continue t) (i 0))
  3463. (while continue
  3464. (skip-chars-forward " =@a-zA-Z0-9_-")
  3465. (cond
  3466. ((> (setq i (1+ i)) 500)
  3467. (message "razor-skip ** warning **")
  3468. (setq continue nil))
  3469. ((and (eq (char-after) ?\*)
  3470. (eq (char-before) ?@))
  3471. (when (not (search-forward "*@" nil t))
  3472. (setq continue nil))
  3473. )
  3474. ((looking-at-p "@[({]")
  3475. (forward-char)
  3476. (when (setq pos (web-mode-closing-paren-position (point)))
  3477. (goto-char pos))
  3478. (forward-char)
  3479. )
  3480. ((and (not (eobp)) (eq ?\( (char-after)))
  3481. (cond
  3482. ((looking-at-p "[ \n]*[<@]")
  3483. (setq continue nil))
  3484. ((setq pos (web-mode-closing-paren-position))
  3485. (goto-char pos)
  3486. (forward-char))
  3487. (t
  3488. (forward-char))
  3489. ) ;cond
  3490. )
  3491. ((and (not (eobp)) (eq ?\< (char-after)) (looking-back "[a-z]" (point-min)))
  3492. (setq pos (point))
  3493. (cond
  3494. ;; #988
  3495. ((search-forward ">" (line-end-position) t)
  3496. (goto-char pos)
  3497. (setq continue nil)
  3498. )
  3499. (t
  3500. (setq continue nil))
  3501. ) ;cond
  3502. )
  3503. ((and (not (eobp)) (eq ?\. (char-after)))
  3504. (forward-char))
  3505. ((and (not (eobp)) (looking-at-p "[ \n]*else"))
  3506. (re-search-forward "[ \t]*else")
  3507. )
  3508. ((looking-at-p "[ \n]*{")
  3509. (search-forward "{")
  3510. (search-forward "=>" (point-at-eol) 't)
  3511. (if (looking-at-p "[ \n]*[<@]")
  3512. (setq continue nil)
  3513. (backward-char)
  3514. (when (setq pos (web-mode-closing-paren-position))
  3515. (goto-char pos))
  3516. (forward-char)
  3517. ) ;if
  3518. )
  3519. ((looking-at-p "}")
  3520. (forward-char))
  3521. (t
  3522. (setq continue nil))
  3523. ) ;cond
  3524. ) ;while
  3525. ))
  3526. (defun web-mode-block-delimiters-set (reg-beg reg-end delim-open delim-close)
  3527. "Set text-property 'block-token to 'delimiter-(beg|end) on block delimiters (e.g. <?php and ?>)"
  3528. ;;(message "reg-beg(%S) reg-end(%S) delim-open(%S) delim-close(%S)" reg-beg reg-end delim-open delim-close)
  3529. (when (member web-mode-engine
  3530. '("artanis" "asp" "aspx" "cl-emb" "clip" "closure" "ctemplate" "django" "dust"
  3531. "elixir" "ejs" "erb" "expressionengine" "freemarker" "go" "hero" "jsp" "lsp"
  3532. "mako" "mason" "mojolicious"
  3533. "smarty" "template-toolkit" "web2py" "xoops" "svelte"))
  3534. (save-excursion
  3535. (when delim-open
  3536. (goto-char reg-beg)
  3537. (looking-at delim-open)
  3538. (setq delim-open (match-string-no-properties 0)))
  3539. (when delim-close
  3540. (goto-char reg-end)
  3541. (looking-back delim-close reg-beg t)
  3542. (setq delim-close (match-string-no-properties 0)))
  3543. ))
  3544. (when delim-open
  3545. (put-text-property reg-beg (+ reg-beg (length delim-open))
  3546. 'block-token 'delimiter-beg))
  3547. (when delim-close
  3548. (put-text-property (- reg-end (length delim-close)) reg-end
  3549. 'block-token 'delimiter-end))
  3550. )
  3551. (defun web-mode-block-foreach (reg-beg reg-end func)
  3552. (let ((i 0) (continue t) (block-beg reg-beg) (block-end nil))
  3553. (while continue
  3554. (setq block-end nil)
  3555. (unless (get-text-property block-beg 'block-beg)
  3556. (setq block-beg (web-mode-block-next-position block-beg)))
  3557. (when (and block-beg (< block-beg reg-end))
  3558. (setq block-end (web-mode-block-end-position block-beg)))
  3559. (cond
  3560. ((> (setq i (1+ i)) 2000)
  3561. (message "process-blocks ** warning (%S) **" (point))
  3562. (setq continue nil))
  3563. ((or (null block-end) (> block-end reg-end))
  3564. (setq continue nil))
  3565. (t
  3566. (setq block-end (1+ block-end))
  3567. (funcall func block-beg block-end)
  3568. (setq block-beg block-end)
  3569. ) ;t
  3570. ) ;cond
  3571. ) ;while
  3572. ))
  3573. (defun web-mode-block-scan (block-beg block-end)
  3574. (let (sub1 sub2 sub3 regexp token-type)
  3575. ;;(message "block-beg=%S block-end=%S" block-beg block-end)
  3576. ;;(remove-text-properties block-beg block-end web-mode-scan-properties)
  3577. (goto-char block-beg)
  3578. (cond
  3579. ((>= (point-max) (+ block-beg 3))
  3580. (setq sub3 (buffer-substring-no-properties block-beg (+ block-beg 3))
  3581. sub2 (buffer-substring-no-properties block-beg (+ block-beg 2))
  3582. sub1 (buffer-substring-no-properties block-beg (+ block-beg 1)))
  3583. )
  3584. ((>= (point-max) (+ block-beg 2))
  3585. (setq sub3 (buffer-substring-no-properties block-beg (+ block-beg 2))
  3586. sub2 (buffer-substring-no-properties block-beg (+ block-beg 2))
  3587. sub1 (buffer-substring-no-properties block-beg (+ block-beg 1)))
  3588. )
  3589. (t
  3590. (setq sub1 (buffer-substring-no-properties block-beg (+ block-beg 1)))
  3591. (setq sub2 sub1
  3592. sub3 sub1)
  3593. )
  3594. )
  3595. (cond
  3596. ((member web-mode-engine '("php" "lsp" "python" "web2py" "mason"))
  3597. (setq regexp web-mode-engine-token-regexp))
  3598. ((string= web-mode-engine "mako")
  3599. (cond
  3600. ((string= sub2 "##")
  3601. (setq token-type 'comment)
  3602. )
  3603. (t
  3604. (setq regexp web-mode-engine-token-regexp))
  3605. )
  3606. ) ;mako
  3607. ((string= web-mode-engine "django")
  3608. (cond
  3609. ((member sub2 '("{{" "{%"))
  3610. (setq regexp "\"\\|'"))
  3611. ((string= sub2 "{#")
  3612. (setq token-type 'comment))
  3613. )
  3614. ) ;django
  3615. ((string= web-mode-engine "ctemplate")
  3616. (cond
  3617. ((string= sub3 "{{!")
  3618. (setq token-type 'comment))
  3619. ((member sub2 '("{{"))
  3620. )
  3621. )
  3622. ) ;ctemplate
  3623. ((string= web-mode-engine "go")
  3624. (cond
  3625. ((string= sub3 "{{/")
  3626. (setq token-type 'comment))
  3627. ((string= sub2 "{{")
  3628. (setq regexp "\"\\|'"))
  3629. )
  3630. ) ;go
  3631. ((string= web-mode-engine "hero")
  3632. (cond
  3633. ((string= sub3 "<%#")
  3634. (setq token-type 'comment))
  3635. (t
  3636. (setq regexp "\"\\|'"))
  3637. )
  3638. ) ;hero
  3639. ((string= web-mode-engine "razor")
  3640. (cond
  3641. ((string= sub2 "@*")
  3642. (setq token-type 'comment))
  3643. (t
  3644. (setq regexp "//\\|@\\*\\|\"\\|'"))
  3645. )
  3646. ) ;razor
  3647. ((string= web-mode-engine "blade")
  3648. (cond
  3649. ((string= sub3 "{{-")
  3650. (setq token-type 'comment))
  3651. (t
  3652. (setq regexp "\"\\|'"))
  3653. )
  3654. ) ;blade
  3655. ((string= web-mode-engine "cl-emb")
  3656. (cond
  3657. ((string= sub3 "<%#")
  3658. (setq token-type 'comment))
  3659. (t
  3660. (setq regexp "\"\\|'"))
  3661. )
  3662. ) ;cl-emb
  3663. ((string= web-mode-engine "artanis")
  3664. (cond
  3665. ((string= sub3 "<%;")
  3666. (setq token-type 'comment))
  3667. ((string= sub3 "<%#|")
  3668. (setq token-type 'comment))
  3669. (t
  3670. (setq regexp "\""))
  3671. )
  3672. ) ;artanis
  3673. ((string= web-mode-engine "elixir")
  3674. (cond
  3675. ((string= sub3 "<%#")
  3676. (setq token-type 'comment))
  3677. (t
  3678. (setq regexp "\"\\|'"))
  3679. )
  3680. ) ;elixir
  3681. ((string= web-mode-engine "mojolicious")
  3682. (cond
  3683. ((or (string= sub2 "%#") (string= sub3 "<%#"))
  3684. (setq token-type 'comment))
  3685. (t
  3686. (setq regexp "\"\\|'"))
  3687. )
  3688. ) ;mojolicious
  3689. ((string= web-mode-engine "velocity")
  3690. (cond
  3691. ((member sub2 '("##" "#*"))
  3692. (setq token-type 'comment))
  3693. ((member sub1 '("$" "#"))
  3694. (setq regexp "\"\\|'"))
  3695. )
  3696. ) ;velocity
  3697. ((string= web-mode-engine "jsp")
  3698. (cond
  3699. ((string= sub3 "<%-")
  3700. (setq token-type 'comment))
  3701. ((string= sub3 "<%@")
  3702. (setq regexp "/\\*"))
  3703. ((member sub2 '("${" "#{"))
  3704. (setq regexp "\"\\|'"))
  3705. ((string= sub2 "<%")
  3706. (setq regexp "//\\|/\\*\\|\"\\|'"))
  3707. )
  3708. ) ;jsp
  3709. ((string= web-mode-engine "clip")
  3710. (setq regexp nil)
  3711. ) ;clip
  3712. ((and (string= web-mode-engine "asp")
  3713. (string= sub2 "<%"))
  3714. (setq regexp "//\\|/\\*\\|\"\\|'")
  3715. ) ;asp
  3716. ((string= web-mode-engine "aspx")
  3717. (cond
  3718. ((string= sub3 "<%-")
  3719. (setq token-type 'comment))
  3720. ((string= sub3 "<%@")
  3721. (setq regexp "/\\*"))
  3722. ((string= sub3 "<%$")
  3723. (setq regexp "\"\\|'"))
  3724. (t
  3725. (setq regexp "//\\|/\\*\\|\"\\|'"))
  3726. )
  3727. ) ;aspx
  3728. ((string= web-mode-engine "freemarker")
  3729. (cond
  3730. ((member sub3 '("<#-" "[#-"))
  3731. (setq token-type 'comment))
  3732. ((member sub2 '("${" "#{"))
  3733. (setq regexp "\"\\|'"))
  3734. ((or (member sub2 '("<@" "[@" "<#" "[#"))
  3735. (member sub3 '("</@" "[/@" "</#" "[/#")))
  3736. (setq regexp "\"\\|'"))
  3737. )
  3738. ) ;freemarker
  3739. ((member web-mode-engine '("ejs" "erb"))
  3740. (cond
  3741. ((string= sub3 "<%#")
  3742. (setq token-type 'comment))
  3743. (t
  3744. (setq regexp web-mode-engine-token-regexp))
  3745. )
  3746. ) ;erb
  3747. ((string= web-mode-engine "template-toolkit")
  3748. (cond
  3749. ((member sub3 '("[%#" "%%#"))
  3750. (setq token-type 'comment))
  3751. (t
  3752. (setq regexp "#\\|\"\\|'"))
  3753. )
  3754. ) ;template-toolkit
  3755. ((string= web-mode-engine "underscore")
  3756. (setq regexp "/\\*\\|\"\\|'")
  3757. ) ;underscore
  3758. ((string= web-mode-engine "angular")
  3759. (setq regexp "#\\|\"\\|'")) ;angular
  3760. ((string= web-mode-engine "vue")
  3761. ) ;vue
  3762. ((string= web-mode-engine "smarty")
  3763. (cond
  3764. ((string= sub2 "{*")
  3765. (setq token-type 'comment))
  3766. (t
  3767. (setq regexp "\"\\|'")))
  3768. ) ;smarty
  3769. ((string= web-mode-engine "xoops")
  3770. (cond
  3771. ((string= sub3 "<{*")
  3772. (setq token-type 'comment))
  3773. (t
  3774. (setq regexp "\"\\|'")))
  3775. ) ;xoops
  3776. ((string= web-mode-engine "spip")
  3777. (if (string= (buffer-substring-no-properties
  3778. block-beg (+ block-beg 7))
  3779. "[(#REM)")
  3780. (setq token-type 'comment
  3781. regexp "\\]")))
  3782. ((string= web-mode-engine "dust")
  3783. (cond
  3784. ((string= sub2 "{!")
  3785. (setq token-type 'comment))
  3786. (t
  3787. (setq regexp "\"\\|'"))
  3788. )
  3789. ) ;dust
  3790. ((string= web-mode-engine "expressionengine")
  3791. (cond
  3792. ((string= sub2 "{!")
  3793. (setq token-type 'comment))
  3794. (t
  3795. (setq regexp "\"\\|'")))
  3796. ) ;expressionengine
  3797. ((string= web-mode-engine "closure")
  3798. (cond
  3799. ((member sub2 '("/*" "//"))
  3800. (setq token-type 'comment))
  3801. (t
  3802. (setq regexp "\"\\|'"))
  3803. )
  3804. ) ;closure
  3805. ((string= web-mode-engine "svelte")
  3806. ) ;svelte
  3807. ) ;cond
  3808. (cond
  3809. (token-type
  3810. (put-text-property block-beg block-end 'block-token token-type))
  3811. ((and regexp
  3812. (> (- block-end block-beg) 6))
  3813. (web-mode-block-tokenize
  3814. (web-mode-block-code-beginning-position block-beg)
  3815. (web-mode-block-code-end-position block-beg)
  3816. regexp)
  3817. )
  3818. ) ;cond
  3819. ))
  3820. (defun web-mode-block-tokenize (reg-beg reg-end &optional regexp)
  3821. (unless regexp (setq regexp web-mode-engine-token-regexp))
  3822. ;;(message "tokenize: reg-beg(%S) reg-end(%S) regexp(%S)" reg-beg reg-end regexp)
  3823. ;;(message "tokenize: reg-beg(%S) reg-end(%S) command(%S)" reg-beg reg-end this-command)
  3824. ;;(message "%S>%S : %S" reg-beg reg-end (buffer-substring-no-properties reg-beg reg-end))
  3825. (save-excursion
  3826. (let ((pos reg-beg) beg end char match continue (flags 0) token-type token-end)
  3827. (remove-list-of-text-properties reg-beg reg-end '(block-token))
  3828. ;; TODO : vérifier la cohérence
  3829. (put-text-property reg-beg reg-end 'block-side t)
  3830. (goto-char reg-beg)
  3831. (when (> (point) reg-end)
  3832. (message "block-tokenize ** reg-beg(%S) > reg-end(%S) **" reg-beg reg-end))
  3833. (while (and (< (point) reg-end) (re-search-forward regexp reg-end t))
  3834. (setq beg (match-beginning 0)
  3835. match (match-string 0)
  3836. continue t
  3837. token-type 'comment
  3838. token-end (if (< reg-end (line-end-position)) reg-end (line-end-position))
  3839. char (aref match 0))
  3840. (cond
  3841. ((and (string= web-mode-engine "asp") (eq char ?\'))
  3842. (goto-char token-end))
  3843. ((and (string= web-mode-engine "razor") (eq char ?\'))
  3844. (cond
  3845. ((looking-at-p "\\(.\\|[\\][bfntr]\\|[\\]u....\\)'")
  3846. (search-forward "'" reg-end t)
  3847. (setq token-type 'string)
  3848. )
  3849. (t
  3850. (re-search-forward "[[:alnum:]_-]+")
  3851. (setq token-type 'symbol)
  3852. )))
  3853. ((eq char ?\')
  3854. (setq token-type 'string)
  3855. (while (and continue (search-forward "'" reg-end t))
  3856. (setq continue (web-mode-string-continue-p reg-beg))
  3857. ))
  3858. ((eq char ?\")
  3859. (setq token-type 'string)
  3860. (while (and continue (search-forward "\"" reg-end t))
  3861. (setq continue (web-mode-string-continue-p reg-beg))
  3862. ))
  3863. ((string= match "//")
  3864. (goto-char token-end))
  3865. ((eq char ?\;)
  3866. (goto-char token-end))
  3867. ((string= match "#|")
  3868. (unless (search-forward "|#" reg-end t)
  3869. (goto-char token-end)))
  3870. ((eq char ?\#)
  3871. (goto-char token-end))
  3872. ((string= match "/*")
  3873. (unless (search-forward "*/" reg-end t)
  3874. (goto-char token-end))
  3875. )
  3876. ((string= match "@*")
  3877. (unless (search-forward "*@" reg-end t)
  3878. (goto-char token-end)))
  3879. ((eq char ?\<)
  3880. (setq token-type 'string)
  3881. (re-search-forward (concat "^[ ]*" (match-string 1)) reg-end t))
  3882. (t
  3883. (message "block-tokenize ** token end (%S) **" beg)
  3884. (setq token-type nil))
  3885. ) ;cond
  3886. (put-text-property beg (point) 'block-token token-type)
  3887. (when (eq token-type 'comment)
  3888. (put-text-property beg (1+ beg) 'syntax-table (string-to-syntax "<"))
  3889. (if (or (< (point) (line-end-position)) (= (point) (point-max)))
  3890. (put-text-property (1- (point)) (point) 'syntax-table (string-to-syntax ">")) ;#445 #480
  3891. (put-text-property (point) (1+ (point)) 'syntax-table (string-to-syntax ">")) ;#377
  3892. )
  3893. )
  3894. ) ;while
  3895. (web-mode-block-controls-unset pos)
  3896. )))
  3897. (defun web-mode-set-php-controls (reg-beg reg-end)
  3898. (goto-char reg-beg)
  3899. (let (match controls
  3900. (continue t)
  3901. (regexp "endif\\|endforeach\\|endfor\\|endwhile\\|elseif\\|else\\|if\\|foreach\\|for\\|while"))
  3902. (while continue
  3903. (if (not (web-mode-block-rsf regexp reg-end))
  3904. (setq continue nil)
  3905. (setq match (match-string-no-properties 0))
  3906. ;; (message "%S %S" match (point))
  3907. (cond
  3908. ((and (member match '("else" "elseif"))
  3909. (looking-at-p "[ ]*[:(]"))
  3910. (setq controls (append controls (list (cons 'inside "if"))))
  3911. )
  3912. ((and (>= (length match) 3)
  3913. (string= (substring match 0 3) "end"))
  3914. (setq controls (append controls (list (cons 'close (substring match 3)))))
  3915. )
  3916. ((and (progn (skip-chars-forward "[ ]") t)
  3917. (eq (char-after) ?\()
  3918. (web-mode-closing-paren reg-end)
  3919. ;;(progn (message "ixi%S" (point)))
  3920. (looking-at-p ")[ ]*:"))
  3921. (setq controls (append controls (list (cons 'open match))))
  3922. )
  3923. ) ;cond
  3924. ) ;if
  3925. ) ;while
  3926. ;;(message "%S-%S %S" reg-beg reg-end controls)
  3927. (when (and controls (> (length controls) 1))
  3928. (setq controls (web-mode-block-controls-reduce controls)))
  3929. controls))
  3930. (defun web-mode-block-controls-reduce (controls)
  3931. (when (and (eq (car (car controls)) 'open)
  3932. (member (cons 'close (cdr (car controls))) controls))
  3933. (setq controls nil))
  3934. controls)
  3935. (defun web-mode-block-controls-unset (pos)
  3936. (cond
  3937. ((null (get-text-property pos 'block-side))
  3938. (message "block-controls-unset ** invalid value (%S) **" pos))
  3939. ((or (get-text-property pos 'block-beg)
  3940. (setq pos (web-mode-block-beginning-position pos)))
  3941. (put-text-property pos (1+ pos) 'block-controls 0))
  3942. (t
  3943. (message "block-controls-unset ** failure (%S) **" (point)))
  3944. ))
  3945. (defun web-mode-block-controls-get (pos)
  3946. (web-mode-with-silent-modifications
  3947. (let ((controls nil))
  3948. (cond
  3949. ((null (get-text-property pos 'block-side))
  3950. (message "block-controls-get ** invalid value (%S) **" pos))
  3951. ((or (get-text-property pos 'block-beg)
  3952. (setq pos (web-mode-block-beginning-position pos)))
  3953. (setq controls (get-text-property pos 'block-controls))
  3954. (when (integerp controls)
  3955. (web-mode-block-controls-set pos (web-mode-block-end-position pos))
  3956. (setq controls (get-text-property pos 'block-controls))
  3957. )
  3958. )
  3959. (t
  3960. (message "block-controls-get ** failure (%S) **" (point)))
  3961. ) ;cond
  3962. controls)))
  3963. (defun web-mode-block-controls-set (reg-beg reg-end)
  3964. (save-excursion
  3965. (goto-char reg-beg)
  3966. (let (controls pos type control)
  3967. (cond
  3968. ((null web-mode-engine)
  3969. (message "block-controls-set ** unknown engine (%S) **" web-mode-engine)
  3970. )
  3971. ((string= web-mode-engine "php")
  3972. (setq controls (web-mode-set-php-controls reg-beg reg-end))
  3973. (when (web-mode-block-starts-with "}" reg-beg)
  3974. (setq controls (append controls (list (cons 'close "{")))))
  3975. (when (web-mode-block-ends-with (cons "{" "}") reg-beg)
  3976. (setq controls (append controls (list (cons 'open "{")))))
  3977. ) ;php
  3978. ((string= web-mode-engine "ejs")
  3979. (cond
  3980. ((web-mode-block-ends-with "}[ ]*else[ ]*{" reg-beg)
  3981. (setq controls (append controls (list (cons 'inside "{")))))
  3982. ((web-mode-block-starts-with "}" reg-beg)
  3983. (setq controls (append controls (list (cons 'close "{")))))
  3984. ((web-mode-block-ends-with "{" reg-beg)
  3985. (setq controls (append controls (list (cons 'open "{")))))
  3986. )
  3987. ) ;ejs
  3988. ((string= web-mode-engine "erb")
  3989. (cond
  3990. ((web-mode-block-starts-with "else\\|elsif\\|when" reg-beg)
  3991. (setq controls (append controls (list (cons 'inside "ctrl")))))
  3992. ((web-mode-block-starts-with "end" reg-beg)
  3993. (setq controls (append controls (list (cons 'close "ctrl")))))
  3994. ((web-mode-block-ends-with " do\\( |.*|\\)?" reg-beg)
  3995. (setq controls (append controls (list (cons 'open "ctrl")))))
  3996. ((and (web-mode-block-starts-with "\\(for\\|if\\|unless\\|case\\)\\_>" reg-beg)
  3997. (not (web-mode-block-ends-with "end" reg-end)))
  3998. (setq controls (append controls (list (cons 'open "ctrl")))))
  3999. )
  4000. ) ;erb
  4001. ((string= web-mode-engine "django")
  4002. (cond
  4003. ((and (string= web-mode-minor-engine "jinja") ;#504
  4004. (web-mode-block-starts-with "else\\_>" reg-beg))
  4005. (let ((continue t)
  4006. (pos reg-beg)
  4007. (ctrl nil))
  4008. (while continue
  4009. (cond
  4010. ((null (setq pos (web-mode-block-control-previous-position 'open pos)))
  4011. (setq continue nil))
  4012. ((member (setq ctrl (cdr (car (get-text-property pos 'block-controls)))) '("if" "ifequal" "ifnotequal" "for"))
  4013. (setq continue nil)
  4014. )
  4015. ) ;cond
  4016. )
  4017. (setq controls (append controls (list (cons 'inside (or ctrl "if")))))
  4018. )
  4019. )
  4020. ((web-mode-block-starts-with "form_start[ ]*(" reg-beg)
  4021. (setq controls (append controls (list (cons 'open "form_start")))))
  4022. ((web-mode-block-starts-with "form_end[ ]*(" reg-beg)
  4023. (setq controls (append controls (list (cons 'close "form_start")))))
  4024. ((not (eq (char-after (1+ reg-beg)) ?\%))
  4025. )
  4026. ((web-mode-block-starts-with "\\(else\\|els?if\\)" reg-beg)
  4027. (let ((continue t)
  4028. (pos reg-beg)
  4029. (ctrl nil))
  4030. (while continue
  4031. (cond
  4032. ((null (setq pos (web-mode-block-control-previous-position 'open pos)))
  4033. (setq continue nil))
  4034. ((member (setq ctrl (cdr (car (get-text-property pos 'block-controls)))) '("if" "ifequal" "ifnotequal"))
  4035. (setq continue nil)
  4036. )
  4037. ) ;cond
  4038. ) ;while
  4039. (setq controls (append controls (list (cons 'inside (or ctrl "if")))))
  4040. ) ;let
  4041. ) ;case else
  4042. ((web-mode-block-starts-with "\\(empty\\)" reg-beg)
  4043. (setq controls (append controls (list (cons 'inside "for")))))
  4044. ((web-mode-block-starts-with "end\\([[:alpha:]]+\\)" reg-beg)
  4045. (setq controls (append controls (list (cons 'close (match-string-no-properties 1))))))
  4046. ((web-mode-block-starts-with (concat web-mode-django-control-blocks-regexp "[ %]") reg-beg)
  4047. (let (control)
  4048. (setq control (match-string-no-properties 1))
  4049. ;;(message "%S %S %S" control (concat "end" control) web-mode-django-control-blocks)
  4050. (when (member (concat "end" control) web-mode-django-control-blocks)
  4051. (setq controls (append controls (list (cons 'open control))))
  4052. ) ;when
  4053. ) ;let
  4054. ) ;case
  4055. ) ;cond
  4056. ) ;django
  4057. ((string= web-mode-engine "smarty")
  4058. (cond
  4059. ((and (eq (char-after (1+ reg-beg)) ?\/)
  4060. (web-mode-block-starts-with "\\([[:alpha:]]+\\)" reg-beg))
  4061. (setq controls (append controls (list (cons 'close (match-string-no-properties 1))))))
  4062. ((web-mode-block-starts-with "\\(else\\|elseif\\)" reg-beg)
  4063. (setq controls (append controls (list (cons 'inside "if")))))
  4064. ((web-mode-block-starts-with "\\(block\\|foreach\\|for\\|if\\|section\\|while\\)")
  4065. (setq controls (append controls (list (cons 'open (match-string-no-properties 1))))))
  4066. )
  4067. ) ;smarty
  4068. ((string= web-mode-engine "expressionengine")
  4069. (cond
  4070. ((and (eq (char-after (1+ reg-beg)) ?\/)
  4071. (web-mode-block-starts-with "\\(if\\)" reg-beg))
  4072. (setq controls (append controls (list (cons 'close (match-string-no-properties 1))))))
  4073. ((web-mode-block-starts-with "\\(if:else\\|if:ifelse\\)" reg-beg)
  4074. (setq controls (append controls (list (cons 'inside "if")))))
  4075. ((web-mode-block-starts-with "\\(if\\)")
  4076. (setq controls (append controls (list (cons 'open (match-string-no-properties 1))))))
  4077. )
  4078. ) ;expressionengine
  4079. ((string= web-mode-engine "xoops")
  4080. (cond
  4081. ((and (eq (char-after (+ reg-beg 2)) ?\/)
  4082. (web-mode-block-starts-with "\\([[:alpha:]]+\\)" reg-beg))
  4083. (setq controls (append controls (list (cons 'close (match-string-no-properties 1))))))
  4084. ((web-mode-block-starts-with "\\(else\\|elseif\\)" reg-beg)
  4085. (setq controls (append controls (list (cons 'inside "if")))))
  4086. ((web-mode-block-starts-with "\\(block\\|foreach\\|for\\|if\\|section\\|while\\)")
  4087. (setq controls (append controls (list (cons 'open (match-string-no-properties 1))))))
  4088. )
  4089. ) ;xoops
  4090. ((string= web-mode-engine "web2py")
  4091. (cond
  4092. ((web-mode-block-starts-with "def" reg-beg)
  4093. (setq controls (append controls (list (cons 'open "def")))))
  4094. ((web-mode-block-starts-with "return" reg-beg)
  4095. (setq controls (append controls (list (cons 'close "def")))))
  4096. ((web-mode-block-starts-with "block" reg-beg)
  4097. (setq controls (append controls (list (cons 'open "block")))))
  4098. ((web-mode-block-starts-with "end" reg-beg)
  4099. (setq controls (append controls (list (cons 'close "block")))))
  4100. ((web-mode-block-starts-with "pass" reg-beg)
  4101. (setq controls (append controls (list (cons 'close "ctrl")))))
  4102. ((web-mode-block-starts-with "\\(except\\|finally\\|els\\)" reg-beg)
  4103. (setq controls (append controls (list (cons 'inside "ctrl")))))
  4104. ((web-mode-block-starts-with "\\(if\\|for\\|try\\|while\\)")
  4105. (setq controls (append controls (list (cons 'open "ctrl")))))
  4106. )
  4107. ) ;web2py
  4108. ((string= web-mode-engine "dust")
  4109. (cond
  4110. ((eq (char-after (1- reg-end)) ?\/)
  4111. )
  4112. ((eq (char-after (1+ reg-beg)) ?\:)
  4113. (setq pos (web-mode-block-control-previous-position 'open reg-beg))
  4114. (when pos
  4115. (setq controls (append controls
  4116. (list
  4117. (cons 'inside
  4118. (cdr (car (web-mode-block-controls-get pos))))))))
  4119. )
  4120. ((looking-at "{/\\([[:alpha:].]+\\)")
  4121. (setq controls (append controls (list (cons 'close (match-string-no-properties 1))))))
  4122. ((looking-at "{[#?@><+^]\\([[:alpha:].]+\\)")
  4123. (setq controls (append controls (list (cons 'open (match-string-no-properties 1))))))
  4124. )
  4125. ) ;dust
  4126. ((member web-mode-engine '("mojolicious"))
  4127. (cond
  4128. ((web-mode-block-ends-with "begin" reg-beg)
  4129. (setq controls (append controls (list (cons 'open "begin")))))
  4130. ((web-mode-block-starts-with "end" reg-beg)
  4131. (setq controls (append controls (list (cons 'close "begin")))))
  4132. ((web-mode-block-starts-with "}[ ]*else[ ]*{" reg-beg)
  4133. (setq controls (append controls (list (cons 'inside "{")))))
  4134. ((web-mode-block-starts-with "}" reg-beg)
  4135. (setq controls (append controls (list (cons 'close "{")))))
  4136. ((web-mode-block-ends-with "{" reg-beg)
  4137. (setq controls (append controls (list (cons 'open "{")))))
  4138. )
  4139. ) ;mojolicious
  4140. ((member web-mode-engine '("aspx" "underscore"))
  4141. (cond
  4142. ((and (web-mode-block-starts-with "}" reg-beg)
  4143. (web-mode-block-ends-with "{" reg-beg))
  4144. (setq controls (append controls (list (cons 'inside "{")))))
  4145. ((web-mode-block-starts-with "}" reg-beg)
  4146. (setq controls (append controls (list (cons 'close "{")))))
  4147. ((web-mode-block-ends-with "{" reg-beg)
  4148. (setq controls (append controls (list (cons 'open "{")))))
  4149. )
  4150. ) ;aspx underscore
  4151. ((member web-mode-engine '("jsp" "asp" "clip"))
  4152. (cond
  4153. ((eq (char-after (1- reg-end)) ?\/)
  4154. )
  4155. ((looking-at "</?\\([[:alpha:]]+\\(?:[:.][[:alpha:]]+\\)\\|[[:alpha:]]+Template\\)")
  4156. (setq control (match-string-no-properties 1)
  4157. type (if (eq (aref (match-string-no-properties 0) 1) ?\/) 'close 'open))
  4158. (when (not (member control '("h:inputtext" "jsp:usebean" "jsp:forward" "struts:property")))
  4159. (setq controls (append controls (list (cons type control)))))
  4160. )
  4161. (t
  4162. (when (web-mode-block-starts-with "}" reg-beg)
  4163. (setq controls (append controls (list (cons 'close "{")))))
  4164. (when (web-mode-block-ends-with "{" reg-beg)
  4165. (setq controls (append controls (list (cons 'open "{")))))
  4166. )
  4167. )
  4168. ) ;jsp asp
  4169. ((string= web-mode-engine "mako")
  4170. (cond
  4171. ((looking-at "</?%\\([[:alpha:]]+\\(?:[:][[:alpha:]]+\\)?\\)")
  4172. (cond
  4173. ((eq (char-after (- (web-mode-block-end-position reg-beg) 1)) ?\/)
  4174. )
  4175. (t
  4176. (setq control (match-string-no-properties 1)
  4177. type (if (eq (aref (match-string-no-properties 0) 1) ?\/) 'close 'open))
  4178. (setq controls (append controls (list (cons type control)))))
  4179. )
  4180. )
  4181. ((web-mode-block-starts-with "\\(else\\|elif\\)" reg-beg)
  4182. (setq controls (append controls (list (cons 'inside "if")))))
  4183. ((web-mode-block-starts-with "end\\(if\\|for\\)" reg-beg)
  4184. (setq controls (append controls (list (cons 'close (match-string-no-properties 1))))))
  4185. ((and (web-mode-block-starts-with "if\\|for" reg-beg)
  4186. (web-mode-block-ends-with ":" reg-beg))
  4187. (setq controls (append controls (list (cons 'open (match-string-no-properties 0))))))
  4188. )
  4189. ) ;mako
  4190. ((string= web-mode-engine "mason")
  4191. (cond
  4192. ((looking-at "</?%\\(after\\|around\\|augment\\|before\\|def\\|filter\\|method\\|override\\)")
  4193. (setq control (match-string-no-properties 1)
  4194. type (if (eq (aref (match-string-no-properties 0) 1) ?\/) 'close 'open))
  4195. (setq controls (append controls (list (cons type control))))
  4196. )
  4197. )
  4198. ) ;mason
  4199. ((string= web-mode-engine "ctemplate")
  4200. (cond
  4201. ((looking-at-p "{{else") ;#721
  4202. (let ((continue t)
  4203. (pos reg-beg)
  4204. (ctrl nil))
  4205. (while continue
  4206. (cond
  4207. ((null (setq pos (web-mode-block-control-previous-position 'open pos)))
  4208. (setq continue nil))
  4209. ((member (setq ctrl (cdr (car (get-text-property pos 'block-controls)))) '("if" "each"))
  4210. (setq continue nil)
  4211. )
  4212. ) ;cond
  4213. ) ;while
  4214. (setq controls (append controls (list (cons 'inside (or ctrl "if")))))
  4215. )
  4216. )
  4217. ((looking-at "{{[#^/][ ]*\\([[:alpha:]_.-]+\\)")
  4218. (setq control (match-string-no-properties 1)
  4219. type (if (eq (aref (match-string-no-properties 0) 2) ?\/) 'close 'open))
  4220. (setq controls (append controls (list (cons type control))))
  4221. )
  4222. )
  4223. ) ;ctemplate
  4224. ((string= web-mode-engine "blade")
  4225. (cond
  4226. ((not (eq (char-after) ?\@))
  4227. )
  4228. ((web-mode-block-starts-with
  4229. "section\(\s*\\(['\"]\\).*\\1\s*,\s*\\(['\"]\\).*\\2\s*\)" reg-beg)
  4230. )
  4231. ((web-mode-block-starts-with "case\\|break" reg-beg)
  4232. (setq type (if (eq (aref (match-string-no-properties 0) 0) ?b) 'close 'open))
  4233. (setq controls (append controls (list (cons type "case"))))
  4234. )
  4235. ((web-mode-block-starts-with
  4236. (concat "\\(?:end\\)?\\(" web-mode-blade-control-blocks-regexp "\\)")
  4237. reg-beg)
  4238. (setq control (match-string-no-properties 1)
  4239. type (if (eq (aref (match-string-no-properties 0) 0) ?e) 'close 'open))
  4240. (setq controls (append controls (list (cons type control))))
  4241. )
  4242. ((web-mode-block-starts-with "stop\\|show\\|overwrite" reg-beg)
  4243. (setq controls (append controls (list (cons 'close "section")))))
  4244. ((web-mode-block-starts-with "else\\|elseif" reg-beg)
  4245. (setq controls (append controls (list (cons 'inside "if")))))
  4246. ((web-mode-block-starts-with "empty" reg-beg)
  4247. (setq controls (append controls (list (cons 'inside "forelse")))))
  4248. )
  4249. ) ;blade
  4250. ((string= web-mode-engine "closure")
  4251. (cond
  4252. ((eq (char-after (1- reg-end)) ?\/)
  4253. )
  4254. ((looking-at "alias\\|namespace")
  4255. )
  4256. ((web-mode-block-starts-with "ifempty" reg-beg)
  4257. (setq controls (append controls (list (cons 'inside "foreach")))))
  4258. ((web-mode-block-starts-with "else\\|elseif" reg-beg)
  4259. (setq controls (append controls (list (cons 'inside "if")))))
  4260. ((web-mode-block-starts-with "case\\|default" reg-beg)
  4261. (setq controls (append controls (list (cons 'inside "switch")))))
  4262. ((looking-at
  4263. "{/?\\(call\\|deltemplate\\|for\\|foreach\\|if\\|let\\|literal\\|msg\\|param\\|switch\\|template\\)")
  4264. (setq control (match-string-no-properties 1)
  4265. type (if (eq (aref (match-string-no-properties 0) 1) ?\/) 'close 'open))
  4266. (setq controls (append controls (list (cons type control))))
  4267. )
  4268. )
  4269. ) ;closure
  4270. ((string= web-mode-engine "go")
  4271. (cond
  4272. ((web-mode-block-starts-with "end\\_>" reg-beg)
  4273. (setq controls (append controls (list (cons 'close "ctrl")))))
  4274. ((web-mode-block-starts-with "else\\_>" reg-beg)
  4275. (setq controls (append controls (list (cons 'inside "ctrl")))))
  4276. ((web-mode-block-starts-with "\\(range\\|with\\|if\\|define\\|block\\)\\_>" reg-beg)
  4277. (setq controls (append controls (list (cons 'open "ctrl")))))
  4278. )
  4279. ) ;go
  4280. ((string= web-mode-engine "template-toolkit")
  4281. (cond
  4282. ((web-mode-block-starts-with "end" reg-beg)
  4283. (setq controls (append controls (list (cons 'close "ctrl")))))
  4284. ((web-mode-block-starts-with "els\\|catch\\|final" reg-beg)
  4285. (setq controls (append controls (list (cons 'inside "ctrl")))))
  4286. ((web-mode-block-starts-with "filter\\|foreach\\|if\\|last\\|next\\|perl\\|rawperl\\|try\\|unless\\|while" reg-beg)
  4287. (setq controls (append controls (list (cons 'open "ctrl")))))
  4288. )
  4289. ) ;template-toolkit
  4290. ((string= web-mode-engine "cl-emb")
  4291. (cond
  4292. ((web-mode-block-starts-with "@else" reg-beg)
  4293. (setq controls (append controls (list (cons 'inside "if")))))
  4294. ((web-mode-block-starts-with "@\\(?:end\\)?\\(if\\|unless\\|repeat\\|loop\\|with\\|genloop\\)" reg-beg)
  4295. (setq control (match-string-no-properties 1)
  4296. type (if (eq (aref (match-string-no-properties 0) 1) ?e) 'close 'open))
  4297. (setq controls (append controls (list (cons type control)))))
  4298. )
  4299. ) ;cl-emb
  4300. ((string= web-mode-engine "elixir")
  4301. (cond
  4302. ((web-mode-block-starts-with "end" reg-beg)
  4303. (setq controls (append controls (list (cons 'close "ctrl")))))
  4304. ((web-mode-block-starts-with "else" reg-beg)
  4305. (setq controls (append controls (list (cons 'inside "ctrl")))))
  4306. ((web-mode-block-ends-with " do" reg-beg)
  4307. (setq controls (append controls (list (cons 'open "ctrl")))))
  4308. ((web-mode-block-ends-with " ->" reg-beg)
  4309. (setq controls (append controls (list (cons 'open "ctrl")))))
  4310. )
  4311. ) ;elixir
  4312. ((string= web-mode-engine "velocity")
  4313. (cond
  4314. ((web-mode-block-starts-with "{?end" reg-beg)
  4315. (setq controls (append controls (list (cons 'close "ctrl")))))
  4316. ((web-mode-block-starts-with "{?els" reg-beg)
  4317. (setq controls (append controls (list (cons 'inside "ctrl")))))
  4318. ((web-mode-block-starts-with "{?\\(def\\|if\\|for\\|foreach\\|macro\\)" reg-beg)
  4319. ;;((web-mode-block-starts-with "{?\\(define\\|\\|if\\|for\\|foreach\\|macro\\)" reg-beg)
  4320. (setq controls (append controls (list (cons 'open "ctrl")))))
  4321. )
  4322. ) ;velocity
  4323. ((string= web-mode-engine "freemarker")
  4324. (cond
  4325. ((looking-at "[<[]#\\(import\\|include\\|assign\\|return\\|local\\)")
  4326. )
  4327. ((eq (char-after (1- reg-end)) ?\/)
  4328. )
  4329. ((looking-at "[<[]#\\(break\\|case\\|default\\)")
  4330. (setq controls (append controls (list (cons 'inside "switch"))))
  4331. )
  4332. ((looking-at "[<[]#els")
  4333. (setq controls (append controls (list (cons 'inside "if"))))
  4334. )
  4335. ((looking-at "</?\\([[:alpha:]]+\\(?:[:][[:alpha:]]+\\)?\\)")
  4336. (setq control (match-string-no-properties 1)
  4337. type (if (eq (aref (match-string-no-properties 0) 1) ?\/) 'close 'open))
  4338. (setq controls (append controls (list (cons type control))))
  4339. )
  4340. ((looking-at "[<[]/?\\(@\\)")
  4341. (setq control (match-string-no-properties 1)
  4342. type (if (eq (aref (match-string-no-properties 0) 1) ?\/) 'close 'open))
  4343. (setq controls (append controls (list (cons type control))))
  4344. )
  4345. ((looking-at "[<[]/?#\\([[:alpha:]]+\\(?:[:][[:alpha:]]+\\)?\\)")
  4346. (setq control (match-string-no-properties 1)
  4347. type (if (eq (aref (match-string-no-properties 0) 1) ?\/) 'close 'open))
  4348. (setq controls (append controls (list (cons type control))))
  4349. )
  4350. (t
  4351. (when (web-mode-block-starts-with "}" reg-beg)
  4352. (setq controls (append controls (list (cons 'close "{")))))
  4353. (when (web-mode-block-ends-with "{" reg-beg)
  4354. (setq controls (append controls (list (cons 'open "{")))))
  4355. )
  4356. )
  4357. ) ;freemarker
  4358. ((string= web-mode-engine "razor")
  4359. (when (web-mode-block-starts-with "}" reg-beg)
  4360. (setq controls (append controls (list (cons 'close "{")))))
  4361. (when (web-mode-block-ends-with "{" reg-beg)
  4362. (setq controls (append controls (list (cons 'open "{")))))
  4363. ) ;razor
  4364. ((string= web-mode-engine "lsp")
  4365. (when (web-mode-block-starts-with ")" reg-beg)
  4366. (setq controls (append controls (list (cons 'close "(")))))
  4367. (when (web-mode-block-is-opened-sexp reg-beg reg-end)
  4368. (setq controls (append controls (list (cons 'open "(")))))
  4369. ) ;lsp
  4370. ((string= web-mode-engine "hero")
  4371. (cond
  4372. ((web-mode-block-ends-with "}[ ]*else[ ]*{" reg-beg)
  4373. (setq controls (append controls (list (cons 'inside "{")))))
  4374. ((web-mode-block-starts-with "}" reg-beg)
  4375. (setq controls (append controls (list (cons 'close "{")))))
  4376. ((web-mode-block-ends-with "{" reg-beg)
  4377. (setq controls (append controls (list (cons 'open "{")))))
  4378. )
  4379. ) ;hero
  4380. ((string= web-mode-engine "svelte")
  4381. (cond
  4382. ((eq (char-after (1- reg-end)) ?\/)
  4383. )
  4384. ((eq (char-after (1+ reg-beg)) ?\:)
  4385. (setq pos (web-mode-block-control-previous-position 'open reg-beg))
  4386. (when pos
  4387. (setq controls (append controls
  4388. (list
  4389. (cons 'inside
  4390. (cdr (car (web-mode-block-controls-get pos))))))))
  4391. )
  4392. ((looking-at "{/\\([[:alpha:].]+\\)")
  4393. (setq controls (append controls (list (cons 'close (match-string-no-properties 1))))))
  4394. ((looking-at "{[#?><+^]\\([[:alpha:].]+\\)")
  4395. (setq controls (append controls (list (cons 'open (match-string-no-properties 1))))))
  4396. )
  4397. ) ;svelte
  4398. ) ;cond engine
  4399. (put-text-property reg-beg (1+ reg-beg) 'block-controls controls)
  4400. ;;(message "(%S) controls=%S" reg-beg controls)
  4401. )))
  4402. (defun web-mode-block-is-opened-sexp (reg-beg reg-end)
  4403. (let ((n 0))
  4404. (save-excursion
  4405. (goto-char reg-beg)
  4406. (while (web-mode-block-rsf "[()]" reg-end)
  4407. (if (eq (char-before) ?\() (setq n (1+ n)) (setq n (1- n)))))
  4408. (> n 0)))
  4409. ;;---- LEXER PARTS -------------------------------------------------------------
  4410. ;; FLAGS: tag
  4411. ;; (1)attrs (2)custom (4)slash-beg (8)slash-end (16)bracket-end
  4412. ;; (32)namespaced
  4413. (defun web-mode-scan-elements (reg-beg reg-end)
  4414. (save-excursion
  4415. (let (part-beg part-end flags limit close-expr props tname tbeg tend element-content-type (regexp web-mode-dom-regexp) part-close-tag char)
  4416. ;;(message "scan-elements: reg-beg(%S) reg-end(%S)" reg-beg reg-end)
  4417. (goto-char reg-beg)
  4418. (while (web-mode-dom-rsf regexp reg-end)
  4419. ;;(message "%S: %S (%S %S)" (point) (match-string-no-properties 0) reg-beg reg-end)
  4420. (setq flags 0
  4421. tname (downcase (match-string-no-properties 1))
  4422. char (aref tname 0)
  4423. tbeg (match-beginning 0)
  4424. tend nil
  4425. element-content-type nil
  4426. limit reg-end
  4427. part-beg nil
  4428. part-end nil
  4429. props nil
  4430. close-expr nil
  4431. part-close-tag nil)
  4432. ;;(message "tname[%S] tbeg(%S) point(%S)" tname tbeg (point))
  4433. (cond
  4434. ((member tname '("/>" ">")) ;;jsx fragment #952
  4435. (setq tname "_fragment_"
  4436. tend (point))
  4437. (if (eq char ?\/)
  4438. (setq props (list 'tag-name tname 'tag-type 'end)
  4439. flags (logior flags 20)) ;; 16 + 4
  4440. (setq props (list 'tag-name tname 'tag-type 'start)
  4441. flags (logior flags 16))
  4442. ) ;if
  4443. )
  4444. ((not (member char '(?\! ?\?)))
  4445. (cond
  4446. ((string-match-p "-" tname)
  4447. (setq flags (logior flags 2)))
  4448. ((string-match-p ":" tname)
  4449. (setq flags (logior flags 32)))
  4450. )
  4451. (cond
  4452. ((eq char ?\/)
  4453. (setq props (list 'tag-name (substring tname 1) 'tag-type 'end)
  4454. flags (logior flags 4)
  4455. limit (if (> reg-end (line-end-position)) (line-end-position) reg-end))
  4456. )
  4457. ((web-mode-element-is-void tname)
  4458. ;;(message "void: tag=%S" tname)
  4459. (setq props (list 'tag-name tname 'tag-type 'void)))
  4460. (t
  4461. (setq props (list 'tag-name tname 'tag-type 'start)))
  4462. ) ;cond
  4463. ) ; not <! <?
  4464. ((and (eq char ?\!) (eq (aref tname 1) ?\-))
  4465. (setq close-expr "-->"
  4466. props '(tag-type comment)))
  4467. ((string= tname "?xml")
  4468. (setq ;;regexp web-mode-tag-regexp2
  4469. close-expr "?>"
  4470. props '(tag-type declaration)))
  4471. ((string= tname "![cdata[")
  4472. (setq close-expr "]]>"
  4473. props '(tag-type cdata)))
  4474. ((string= tname "!doctype")
  4475. (setq ;;regexp web-mode-tag-regexp2
  4476. props '(tag-type doctype)))
  4477. ) ;cond - special tags
  4478. (cond
  4479. (tend
  4480. )
  4481. ((and (null close-expr) (eq (char-after) ?\>))
  4482. (setq flags (logior flags 16)
  4483. tend (1+ (point)))
  4484. ;;(message "end=%S" tend)
  4485. )
  4486. ((and (null close-expr)
  4487. (looking-at "[ ]\\(class\\|id\\|href\\|style\\)=\"[[:alnum:]_=:/?;#. -]*\">"))
  4488. (let ((beg (1+ (point)))
  4489. (end (+ (point) (length (match-string-no-properties 0)))))
  4490. (setq flags (logior flags 17)
  4491. tend end)
  4492. (put-text-property beg (1+ beg) 'tag-attr-beg 0)
  4493. (put-text-property beg (1- end) 'tag-attr t)
  4494. (put-text-property (- end 2) (1- end) 'tag-attr-end (length (match-string-no-properties 1)))
  4495. ) ;let
  4496. )
  4497. ((null close-expr)
  4498. (setq flags (logior flags (web-mode-attr-skip reg-end)))
  4499. (when (> (logand flags 8) 0)
  4500. (setq props (plist-put props 'tag-type 'void)))
  4501. (setq tend (point)))
  4502. ((web-mode-dom-sf close-expr limit t)
  4503. (setq tend (point)))
  4504. (t
  4505. (setq tend (line-end-position)))
  4506. ) ;cond
  4507. (cond
  4508. ((string= tname "style")
  4509. (let (style)
  4510. (setq style (buffer-substring-no-properties tbeg tend)
  4511. part-close-tag "</style>")
  4512. (cond
  4513. ((string-match-p " lang[ ]*=[ ]*[\"']stylus" style)
  4514. (setq element-content-type "stylus"))
  4515. ((string-match-p " lang[ ]*=[ ]*[\"']sass" style)
  4516. (setq element-content-type "sass"))
  4517. (t
  4518. (setq element-content-type "css"))
  4519. ) ;cond
  4520. ) ;let
  4521. ) ;style
  4522. ((string= tname "script")
  4523. (let (script)
  4524. (setq script (buffer-substring-no-properties tbeg tend)
  4525. part-close-tag "</script>")
  4526. (cond
  4527. ((string-match-p " type[ ]*=[ ]*[\"']text/\\(jsx\\|babel\\)" script)
  4528. (setq element-content-type "jsx"))
  4529. ((string-match-p " type[ ]*=[ ]*[\"']text/\\(markdown\\|template\\)" script)
  4530. (setq element-content-type "markdown"))
  4531. ((string-match-p " type[ ]*=[ ]*[\"']text/ruby" script)
  4532. (setq element-content-type "ruby"))
  4533. ((seq-some (lambda (x)
  4534. (string-match-p (concat "type[ ]*=[ ]*[\"']" x) script))
  4535. web-mode-script-template-types)
  4536. (setq element-content-type "html"
  4537. part-close-tag nil))
  4538. ((string-match-p " type[ ]*=[ ]*[\"']application/\\(ld\\+json\\|json\\)" script)
  4539. (setq element-content-type "json"))
  4540. ((string-match-p " lang[ ]*=[ ]*[\"']\\(typescript\\|ts\\)" script)
  4541. (setq element-content-type "typescript"))
  4542. (t
  4543. (setq element-content-type "javascript"))
  4544. ) ;cond
  4545. ) ;let
  4546. ) ;script
  4547. ((and (string= tname "template") (string-match-p " lang" (buffer-substring-no-properties tbeg tend)))
  4548. (let (template)
  4549. (setq template (buffer-substring-no-properties tbeg tend)
  4550. part-close-tag "</template>")
  4551. (cond
  4552. ((string-match-p " lang[ ]*=[ ]*[\"']pug" template)
  4553. (setq element-content-type "pug"))
  4554. (t
  4555. (setq element-content-type "html"))
  4556. ) ;cond
  4557. ) ;let
  4558. ) ;style
  4559. ((and (string= web-mode-engine "archibus")
  4560. (string= tname "sql"))
  4561. (setq element-content-type "sql"
  4562. part-close-tag "</sql>"))
  4563. )
  4564. (add-text-properties tbeg tend props)
  4565. (put-text-property tbeg (1+ tbeg) 'tag-beg flags)
  4566. (put-text-property (1- tend) tend 'tag-end t)
  4567. (when (and part-close-tag
  4568. (web-mode-dom-sf part-close-tag reg-end t)
  4569. (setq part-beg tend)
  4570. (setq part-end (match-beginning 0))
  4571. (> part-end part-beg))
  4572. (put-text-property part-beg part-end 'part-side
  4573. (intern element-content-type web-mode-obarray))
  4574. (setq tend part-end)
  4575. ) ;when
  4576. (goto-char tend)
  4577. ) ;while
  4578. )))
  4579. ;; FLAGS: attr
  4580. ;; (1)custom-attr (2)engine-attr (4)spread-attr[jsx] (8)code-value
  4581. ;; STATES: attr
  4582. ;; (0)nil (1)space (2)name (3)space-before (4)equal (5)space-after
  4583. ;; (6)value-uq (7)value-sq (8)value-dq (9)value-bq : jsx attr={}
  4584. (defun web-mode-attr-skip (limit)
  4585. (let ((tag-flags 0) (attr-flags 0) (continue t) (attrs 0) (counter 0) (brace-depth 0)
  4586. (pos-ori (point)) (state 0) (equal-offset 0) (go-back nil)
  4587. (is-jsx (or (string= web-mode-content-type "jsx") (eq (get-text-property (point) 'part-type) 'jsx)))
  4588. attr name-beg name-end val-beg char pos escaped spaced quoted)
  4589. (while continue
  4590. (setq pos (point)
  4591. char (char-after)
  4592. ;;spaced (eq char ?\s)
  4593. spaced (member char '(?\s ?\n))
  4594. )
  4595. (when quoted (setq quoted (1+ quoted)))
  4596. (cond
  4597. ((>= pos limit)
  4598. (setq continue nil)
  4599. (setq go-back t)
  4600. (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset)))
  4601. )
  4602. ((or (and (= state 8) (not (member char '(?\" ?\\))))
  4603. (and (= state 7) (not (member char '(?\' ?\\))))
  4604. (and (= state 9) (not (member char '(?} ?\\))))
  4605. )
  4606. (when (and (= state 9) (eq char ?\{))
  4607. (setq brace-depth (1+ brace-depth)))
  4608. )
  4609. ((and (= state 9) (eq char ?\}) (> brace-depth 1))
  4610. (setq brace-depth (1- brace-depth)))
  4611. ((get-text-property pos 'block-side)
  4612. (when (= state 2)
  4613. (setq name-end pos))
  4614. )
  4615. ((and (= state 2) is-jsx (eq char ?\}) (eq attr-flags 4))
  4616. (setq name-end pos)
  4617. (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset)))
  4618. (setq state 0
  4619. attr-flags 0
  4620. equal-offset 0
  4621. name-beg nil
  4622. name-end nil
  4623. val-beg nil)
  4624. )
  4625. ((or (and (= state 8) (eq ?\" char) (not escaped))
  4626. (and (= state 7) (eq ?\' char) (not escaped))
  4627. (and (= state 9) (eq ?\} char) (= brace-depth 1))
  4628. )
  4629. ;;(message "%S %S" (point) attr-flags)
  4630. (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset)))
  4631. (setq state 0
  4632. attr-flags 0
  4633. equal-offset 0
  4634. name-beg nil
  4635. name-end nil
  4636. val-beg nil)
  4637. )
  4638. ((and (member state '(4 5)) (member char '(?\' ?\" ?\{)))
  4639. (setq val-beg pos)
  4640. (setq quoted 1)
  4641. (setq state (cond ((eq ?\' char) 7)
  4642. ((eq ?\" char) 8)
  4643. (t 9)))
  4644. (when (= state 9)
  4645. (setq brace-depth 1))
  4646. )
  4647. ((and (eq ?\= char) (member state '(2 3)))
  4648. (setq equal-offset (- pos name-beg)
  4649. name-end (1- pos))
  4650. (setq state 4)
  4651. (setq attr (buffer-substring-no-properties name-beg (1+ name-end)))
  4652. (when (and web-mode-indentless-attributes (member (downcase attr) web-mode-indentless-attributes))
  4653. ;;(message "onclick")
  4654. (setq attr-flags (logior attr-flags 8)))
  4655. )
  4656. ((and spaced (= state 0))
  4657. (setq state 1)
  4658. )
  4659. ((and (eq char ?\<) (not (member state '(7 8 9))))
  4660. (setq continue nil)
  4661. (setq go-back t)
  4662. (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset)))
  4663. )
  4664. ((and (eq char ?\>) (not (member state '(7 8 9))))
  4665. (setq tag-flags (logior tag-flags 16))
  4666. (when (eq (char-before) ?\/)
  4667. (setq tag-flags (logior tag-flags 8))
  4668. )
  4669. (setq continue nil)
  4670. (when name-beg
  4671. (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset))))
  4672. )
  4673. ((and spaced (member state '(1 3 5)))
  4674. )
  4675. ((and spaced (= state 2))
  4676. (setq state 3)
  4677. )
  4678. ((and (eq char ?\/) (member state '(4 5)))
  4679. (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset)))
  4680. (setq state 1
  4681. attr-flags 0
  4682. equal-offset 0
  4683. name-beg nil
  4684. name-end nil
  4685. val-beg nil)
  4686. )
  4687. ((and (eq char ?\/) (member state '(0 1)))
  4688. )
  4689. ((and spaced (= state 4))
  4690. (setq state 5)
  4691. )
  4692. ((and (= state 3)
  4693. (or (and (>= char 97) (<= char 122)) ;a - z
  4694. (and (>= char 65) (<= char 90)) ;A - Z
  4695. (eq char ?\-)))
  4696. (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset)))
  4697. (setq state 2
  4698. attr-flags 0
  4699. equal-offset 0
  4700. name-beg pos
  4701. name-end pos
  4702. val-beg nil)
  4703. )
  4704. ((and (eq char ?\n) (not (member state '(7 8 9))))
  4705. (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset)))
  4706. (setq state 1
  4707. attr-flags 0
  4708. equal-offset 0
  4709. name-beg nil
  4710. name-end nil
  4711. val-beg nil)
  4712. )
  4713. ((and (= state 6) (member char '(?\s ?\n ?\/)))
  4714. (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset)))
  4715. (setq state 1
  4716. attr-flags 0
  4717. equal-offset 0
  4718. name-beg nil
  4719. name-end nil
  4720. val-beg nil)
  4721. )
  4722. ((and quoted (= quoted 2) (member char '(?\s ?\n ?\>)))
  4723. (when (eq char ?\>)
  4724. (setq tag-flags (logior tag-flags 16))
  4725. (setq continue nil))
  4726. (setq state 6)
  4727. (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset)))
  4728. (setq state 1
  4729. attr-flags 0
  4730. equal-offset 0
  4731. name-beg nil
  4732. name-end nil
  4733. val-beg nil)
  4734. )
  4735. ((and (not spaced) (= state 1))
  4736. (when (and is-jsx (eq char ?\{))
  4737. (setq attr-flags 4))
  4738. (setq state 2)
  4739. (setq name-beg pos
  4740. name-end pos)
  4741. )
  4742. ((member state '(4 5))
  4743. (setq val-beg pos)
  4744. (setq state 6)
  4745. )
  4746. ((= state 1)
  4747. (setq state 2)
  4748. )
  4749. ((= state 2)
  4750. (setq name-end pos)
  4751. (when (and nil (= attr-flags 0) (member char '(?\- ?\:)))
  4752. (let (attr)
  4753. (setq attr (buffer-substring-no-properties name-beg (1+ name-end)))
  4754. (cond
  4755. ((member attr '("http-equiv"))
  4756. (setq attr-flags (1- attr-flags))
  4757. )
  4758. ;;((and web-mode-engine-attr-regexp
  4759. ;; (string-match-p web-mode-engine-attr-regexp attr))
  4760. ;; (setq attr-flags (logior attr-flags 2))
  4761. ;; )
  4762. ((and (eq char ?\-) (not (string= attr "http-")))
  4763. (setq attr-flags (logior attr-flags 1)))
  4764. ) ;cond
  4765. ) ;let
  4766. ) ;when attr-flags = 1
  4767. ) ;state=2
  4768. ) ;cond
  4769. ;;(message "point(%S) end(%S) state(%S) c(%S) name-beg(%S) name-end(%S) val-beg(%S) attr-flags(%S) equal-offset(%S)" pos end state char name-beg name-end val-beg attr-flags equal-offset)
  4770. (when (and quoted (>= quoted 2))
  4771. (setq quoted nil))
  4772. (setq escaped (eq ?\\ char))
  4773. (when (null go-back)
  4774. (forward-char))
  4775. ) ;while
  4776. (when (> attrs 0) (setq tag-flags (logior tag-flags 1)))
  4777. tag-flags))
  4778. (defun web-mode-attr-scan (state char name-beg name-end val-beg flags equal-offset)
  4779. ;;(message "point(%S) state(%S) c(%c) name-beg(%S) name-end(%S) val-beg(%S) flags(%S) equal-offset(%S)"
  4780. ;; (point) state char name-beg name-end val-beg flags equal-offset)
  4781. (when (null flags) (setq flags 0))
  4782. (when (and name-beg name-end web-mode-engine-attr-regexp)
  4783. (let (name)
  4784. (setq name (buffer-substring-no-properties name-beg (1+ name-end)))
  4785. ;;(message "%S" name)
  4786. (cond
  4787. ((string-match-p "^data[-]" name)
  4788. (setq flags (logior flags 1))
  4789. )
  4790. ((string-match-p web-mode-engine-attr-regexp name)
  4791. (setq flags (logior flags 2))
  4792. )
  4793. )
  4794. ) ;name
  4795. )
  4796. ;;(message "%S" name)
  4797. (cond
  4798. ((null name-beg)
  4799. ;; (message "name-beg is null (%S)" (point))
  4800. 0)
  4801. ((or (and (= state 8) (not (eq ?\" char)))
  4802. (and (= state 7) (not (eq ?\' char))))
  4803. (put-text-property name-beg (1+ name-beg) 'tag-attr-beg flags)
  4804. (put-text-property name-beg val-beg 'tag-attr t)
  4805. (put-text-property (1- val-beg) val-beg 'tag-attr-end equal-offset)
  4806. 1)
  4807. ((and (member state '(4 5)) (null val-beg))
  4808. (put-text-property name-beg (1+ name-beg) 'tag-attr-beg flags)
  4809. (put-text-property name-beg (+ name-beg equal-offset 1) 'tag-attr t)
  4810. (put-text-property (+ name-beg equal-offset) (+ name-beg equal-offset 1) 'tag-attr-end equal-offset)
  4811. 1)
  4812. (t
  4813. (let (val-end)
  4814. (if (null val-beg)
  4815. (setq val-end name-end)
  4816. (setq val-end (point))
  4817. (when (or (null char) (member char '(?\s ?\n ?\> ?\/)))
  4818. (setq val-end (1- val-end))
  4819. )
  4820. ) ;if
  4821. (put-text-property name-beg (1+ name-beg) 'tag-attr-beg flags)
  4822. (put-text-property name-beg (1+ val-end) 'tag-attr t)
  4823. (put-text-property val-end (1+ val-end) 'tag-attr-end equal-offset)
  4824. ) ;let
  4825. 1) ;t
  4826. ) ;cond
  4827. )
  4828. (defun web-mode-part-foreach (reg-beg reg-end func)
  4829. (let ((i 0) (continue t) (part-beg reg-beg) (part-end nil))
  4830. (while continue
  4831. (setq part-end nil)
  4832. (unless (get-text-property part-beg 'part-side)
  4833. (setq part-beg (web-mode-part-next-position part-beg)))
  4834. (when (and part-beg (< part-beg reg-end))
  4835. (setq part-end (web-mode-part-end-position part-beg)))
  4836. (cond
  4837. ((> (setq i (1+ i)) 100)
  4838. (message "process-parts ** warning (%S) **" (point))
  4839. (setq continue nil))
  4840. ((or (null part-end) (> part-end reg-end))
  4841. (setq continue nil))
  4842. (t
  4843. (setq part-end (1+ part-end))
  4844. (funcall func part-beg part-end)
  4845. (setq part-beg part-end))
  4846. ) ;cond
  4847. ) ;while
  4848. ))
  4849. (defun web-mode-part-scan (reg-beg reg-end &optional content-type depth)
  4850. (save-excursion
  4851. (let (token-re ch-before ch-at ch-next token-type beg continue)
  4852. ;;(message "%S %S" reg-beg reg-end)
  4853. (cond
  4854. (content-type
  4855. )
  4856. ((member web-mode-content-type web-mode-part-content-types)
  4857. (setq content-type web-mode-content-type))
  4858. (t
  4859. (setq content-type (symbol-name (get-text-property reg-beg 'part-side))))
  4860. ) ;cond
  4861. (goto-char reg-beg)
  4862. (cond
  4863. ((member content-type '("javascript" "json"))
  4864. (setq token-re "/\\|\"\\|'\\|`"))
  4865. ((member content-type '("typescript"))
  4866. (setq token-re "\"\\|'\\|`\\|//\\|/\\*"))
  4867. ((member content-type '("jsx"))
  4868. (setq token-re "/\\|\"\\|'\\|`\\|</?[[:alpha:]>]"))
  4869. ((string= web-mode-content-type "css")
  4870. (setq token-re "\"\\|'\\|/\\*\\|//"))
  4871. ((string= content-type "css")
  4872. (setq token-re "\"\\|'\\|/\\*"))
  4873. (t
  4874. (setq token-re "/\\*\\|\"\\|'"))
  4875. )
  4876. (while (and token-re (< (point) reg-end) (web-mode-dom-rsf token-re reg-end t))
  4877. (setq beg (match-beginning 0)
  4878. token-type nil
  4879. continue t
  4880. ch-at (char-after beg)
  4881. ch-next (or (char-after (1+ beg)) ?\d)
  4882. ch-before (or (char-before beg) ?\d))
  4883. ;;(message "[%S>%S|%S] %S %c %c %c" reg-beg reg-end depth beg ch-before ch-at ch-next)
  4884. (cond
  4885. ((eq ?\' ch-at)
  4886. (while (and continue (search-forward "'" reg-end t))
  4887. (cond
  4888. ((get-text-property (1- (point)) 'block-side)
  4889. (setq continue t))
  4890. (t
  4891. (setq continue (web-mode-string-continue-p reg-beg)))
  4892. )
  4893. ) ;while
  4894. (setq token-type 'string))
  4895. ((eq ?\` ch-at)
  4896. (while (and continue (search-forward "`" reg-end t))
  4897. (cond
  4898. ((get-text-property (1- (point)) 'block-side)
  4899. (setq continue t))
  4900. (t
  4901. (setq continue (web-mode-string-continue-p reg-beg)))
  4902. )
  4903. ) ;while
  4904. (setq token-type 'string))
  4905. ((eq ?\" ch-at)
  4906. (while (and continue (search-forward "\"" reg-end t))
  4907. (cond
  4908. ((get-text-property (1- (point)) 'block-side)
  4909. (setq continue t))
  4910. (t
  4911. (setq continue (web-mode-string-continue-p reg-beg)))
  4912. ) ;cond
  4913. ) ;while
  4914. (cond
  4915. ((string= content-type "json")
  4916. (if (looking-at-p "[ ]*:")
  4917. (cond
  4918. ((eq ?\@ (char-after (1+ beg)))
  4919. (setq token-type 'context))
  4920. (t
  4921. (setq token-type 'key))
  4922. )
  4923. (setq token-type 'string))
  4924. ) ;json
  4925. (t
  4926. (setq token-type 'string))
  4927. ) ;cond
  4928. )
  4929. ((and (eq ?\< ch-at)
  4930. (not (or (and (>= ch-before 97) (<= ch-before 122))
  4931. (and (>= ch-before 65) (<= ch-before 90)))))
  4932. ;;(message "before [%S>%S|%S] pt=%S" reg-beg reg-end depth (point))
  4933. (search-backward "<")
  4934. (if (web-mode-jsx-skip reg-end)
  4935. (web-mode-jsx-scan-element beg (point) depth)
  4936. (forward-char))
  4937. ;;(message "after [%S>%S|%S] pt=%S" reg-beg reg-end depth (point))
  4938. )
  4939. ((and (eq ?\/ ch-at) (member content-type '("javascript" "jsx")))
  4940. (cond
  4941. ((eq ?\\ ch-before)
  4942. )
  4943. ((eq ?\* ch-next)
  4944. ;;(message "--> %S %S" (point) reg-end)
  4945. (when (search-forward "*/" reg-end t)
  4946. (setq token-type 'comment))
  4947. )
  4948. ((eq ?\/ ch-next)
  4949. (setq token-type 'comment)
  4950. (goto-char (if (< reg-end (line-end-position)) reg-end (line-end-position)))
  4951. )
  4952. ((and (looking-at-p ".*/")
  4953. (looking-back "\\(^\\|case\\|[[(,=:!&|?{};]\\)[ ]*/" (point-min)))
  4954. ;;(re-search-forward "/[gimyu]*" reg-end t))
  4955. (let ((eol (line-end-position)))
  4956. (while (and continue (search-forward "/" eol t))
  4957. (cond
  4958. ((get-text-property (1- (point)) 'block-side)
  4959. (setq continue t))
  4960. ((looking-back "\\\\+/" reg-beg t)
  4961. (setq continue (= (mod (- (point) (match-beginning 0)) 2) 0)))
  4962. (t
  4963. (re-search-forward "[gimyu]*" eol t)
  4964. (setq token-type 'string)
  4965. (setq continue nil))
  4966. )
  4967. ) ;while
  4968. ) ;let
  4969. )
  4970. ) ;cond
  4971. )
  4972. ((eq ?\/ ch-next)
  4973. ;;(message "%S" (point))
  4974. (cond
  4975. ((and (string= content-type "css")
  4976. (eq ?/ ch-at)
  4977. (eq ?: ch-before))
  4978. )
  4979. (t
  4980. (unless (eq ?\\ ch-before)
  4981. (setq token-type 'comment)
  4982. (goto-char (if (< reg-end (line-end-position)) reg-end (line-end-position)))
  4983. )
  4984. )
  4985. )
  4986. )
  4987. ((eq ?\* ch-next)
  4988. (cond
  4989. ((search-forward "*/" reg-end t)
  4990. (setq token-type 'comment))
  4991. ((not (eobp))
  4992. (forward-char))
  4993. ) ;cond
  4994. )
  4995. ) ;cond
  4996. (when (and beg (>= reg-end (point)) token-type)
  4997. (put-text-property beg (point) 'part-token token-type)
  4998. (cond
  4999. ((eq token-type 'comment)
  5000. (put-text-property beg (1+ beg) 'syntax-table (string-to-syntax "<"))
  5001. (when (< (point) (point-max))
  5002. (if (< (point) (line-end-position))
  5003. (put-text-property (1- (point)) (point) 'syntax-table (string-to-syntax ">")) ;#445
  5004. (put-text-property (point) (1+ (point)) 'syntax-table (string-to-syntax ">")) ;#377
  5005. )
  5006. ) ;when
  5007. ) ;comment
  5008. ((eq token-type 'string)
  5009. (put-text-property beg (1+ beg) 'syntax-table (string-to-syntax "|"))
  5010. (when (< (point) (point-max))
  5011. (if (< (point) (line-end-position))
  5012. (put-text-property (1- (point)) (point) 'syntax-table (string-to-syntax "|"))
  5013. (put-text-property (point) (1+ (point)) 'syntax-table (string-to-syntax "|"))
  5014. )
  5015. ) ;when
  5016. ) ;string
  5017. ) ;cond
  5018. ) ;when
  5019. (when (> (point) reg-end)
  5020. (message "reg-beg(%S) reg-end(%S) token-type(%S) point(%S)" reg-beg reg-end token-type (point)))
  5021. ;;(message "#[%S>%S|%S] %S %c %c %c | (%S)" reg-beg reg-end depth beg ch-before ch-at ch-next (point))
  5022. ) ;while
  5023. )))
  5024. (defun web-mode-string-continue-p (reg-beg)
  5025. "Is `point' preceeded by an odd number of backslashes?"
  5026. (let ((p (1- (point))))
  5027. (while (and (< reg-beg p) (eq ?\\ (char-before p)))
  5028. (setq p (1- p)))
  5029. (= (mod (- (point) p) 2) 0)))
  5030. ;; css rule = selector(s) + declaration (properties)
  5031. (defun web-mode-css-rule-next (limit)
  5032. (let (at-rule var-rule sel-beg sel-end dec-beg dec-end chunk)
  5033. (skip-chars-forward "\n\t ")
  5034. (setq sel-beg (point))
  5035. (when (and (< (point) limit)
  5036. (web-mode-part-rsf "[{;]" limit))
  5037. (setq sel-end (1- (point)))
  5038. (cond
  5039. ((eq (char-before) ?\{)
  5040. (setq dec-beg (point))
  5041. (setq dec-end (web-mode-closing-paren-position (1- dec-beg) limit))
  5042. (if dec-end
  5043. (progn
  5044. (goto-char dec-end)
  5045. (forward-char))
  5046. (setq dec-end limit)
  5047. (goto-char limit))
  5048. )
  5049. (t
  5050. )
  5051. ) ;cond
  5052. (setq chunk (buffer-substring-no-properties sel-beg sel-end))
  5053. (cond
  5054. ((string-match "@\\([[:alpha:]-]+\\)" chunk)
  5055. (setq at-rule (match-string-no-properties 1 chunk)))
  5056. ((string-match "\\$\\([[:alpha:]-]+\\)" chunk)
  5057. (setq var-rule (match-string-no-properties 1 chunk)))
  5058. ) ;cond
  5059. ) ;when
  5060. (if (not sel-end)
  5061. (progn (goto-char limit) nil)
  5062. (list :at-rule at-rule
  5063. :var-rule var-rule
  5064. :sel-beg sel-beg
  5065. :sel-end sel-end
  5066. :dec-beg dec-beg
  5067. :dec-end dec-end)
  5068. ) ;if
  5069. ))
  5070. (defun web-mode-css-rule-current (&optional pos part-beg part-end)
  5071. "Current CSS rule boundaries."
  5072. (unless pos (setq pos (point)))
  5073. (unless part-beg (setq part-beg (web-mode-part-beginning-position pos)))
  5074. (unless part-end (setq part-end (web-mode-part-end-position pos)))
  5075. (save-excursion
  5076. (let (beg end)
  5077. (goto-char pos)
  5078. (if (not (web-mode-part-sb "{" part-beg))
  5079. (progn
  5080. (setq beg part-beg)
  5081. (if (web-mode-part-sf ";" part-end)
  5082. (setq end (1+ (point)))
  5083. (setq end part-end))
  5084. ) ;progn
  5085. (setq beg (point))
  5086. (setq end (web-mode-closing-paren-position beg part-end))
  5087. (if end
  5088. (setq end (1+ end))
  5089. (setq end (line-end-position)))
  5090. ;; (message "%S >>beg%S >>end%S" pos beg end)
  5091. (if (> pos end)
  5092. ;;selectors
  5093. (progn
  5094. (goto-char pos)
  5095. (if (web-mode-part-rsb "[};]" part-beg)
  5096. (setq beg (1+ (point)))
  5097. (setq beg part-beg)
  5098. ) ;if
  5099. (goto-char pos)
  5100. (if (web-mode-part-rsf "[{;]" part-end)
  5101. (cond
  5102. ((eq (char-before) ?\;)
  5103. (setq end (point))
  5104. )
  5105. (t
  5106. (setq end (web-mode-closing-paren-position (1- (point)) part-end))
  5107. (if end
  5108. (setq end (1+ end))
  5109. (setq end part-end))
  5110. )
  5111. ) ;cond
  5112. (setq end part-end)
  5113. )
  5114. ) ;progn selectors
  5115. ;; declaration
  5116. (goto-char beg)
  5117. (if (web-mode-part-rsb "[}{;]" part-beg)
  5118. (setq beg (1+ (point)))
  5119. (setq beg part-beg)
  5120. ) ;if
  5121. ) ;if > pos end
  5122. )
  5123. ;; (message "beg(%S) end(%S)" beg end)
  5124. (when (eq (char-after beg) ?\n)
  5125. (setq beg (1+ beg)))
  5126. (cons beg end)
  5127. )))
  5128. (defun web-mode-jsx-skip (reg-end)
  5129. (let ((continue t) (pos nil) (i 0) tag)
  5130. (looking-at "<\\([[:alpha:]][[:alnum:]:-]*\\)")
  5131. (setq tag (match-string-no-properties 1))
  5132. ;;(message "point=%S tag=%S" (point) tag)
  5133. (save-excursion
  5134. (while continue
  5135. (cond
  5136. ((> (setq i (1+ i)) 1000)
  5137. (message "jsx-skip ** warning **")
  5138. (setq continue nil))
  5139. ((looking-at "<[[:alpha:]][[:alnum:]:-]*[ ]*/>")
  5140. (goto-char (match-end 0))
  5141. (setq pos (point))
  5142. (setq continue nil))
  5143. ((not (web-mode-dom-rsf ">\\([ \t\n]*[\];,)':}|&]\\)\\|{" reg-end))
  5144. (setq continue nil)
  5145. )
  5146. ((eq (char-before) ?\{)
  5147. (backward-char)
  5148. (web-mode-closing-paren reg-end)
  5149. (forward-char)
  5150. )
  5151. (t
  5152. (setq continue nil)
  5153. (setq pos (match-beginning 1))
  5154. ) ;t
  5155. ) ;cond
  5156. ) ;while
  5157. ) ;save-excursion
  5158. (when pos (goto-char pos))
  5159. ;;(message "jsx-skip: %S" pos)
  5160. pos))
  5161. ;; (defun web-mode-jsx-skip2 (reg-end)
  5162. ;; (let ((continue t) (pos nil) (i 0) (tag nil) (regexp nil) (counter 1))
  5163. ;; (looking-at "<\\([[:alpha:]][[:alnum:]:-]*\\)")
  5164. ;; (setq tag (match-string-no-properties 1))
  5165. ;; (setq regexp (concat "</?" tag))
  5166. ;; ;;(message "point=%S tag=%S" (point) tag)
  5167. ;; (save-excursion
  5168. ;; (while continue
  5169. ;; (cond
  5170. ;; ((> (setq i (1+ i)) 100)
  5171. ;; (message "jsx-skip ** warning **")
  5172. ;; (setq continue nil))
  5173. ;; ((looking-at "<[[:alpha:]][[:alnum:]:-]*[ ]*/>")
  5174. ;; (goto-char (match-end 0))
  5175. ;; (setq pos (point))
  5176. ;; (setq continue nil))
  5177. ;; ((not (web-mode-dom-rsf ">\\([ \t\n]*[\];,)':}]\\)\\|{" reg-end))
  5178. ;; (setq continue nil)
  5179. ;; )
  5180. ;; ((eq (char-before) ?\{)
  5181. ;; (backward-char)
  5182. ;; (web-mode-closing-paren reg-end)
  5183. ;; (forward-char)
  5184. ;; )
  5185. ;; (t
  5186. ;; (setq continue nil)
  5187. ;; (setq pos (match-beginning 1))
  5188. ;; ) ;t
  5189. ;; ) ;cond
  5190. ;; ) ;while
  5191. ;; ) ;save-excursion
  5192. ;; (when pos (goto-char pos))
  5193. ;; ;;(message "jsx-skip: %S" pos)
  5194. ;; pos))
  5195. ;; http://facebook.github.io/jsx/
  5196. ;; https://github.com/facebook/jsx/blob/master/AST.md
  5197. (defun web-mode-jsx-scan-element (reg-beg reg-end depth)
  5198. (unless depth (setq depth 1))
  5199. (save-excursion
  5200. (let (token-beg token-end regexp)
  5201. (goto-char reg-beg)
  5202. (put-text-property reg-beg (1+ reg-beg) 'jsx-beg depth)
  5203. (put-text-property (1- reg-end) reg-end 'jsx-end depth)
  5204. (put-text-property reg-beg reg-end 'jsx-depth depth)
  5205. (goto-char reg-beg)
  5206. (web-mode-scan-elements reg-beg reg-end)
  5207. (web-mode-jsx-scan-expression reg-beg reg-end (1+ depth))
  5208. )))
  5209. (defun web-mode-jsx-scan-expression (reg-beg reg-end depth)
  5210. (let ((continue t) beg end)
  5211. (save-excursion
  5212. (goto-char reg-beg)
  5213. ;;(message "reg-beg=%S reg-end=%S" reg-beg reg-end)
  5214. (while (and continue (search-forward "{" reg-end t))
  5215. (backward-char)
  5216. (setq beg (point)
  5217. end (web-mode-closing-paren reg-end))
  5218. (cond
  5219. ((eq (get-text-property beg 'part-token) 'comment)
  5220. (forward-char))
  5221. ((not end)
  5222. (setq continue nil))
  5223. (t
  5224. (setq end (1+ end))
  5225. (put-text-property beg end 'jsx-depth depth)
  5226. (put-text-property beg (1+ beg) 'jsx-beg depth)
  5227. (put-text-property (1- end) end 'jsx-end depth)
  5228. (web-mode-part-scan beg end "jsx" (1+ depth))
  5229. ) ;t
  5230. ) ;cond
  5231. ) ;while
  5232. ) ;save-excursion
  5233. ))
  5234. (defun web-mode-jsx-is-html (&optional pos)
  5235. (interactive)
  5236. (unless pos (setq pos (point)))
  5237. (let (ret (depth (get-text-property pos 'jsx-depth)))
  5238. (cond
  5239. ((or (null depth) (<= pos 2))
  5240. (setq pos nil))
  5241. ((and (= depth 1) (get-text-property pos 'jsx-beg))
  5242. (setq pos nil))
  5243. ((get-text-property pos 'tag-end)
  5244. (setq pos nil))
  5245. ((get-text-property pos 'tag-attr-beg)
  5246. (setq pos nil))
  5247. ((get-text-property pos 'jsx-beg)
  5248. (setq pos (null (get-text-property pos 'tag-beg))))
  5249. ((setq pos (web-mode-jsx-depth-beginning-position pos))
  5250. (setq pos (not (null (get-text-property pos 'tag-beg)))))
  5251. (t
  5252. (setq pos nil))
  5253. ) ;cond
  5254. ;;(message "is-html: %S (depth=%S)" pos depth)
  5255. pos))
  5256. (defun web-mode-jsx-is-expr (&optional pos)
  5257. (cond
  5258. ((and (get-text-property pos 'jsx-beg)
  5259. (not (get-text-property pos 'tag-beg)))
  5260. nil)
  5261. (t
  5262. (setq pos (web-mode-jsx-depth-beginning-position pos))
  5263. (null (get-text-property pos 'tag-beg)))
  5264. ) ;cond
  5265. )
  5266. (defun web-mode-jsx-depth-beginning-position (&optional pos target-depth)
  5267. (interactive)
  5268. (unless pos (setq pos (point)))
  5269. (unless target-depth (setq target-depth (get-text-property pos 'jsx-depth)))
  5270. (cond
  5271. ((or (null target-depth) (bobp))
  5272. (setq pos nil))
  5273. ((and (get-text-property pos 'jsx-beg) (= target-depth (get-text-property pos 'jsx-depth)))
  5274. )
  5275. (t
  5276. (let ((continue t) depth)
  5277. (while continue
  5278. (setq pos (previous-single-property-change pos 'jsx-depth))
  5279. (cond
  5280. ((or (null pos)
  5281. (null (setq depth (get-text-property pos 'jsx-depth))))
  5282. (setq continue nil
  5283. pos nil))
  5284. ((and (get-text-property pos 'jsx-beg) (= target-depth depth))
  5285. (setq continue nil))
  5286. ) ;cond
  5287. ) ;while
  5288. ) ;let
  5289. ) ;t
  5290. ) ;cond
  5291. ;;(message "beg: %S" pos)
  5292. pos)
  5293. (defun web-mode-jsx-element-next (reg-end)
  5294. (let (continue beg end)
  5295. (setq beg (point))
  5296. (unless (get-text-property beg 'jsx-depth)
  5297. (setq beg (next-single-property-change beg 'jsx-beg)))
  5298. (setq continue (and beg (< beg reg-end))
  5299. end beg)
  5300. (while continue
  5301. (setq end (next-single-property-change end 'jsx-end))
  5302. (cond
  5303. ((or (null end) (> end reg-end))
  5304. (setq continue nil
  5305. end nil))
  5306. ((eq (get-text-property end 'jsx-depth) 1)
  5307. (setq continue nil))
  5308. (t
  5309. (setq end (1+ end)))
  5310. ) ;cond
  5311. ) ;while
  5312. ;;(message "beg=%S end=%S" beg end)
  5313. (if (and beg end (< beg end)) (cons beg end) nil)))
  5314. (defun web-mode-jsx-expression-next (reg-end)
  5315. (let (beg end depth continue pos)
  5316. (setq beg (point))
  5317. ;;(message "pt=%S" beg)
  5318. (unless (and (get-text-property beg 'jsx-beg) (null (get-text-property beg 'tag-beg)))
  5319. ;;(setq beg (next-single-property-change beg 'jsx-beg))
  5320. (setq continue t
  5321. pos (1+ beg))
  5322. (while continue
  5323. (setq pos (next-single-property-change pos 'jsx-beg))
  5324. (cond
  5325. ((null pos)
  5326. (setq continue nil
  5327. beg nil))
  5328. ((> pos reg-end)
  5329. (setq continue nil
  5330. beg nil))
  5331. ((null (get-text-property pos 'jsx-beg))
  5332. )
  5333. ((null (get-text-property pos 'tag-beg))
  5334. (setq continue nil
  5335. beg pos))
  5336. ;;(t
  5337. ;; (setq pos (1+ pos)))
  5338. ) ;cond
  5339. ) ;while
  5340. ) ;unless
  5341. ;;(message "beg=%S" beg)
  5342. (when (and beg (< beg reg-end))
  5343. (setq depth (get-text-property beg 'jsx-beg)
  5344. continue (not (null depth))
  5345. pos beg)
  5346. ;;(message "beg=%S" beg)
  5347. (while continue
  5348. (setq pos (next-single-property-change pos 'jsx-end))
  5349. ;;(message "pos=%S" pos)
  5350. (cond
  5351. ((null pos)
  5352. (setq continue nil))
  5353. ((> pos reg-end)
  5354. (setq continue nil))
  5355. ((eq depth (get-text-property pos 'jsx-end))
  5356. (setq continue nil
  5357. end pos))
  5358. (t
  5359. ;;(setq pos (1+ pos))
  5360. )
  5361. ) ;cond
  5362. ) ;while
  5363. ) ;when
  5364. ;;(message "%S > %S" beg end)
  5365. (if (and beg end) (cons beg end) nil)))
  5366. (defun web-mode-jsx-depth-next (reg-end)
  5367. (let (beg end depth continue pos)
  5368. (setq beg (point))
  5369. ;;(message "pt=%S" beg)
  5370. (unless (get-text-property beg 'jsx-beg)
  5371. ;;(setq beg (next-single-property-change beg 'jsx-beg))
  5372. ;;(setq pos (1+ beg))
  5373. (setq pos (next-single-property-change (1+ beg) 'jsx-beg))
  5374. (cond
  5375. ((null pos)
  5376. (setq beg nil))
  5377. ((>= pos reg-end)
  5378. (setq beg nil))
  5379. (t
  5380. (setq beg pos))
  5381. ) ;cond
  5382. ) ;unless
  5383. ;;(message "beg=%S" beg)
  5384. (when beg
  5385. (setq depth (get-text-property beg 'jsx-beg)
  5386. continue (not (null depth))
  5387. pos beg)
  5388. ;;(message "beg=%S" beg)
  5389. (while continue
  5390. (setq pos (next-single-property-change pos 'jsx-end))
  5391. ;;(message "pos=%S" pos)
  5392. (cond
  5393. ((null pos)
  5394. (setq continue nil))
  5395. ((> pos reg-end)
  5396. (setq continue nil))
  5397. ((eq depth (get-text-property pos 'jsx-end))
  5398. (setq continue nil
  5399. end pos))
  5400. (t
  5401. ;;(setq pos (1+ pos))
  5402. )
  5403. ) ;cond
  5404. ) ;while
  5405. ) ;when
  5406. ;;(message "%S > %S" beg end)
  5407. (if (and beg end) (cons beg end) nil)))
  5408. (defun web-mode-jsx-beginning ()
  5409. (interactive)
  5410. (let (depth (continue t) (reg-beg (point-min)) (pos (point)))
  5411. (setq depth (get-text-property pos 'jsx-depth))
  5412. (cond
  5413. ((not depth)
  5414. )
  5415. ((get-text-property (1- pos) 'jsx-beg)
  5416. (goto-char (1- pos)))
  5417. (t
  5418. (while continue
  5419. (setq pos (previous-single-property-change pos 'jsx-beg))
  5420. ;;(message "pos=%S" pos)
  5421. (cond
  5422. ((null pos)
  5423. (setq continue nil))
  5424. ((<= pos reg-beg)
  5425. (setq continue nil))
  5426. ((eq depth (get-text-property pos 'jsx-beg))
  5427. (setq continue nil))
  5428. ) ;cond
  5429. ) ;while
  5430. (web-mode-go pos)
  5431. ) ;t
  5432. ) ;cond
  5433. ))
  5434. (defun web-mode-jsx-end ()
  5435. (interactive)
  5436. (let (depth (continue t) (reg-end (point-max)) (pos (point)))
  5437. (setq depth (get-text-property pos 'jsx-depth))
  5438. (cond
  5439. ((not depth)
  5440. )
  5441. ((get-text-property pos 'jsx-end)
  5442. (goto-char (+ pos 1)))
  5443. (t
  5444. (while continue
  5445. (setq pos (next-single-property-change pos 'jsx-end))
  5446. ;;(message "pos=%S" pos)
  5447. (cond
  5448. ((null pos)
  5449. (setq continue nil))
  5450. ((> pos reg-end)
  5451. (setq continue nil))
  5452. ((eq depth (get-text-property pos 'jsx-end))
  5453. (setq continue nil))
  5454. ) ;cond
  5455. ) ;while
  5456. (web-mode-go pos 1)
  5457. ) ;t
  5458. ) ;cond
  5459. ))
  5460. ;;---- FONTIFICATION -----------------------------------------------------------
  5461. ;; 1/ after-change
  5462. ;; 2/ extend-region
  5463. ;; 3/ scan
  5464. ;; 4/ fontify
  5465. ;; 5/ post-command
  5466. (defun web-mode-extend-region ()
  5467. ;;(message "extend-region: flb(%S) fle(%S) wmcb(%S) wmce(%S)" font-lock-beg font-lock-end web-mode-change-beg web-mode-change-end)
  5468. (cond
  5469. (web-mode-fontification-off
  5470. nil)
  5471. (t
  5472. (when (or (null web-mode-change-beg) (< font-lock-beg web-mode-change-beg))
  5473. ;;(message "font-lock-beg(%S) < web-mode-change-beg(%S)" font-lock-beg web-mode-change-beg)
  5474. (setq web-mode-change-beg font-lock-beg))
  5475. (when (or (null web-mode-change-end) (> font-lock-end web-mode-change-end))
  5476. ;;(message "font-lock-end(%S) > web-mode-change-end(%S)" font-lock-end web-mode-change-end)
  5477. (setq web-mode-change-end font-lock-end))
  5478. (let ((region (web-mode-scan web-mode-change-beg web-mode-change-end)))
  5479. (when region
  5480. ;;(message "region: %S" region)
  5481. (setq font-lock-beg (car region)
  5482. font-lock-end (cdr region))
  5483. ) ;when
  5484. ) ;let
  5485. nil) ;t
  5486. ))
  5487. (defun web-mode-fontify (limit)
  5488. ;;(message "fontify: point(%S) limit(%S) change-beg(%S) change-end(%S)" (point) limit web-mode-change-beg web-mode-change-end)
  5489. (cond
  5490. (web-mode-fontification-off
  5491. nil)
  5492. (t
  5493. (web-mode-with-silent-modifications
  5494. (save-excursion
  5495. (save-restriction
  5496. (save-match-data
  5497. (let ((beg (point))
  5498. (buffer-undo-list t)
  5499. (end limit)
  5500. (inhibit-point-motion-hooks t)
  5501. (inhibit-quit t))
  5502. (remove-list-of-text-properties beg end '(font-lock-face face))
  5503. (cond
  5504. ((and (get-text-property beg 'block-side)
  5505. (not (get-text-property beg 'block-beg)))
  5506. (web-mode-fontify-block beg end))
  5507. ((or (member web-mode-content-type web-mode-part-content-types)
  5508. (get-text-property beg 'part-side))
  5509. (web-mode-fontify-part beg end)
  5510. (web-mode-block-foreach beg end 'web-mode-fontify-block))
  5511. ((string= web-mode-engine "none")
  5512. (web-mode-fontify-tags beg end)
  5513. (web-mode-part-foreach beg end 'web-mode-fontify-part))
  5514. (t
  5515. (web-mode-fontify-tags beg end)
  5516. (web-mode-part-foreach beg end 'web-mode-fontify-part)
  5517. (web-mode-block-foreach beg end 'web-mode-fontify-block))
  5518. ) ;cond
  5519. (when web-mode-enable-element-content-fontification
  5520. (web-mode-fontify-elements beg end))
  5521. (when web-mode-enable-whitespace-fontification
  5522. (web-mode-fontify-whitespaces beg end))
  5523. ) ;let
  5524. ))))
  5525. nil) ;t
  5526. ))
  5527. (defun web-mode-buffer-fontify ()
  5528. (interactive)
  5529. (cond
  5530. ((and (fboundp 'font-lock-flush) global-font-lock-mode)
  5531. (font-lock-flush)
  5532. (font-lock-ensure))
  5533. (t ;emacs 24
  5534. ;;(font-lock-fontify-buffer)
  5535. (and global-font-lock-mode
  5536. (font-lock-fontify-region (point-min) (point-max))))
  5537. ))
  5538. (defun web-mode-unfontify-region (beg end)
  5539. ;;(message "unfontify: %S %S" beg end)
  5540. )
  5541. (defun web-mode-fontify-region (beg end keywords)
  5542. ;; (message "beg=%S end=%S keywords=%S" beg end (symbol-name keywords))
  5543. (save-excursion
  5544. (let ((font-lock-keywords keywords)
  5545. (font-lock-multiline nil)
  5546. (font-lock-keywords-case-fold-search
  5547. (member web-mode-engine '("archibus" "asp" "template-toolkit")))
  5548. (font-lock-keywords-only t)
  5549. (font-lock-extend-region-functions nil))
  5550. (when (and (listp font-lock-keywords) global-font-lock-mode)
  5551. (font-lock-fontify-region beg end)
  5552. )
  5553. )))
  5554. (defun web-mode-fontify-tags (reg-beg reg-end &optional depth)
  5555. (let ((continue t))
  5556. (goto-char reg-beg)
  5557. (when (and (not (get-text-property (point) 'tag-beg))
  5558. (not (web-mode-tag-next)))
  5559. (setq continue nil))
  5560. (when (and continue (>= (point) reg-end))
  5561. (setq continue nil))
  5562. (while continue
  5563. (cond
  5564. (depth
  5565. (when (eq depth (get-text-property (point) 'jsx-depth))
  5566. (web-mode-fontify-tag))
  5567. )
  5568. (t
  5569. (web-mode-fontify-tag))
  5570. ) ;cond
  5571. (when (or (not (web-mode-tag-next))
  5572. (>= (point) reg-end))
  5573. (setq continue nil))
  5574. ) ;while
  5575. (when web-mode-enable-inlays
  5576. (when (null web-mode-inlay-regexp)
  5577. (setq web-mode-inlay-regexp (regexp-opt '("\\[" "\\(" "\\begin{align}"))))
  5578. (let (beg end expr)
  5579. (goto-char reg-beg)
  5580. (while (web-mode-dom-rsf web-mode-inlay-regexp reg-end)
  5581. (setq beg (match-beginning 0)
  5582. end nil
  5583. expr (substring (match-string-no-properties 0) 0 2))
  5584. (setq expr (cond
  5585. ((string= expr "\\[") "\\]")
  5586. ((string= expr "\\(") "\\)")
  5587. (t "\\end{align}")))
  5588. (when (and (web-mode-dom-sf expr reg-end)
  5589. (setq end (match-end 0))
  5590. (not (text-property-any beg end 'tag-end t)))
  5591. (font-lock-append-text-property beg end 'font-lock-face 'web-mode-inlay-face)
  5592. ) ;when
  5593. ) ;while
  5594. ) ;let
  5595. ) ;when
  5596. (when web-mode-enable-html-entities-fontification
  5597. (let (beg end)
  5598. (goto-char reg-beg)
  5599. (while (web-mode-dom-rsf "&\\([#]?[[:alnum:]]\\{2,8\\}\\);" reg-end)
  5600. (setq beg (match-beginning 0)
  5601. end (match-end 0))
  5602. (when (not (text-property-any beg end 'tag-end t))
  5603. (font-lock-append-text-property beg end 'font-lock-face 'web-mode-html-entity-face)
  5604. ) ;when
  5605. ) ;while
  5606. ) ;let
  5607. ) ;when
  5608. ))
  5609. (defun web-mode-fontify-tag (&optional beg end)
  5610. (unless beg (setq beg (point)))
  5611. (unless end (setq end (1+ (web-mode-tag-end-position beg))))
  5612. (let (name type face flags slash-beg slash-end bracket-end)
  5613. (setq flags (get-text-property beg 'tag-beg)
  5614. type (get-text-property beg 'tag-type)
  5615. name (get-text-property beg 'tag-name))
  5616. (setq bracket-end (> (logand flags 16) 0))
  5617. (cond
  5618. ((eq type 'comment)
  5619. (put-text-property beg end 'font-lock-face 'web-mode-comment-face)
  5620. (when (and web-mode-enable-comment-interpolation (> (- end beg) 5))
  5621. (web-mode-interpolate-comment beg end nil)))
  5622. ((eq type 'cdata)
  5623. (put-text-property beg end 'font-lock-face 'web-mode-doctype-face))
  5624. ((eq type 'doctype)
  5625. (put-text-property beg end 'font-lock-face 'web-mode-doctype-face))
  5626. ((eq type 'declaration)
  5627. (put-text-property beg end 'font-lock-face 'web-mode-doctype-face))
  5628. (name
  5629. (setq slash-beg (> (logand flags 4) 0)
  5630. slash-end (> (logand flags 8) 0)
  5631. bracket-end (> (logand flags 16) 0))
  5632. (setq face (cond
  5633. ((not bracket-end) 'web-mode-html-tag-unclosed-face)
  5634. ((and web-mode-enable-element-tag-fontification
  5635. (setq face (cdr (assoc name web-mode-element-tag-faces))))
  5636. face)
  5637. ((> (logand flags 32) 0) 'web-mode-html-tag-namespaced-face)
  5638. ((> (logand flags 2) 0) 'web-mode-html-tag-custom-face)
  5639. (t 'web-mode-html-tag-face)))
  5640. (put-text-property beg (+ beg (if slash-beg 2 1))
  5641. 'font-lock-face 'web-mode-html-tag-bracket-face)
  5642. (unless (string= name "_fragment_")
  5643. (put-text-property (+ beg (if slash-beg 2 1))
  5644. (+ beg (if slash-beg 2 1) (length name))
  5645. 'font-lock-face face))
  5646. (when (or slash-end bracket-end)
  5647. (put-text-property (- end (if slash-end 2 1)) end 'font-lock-face 'web-mode-html-tag-bracket-face)
  5648. ) ;when
  5649. (when (> (logand flags 1) 0)
  5650. ;;(message "%S>%S" beg end)
  5651. (web-mode-fontify-attrs beg end))
  5652. ) ;case name
  5653. ) ;cond
  5654. ))
  5655. (defun web-mode-fontify-attrs (reg-beg reg-end)
  5656. (let ((continue t) (pos reg-beg) beg end flags offset face)
  5657. ;;(message "fontify-attrs %S>%S" reg-beg reg-end)
  5658. (while continue
  5659. (setq beg (web-mode-attribute-next-position pos reg-end))
  5660. (cond
  5661. ((or (null beg) (>= beg reg-end))
  5662. (setq continue nil))
  5663. (t
  5664. (setq flags (or (get-text-property beg 'tag-attr-beg) 0))
  5665. (setq face (cond
  5666. ((= (logand flags 1) 1) 'web-mode-html-attr-custom-face)
  5667. ((= (logand flags 2) 2) 'web-mode-html-attr-engine-face)
  5668. ((= (logand flags 4) 4) nil)
  5669. (t 'web-mode-html-attr-name-face)))
  5670. ;;(setq end (if (get-text-property beg 'tag-attr-end) beg (web-mode-attribute-end-position beg)))
  5671. (setq end (web-mode-attribute-end-position beg))
  5672. ;;(message "beg=%S end=%S" beg end)
  5673. (cond
  5674. ((or (null end) (>= end reg-end))
  5675. (setq continue nil))
  5676. (t
  5677. (setq offset (get-text-property end 'tag-attr-end))
  5678. (if (= offset 0)
  5679. (put-text-property beg (1+ end) 'font-lock-face face)
  5680. (put-text-property beg (+ beg offset) 'font-lock-face face)
  5681. (put-text-property (+ beg offset) (+ beg offset 1)
  5682. 'font-lock-face
  5683. 'web-mode-html-attr-equal-face)
  5684. (when (not (get-text-property (+ beg offset 1) 'jsx-beg))
  5685. (put-text-property (+ beg offset 1) (1+ end)
  5686. 'font-lock-face
  5687. 'web-mode-html-attr-value-face)
  5688. )
  5689. ) ;if offset
  5690. (setq pos (1+ end))
  5691. ) ;t
  5692. ) ;cond
  5693. ) ;t
  5694. );cond
  5695. ) ;while
  5696. ))
  5697. (defun web-mode-fontify-block (reg-beg reg-end)
  5698. (let (sub1 sub2 sub3 continue char keywords token-type face beg end (buffer (current-buffer)))
  5699. ;;(message "reg-beg=%S reg-end=%S" reg-beg reg-end)
  5700. ;; NOTE: required for blocks inside tag attrs
  5701. (remove-list-of-text-properties reg-beg reg-end '(font-lock-face))
  5702. (goto-char reg-beg)
  5703. (when (null web-mode-engine-font-lock-keywords)
  5704. (setq sub1 (buffer-substring-no-properties
  5705. reg-beg (+ reg-beg 1))
  5706. sub2 (buffer-substring-no-properties
  5707. reg-beg (+ reg-beg 2))
  5708. sub3 (buffer-substring-no-properties
  5709. reg-beg (+ reg-beg (if (>= (point-max) (+ reg-beg 3)) 3 2))))
  5710. )
  5711. (cond
  5712. ((and (get-text-property reg-beg 'block-beg)
  5713. (eq (get-text-property reg-beg 'block-token) 'comment))
  5714. (put-text-property reg-beg reg-end 'font-lock-face 'web-mode-comment-face)
  5715. ) ;comment block
  5716. (web-mode-engine-font-lock-keywords
  5717. (setq keywords web-mode-engine-font-lock-keywords)
  5718. )
  5719. ((string= web-mode-engine "django")
  5720. (cond
  5721. ((string= sub2 "{{")
  5722. (setq keywords web-mode-django-expr-font-lock-keywords))
  5723. ((string= sub2 "{%")
  5724. (setq keywords web-mode-django-code-font-lock-keywords))
  5725. )) ;django
  5726. ((string= web-mode-engine "mako")
  5727. (cond
  5728. ((member sub3 '("<% " "<%\n" "<%!"))
  5729. (setq keywords web-mode-mako-block-font-lock-keywords))
  5730. ((eq (aref sub2 0) ?\%)
  5731. (setq keywords web-mode-mako-block-font-lock-keywords))
  5732. ((member sub2 '("<%" "</"))
  5733. (setq keywords web-mode-mako-tag-font-lock-keywords))
  5734. ((member sub2 '("${"))
  5735. (setq keywords web-mode-uel-font-lock-keywords))
  5736. )) ;mako
  5737. ((string= web-mode-engine "mason")
  5738. ;;(message "%S %S" sub2 sub3)
  5739. (cond
  5740. ((member sub3 '("<% " "<%\n" "<&|"))
  5741. (setq keywords web-mode-mason-code-font-lock-keywords))
  5742. ((eq (aref sub2 0) ?\%)
  5743. (setq keywords web-mode-mason-code-font-lock-keywords))
  5744. ((and (or (string= sub2 "<%") (string= sub3 "</%"))
  5745. (not (member sub3 '("<%c" "<%i" "<%p"))))
  5746. (setq keywords web-mode-mason-block-font-lock-keywords))
  5747. (t
  5748. (setq keywords web-mode-mason-code-font-lock-keywords))
  5749. )) ;mason
  5750. ((string= web-mode-engine "jsp")
  5751. (cond
  5752. ((string= sub3 "<%@")
  5753. (setq keywords web-mode-directive-font-lock-keywords))
  5754. ((member sub2 '("${" "#{"))
  5755. (setq keywords web-mode-uel-font-lock-keywords))
  5756. ((string= sub2 "<%")
  5757. (setq keywords web-mode-jsp-font-lock-keywords))
  5758. )) ;jsp
  5759. ((string= web-mode-engine "asp")
  5760. (cond
  5761. ((or (string= sub2 "<%")
  5762. (not (string= sub1 "<")))
  5763. (setq keywords web-mode-asp-font-lock-keywords))
  5764. (t
  5765. (setq keywords web-mode-engine-tag-font-lock-keywords))
  5766. )) ;asp
  5767. ((string= web-mode-engine "clip")
  5768. (setq keywords web-mode-engine-tag-font-lock-keywords)
  5769. ) ;clip
  5770. ((string= web-mode-engine "aspx")
  5771. (cond
  5772. ((string= sub3 "<%@")
  5773. (setq keywords web-mode-directive-font-lock-keywords))
  5774. ((string= sub3 "<%$")
  5775. (setq keywords web-mode-expression-font-lock-keywords))
  5776. (t
  5777. (setq keywords web-mode-aspx-font-lock-keywords))
  5778. )) ;aspx
  5779. ((string= web-mode-engine "freemarker")
  5780. (cond
  5781. ((member sub2 '("${" "#{"))
  5782. (setq keywords web-mode-uel-font-lock-keywords))
  5783. ((or (member sub2 '("<@" "[@" "<#" "[#"))
  5784. (member sub3 '("</@" "[/@" "</#" "[/#")))
  5785. (setq keywords (if (eq ?\[ (aref sub2 0))
  5786. web-mode-freemarker-square-font-lock-keywords
  5787. web-mode-freemarker-font-lock-keywords)))
  5788. (t
  5789. (setq keywords web-mode-engine-tag-font-lock-keywords))
  5790. )) ;freemarker
  5791. ) ;cond
  5792. (when keywords
  5793. (web-mode-fontify-region reg-beg reg-end keywords)
  5794. (setq continue t)
  5795. (setq end reg-beg)
  5796. (while continue
  5797. (if (get-text-property end 'block-token)
  5798. (setq beg end)
  5799. (setq beg (next-single-property-change end 'block-token buffer reg-end)))
  5800. (setq end nil)
  5801. (when beg (setq char (char-after beg)))
  5802. (if (and beg (< beg reg-end))
  5803. (progn
  5804. (setq token-type (get-text-property beg 'block-token))
  5805. (setq face (cond
  5806. ((eq token-type 'string) 'web-mode-block-string-face)
  5807. ((eq token-type 'comment) 'web-mode-block-comment-face)
  5808. ((eq token-type 'symbol) 'web-mode-symbol-face)
  5809. (t 'web-mode-block-delimiter-face)))
  5810. (setq end (next-single-property-change beg 'block-token buffer reg-end))
  5811. ;; (message "end=%S" end)
  5812. (if (and end (<= end reg-end))
  5813. (progn
  5814. ;;(message "%S > %S face(%S)" beg end face)
  5815. (remove-list-of-text-properties beg end '(face))
  5816. (put-text-property beg end 'font-lock-face face)
  5817. )
  5818. (setq continue nil
  5819. end nil)
  5820. ) ;if end
  5821. ) ;progn beg
  5822. (setq continue nil
  5823. end nil)
  5824. ) ;if beg
  5825. (when (and beg end)
  5826. (save-match-data
  5827. (when (and web-mode-enable-heredoc-fontification
  5828. (eq char ?\<)
  5829. (> (- end beg) 8)
  5830. ;;(progn (message "%S" (buffer-substring-no-properties beg end)) t)
  5831. (string-match-p "JS\\|JAVASCRIPT\\|HTM\\|CSS" (buffer-substring-no-properties beg end)))
  5832. (setq keywords
  5833. (cond
  5834. ((string-match-p "H" (buffer-substring-no-properties beg (+ beg 8)))
  5835. web-mode-html-font-lock-keywords)
  5836. (t
  5837. web-mode-javascript-font-lock-keywords)
  5838. ))
  5839. (web-mode-fontify-region beg end keywords)
  5840. ))
  5841. ;; (message "%S %c %S beg=%S end=%S" web-mode-enable-string-interpolation char web-mode-engine beg end)
  5842. (when (and web-mode-enable-string-interpolation
  5843. (member char '(?\" ?\<))
  5844. (member web-mode-engine '("php" "erb"))
  5845. (> (- end beg) 4))
  5846. (web-mode-interpolate-block-string beg end)
  5847. ) ;when
  5848. (when (and web-mode-enable-comment-interpolation
  5849. (eq token-type 'comment)
  5850. (> (- end beg) 3))
  5851. (web-mode-interpolate-comment beg end t)
  5852. ) ;when
  5853. (when (and web-mode-enable-comment-annotation
  5854. (eq token-type 'comment)
  5855. (> (- end beg) 3))
  5856. (web-mode-annotate-comment beg end)
  5857. ) ;when
  5858. (when (and web-mode-enable-sql-detection
  5859. (eq token-type 'string)
  5860. (> (- end beg) 6)
  5861. ;;(eq char ?\<)
  5862. ;;(web-mode-looking-at-p (concat "[ \n]*" web-mode-sql-queries) (1+ beg))
  5863. (web-mode-looking-at-p (concat "\\(.\\|<<<[[:alnum:]]+\\)[ \n]*" web-mode-sql-queries) beg)
  5864. )
  5865. (web-mode-interpolate-sql-string beg end)
  5866. ) ;when
  5867. ) ;when beg end
  5868. ) ;while continue
  5869. ) ;when keywords
  5870. ;;(when (and (member web-mode-engine '("jsp" "mako"))
  5871. (when (and (member web-mode-engine '("mako"))
  5872. (> (- reg-end reg-beg) 12)
  5873. (eq ?\< (char-after reg-beg)))
  5874. (web-mode-interpolate-block-tag reg-beg reg-end))
  5875. (when web-mode-enable-block-face
  5876. ;; (message "block-face %S %S" reg-beg reg-end)
  5877. (font-lock-append-text-property reg-beg reg-end 'face 'web-mode-block-face))
  5878. ))
  5879. (defun web-mode-fontify-part (reg-beg reg-end &optional depth)
  5880. (save-excursion
  5881. (let (start continue token-type face pos beg end string-face comment-face content-type)
  5882. ;;(message "fontify-part: reg-beg(%S) reg-end(%S)" reg-beg reg-end)
  5883. (if (member web-mode-content-type web-mode-part-content-types)
  5884. (setq content-type web-mode-content-type)
  5885. (setq content-type (symbol-name (get-text-property reg-beg 'part-side))))
  5886. ;;(message "content-type=%S" content-type)
  5887. (unless depth
  5888. (when (string= content-type "jsx") (setq depth 0))
  5889. )
  5890. (setq string-face 'web-mode-part-string-face
  5891. comment-face 'web-mode-part-comment-face)
  5892. (cond
  5893. ((member content-type '("javascript" "jsx"))
  5894. (setq string-face 'web-mode-javascript-string-face
  5895. comment-face 'web-mode-javascript-comment-face)
  5896. (web-mode-fontify-region reg-beg reg-end web-mode-javascript-font-lock-keywords))
  5897. ((string= content-type "json")
  5898. (setq string-face 'web-mode-json-string-face
  5899. comment-face 'web-mode-json-comment-face)
  5900. (web-mode-fontify-region reg-beg reg-end web-mode-javascript-font-lock-keywords))
  5901. ((string= content-type "css")
  5902. (setq string-face 'web-mode-css-string-face
  5903. comment-face 'web-mode-css-comment-face)
  5904. (web-mode-fontify-css-rules reg-beg reg-end))
  5905. ((string= content-type "sql")
  5906. (web-mode-fontify-region reg-beg reg-end web-mode-sql-font-lock-keywords))
  5907. ((string= content-type "stylus")
  5908. (web-mode-fontify-region reg-beg reg-end web-mode-stylus-font-lock-keywords))
  5909. ((string= content-type "sass")
  5910. (web-mode-fontify-region reg-beg reg-end web-mode-sass-font-lock-keywords))
  5911. ((string= content-type "pug")
  5912. (web-mode-fontify-region reg-beg reg-end web-mode-pug-font-lock-keywords))
  5913. ((string= content-type "markdown")
  5914. (web-mode-fontify-region reg-beg reg-end web-mode-markdown-font-lock-keywords))
  5915. ((string= content-type "ruby")
  5916. (web-mode-fontify-region reg-beg reg-end web-mode-erb-font-lock-keywords))
  5917. ((string= content-type "typescript")
  5918. (web-mode-fontify-region reg-beg reg-end web-mode-javascript-font-lock-keywords))
  5919. ) ;cond
  5920. (goto-char reg-beg)
  5921. ;;(when (string= content-type "jsx") (web-mode-fontify-tags reg-beg reg-end))
  5922. ;;(setq continue (and pos (< pos reg-end)))
  5923. (setq continue t
  5924. pos reg-beg)
  5925. (while continue
  5926. (if (get-text-property pos 'part-token)
  5927. (setq beg pos)
  5928. (setq beg (next-single-property-change pos 'part-token)))
  5929. (cond
  5930. ((or (null beg) (>= beg reg-end))
  5931. (setq continue nil
  5932. end nil))
  5933. ((and (eq depth 0) (get-text-property beg 'jsx-depth))
  5934. (setq pos (or (next-single-property-change beg 'jsx-depth) (point-max))))
  5935. (t
  5936. ;;(message "%c" (char-after beg))
  5937. (setq token-type (get-text-property beg 'part-token))
  5938. (setq face (cond
  5939. ((eq token-type 'string) string-face)
  5940. ((eq token-type 'comment) comment-face)
  5941. ((eq token-type 'context) 'web-mode-json-context-face)
  5942. ((eq token-type 'key) 'web-mode-json-key-face)
  5943. (t nil)))
  5944. (setq end (or (next-single-property-change beg 'part-token) (point-max))
  5945. pos end)
  5946. (cond
  5947. ((or (null end) (> end reg-end))
  5948. (setq continue nil
  5949. end nil))
  5950. (t
  5951. (when face
  5952. (remove-list-of-text-properties beg end '(face))
  5953. (put-text-property beg end 'font-lock-face face))
  5954. (cond
  5955. ((< (- end beg) 6)
  5956. )
  5957. ((eq token-type 'string)
  5958. (cond
  5959. ((and (eq (char-after beg) ?\`)
  5960. web-mode-enable-literal-interpolation
  5961. (member content-type '("javascript" "jsx")))
  5962. (web-mode-interpolate-javascript-literal beg end)
  5963. )
  5964. ((and (eq (char-after beg) ?\")
  5965. web-mode-enable-string-interpolation
  5966. (member content-type '("javascript" "jsx")))
  5967. (web-mode-interpolate-javascript-string beg end))
  5968. ) ;cond
  5969. ) ;case string
  5970. ((eq token-type 'comment)
  5971. (when web-mode-enable-comment-interpolation
  5972. (web-mode-interpolate-comment beg end t))
  5973. (when web-mode-enable-comment-annotation
  5974. (web-mode-annotate-comment beg end))
  5975. )
  5976. ) ;cond
  5977. ) ;t
  5978. ) ;cond
  5979. ) ;t
  5980. ) ;cond
  5981. ) ;while
  5982. (when (and (string= web-mode-content-type "html") web-mode-enable-part-face)
  5983. (font-lock-append-text-property reg-beg reg-end 'face
  5984. (cond
  5985. ((string= content-type "javascript")
  5986. 'web-mode-script-face)
  5987. ((string= content-type "css")
  5988. 'web-mode-style-face)
  5989. (t
  5990. 'web-mode-part-face)))
  5991. )
  5992. (when (and web-mode-enable-css-colorization (string= content-type "stylus"))
  5993. (goto-char reg-beg)
  5994. (while (and (re-search-forward "#[0-9a-fA-F]\\{6\\}\\|#[0-9a-fA-F]\\{3\\}\\|rgba?([ ]*\\([[:digit:]]\\{1,3\\}\\)[ ]*,[ ]*\\([[:digit:]]\\{1,3\\}\\)[ ]*,[ ]*\\([[:digit:]]\\{1,3\\}\\)\\(.*?\\))" end t)
  5995. (<= (point) reg-end))
  5996. (web-mode-colorize (match-beginning 0) (match-end 0))
  5997. )
  5998. )
  5999. (when (and (eq depth 0) (string= content-type "jsx"))
  6000. (let (pair elt-beg elt-end exp-beg exp-end exp-depth)
  6001. (goto-char reg-beg)
  6002. (while (setq pair (web-mode-jsx-element-next reg-end))
  6003. ;;(message "elt-pair=%S" pair)
  6004. (setq elt-beg (car pair)
  6005. elt-end (cdr pair))
  6006. (remove-list-of-text-properties elt-beg (1+ elt-end) '(face))
  6007. (web-mode-fontify-tags elt-beg elt-end 1)
  6008. (goto-char elt-beg)
  6009. (while (setq pair (web-mode-jsx-expression-next elt-end))
  6010. ;;(message "exp-pair=%S elt-end=%S" pair elt-end)
  6011. (setq exp-beg (car pair)
  6012. exp-end (cdr pair))
  6013. (when (eq (char-after exp-beg) ?\{)
  6014. ;;(message "%S : %c %c" exp-beg (char-after (+ exp-beg 1)) (char-after (+ exp-beg 2)))
  6015. (cond
  6016. ;;((and (eq (char-after (+ exp-beg 1)) ?\/) (eq (char-after (+ exp-beg 2)) ?\*))
  6017. ;; (put-text-property exp-beg (1+ exp-end) 'font-lock-face 'web-mode-part-comment-face)
  6018. ;; )
  6019. (t
  6020. (setq exp-depth (get-text-property exp-beg 'jsx-depth))
  6021. (remove-list-of-text-properties exp-beg exp-end '(font-lock-face))
  6022. (put-text-property exp-beg (1+ exp-beg) 'font-lock-face 'web-mode-block-delimiter-face)
  6023. (when (and (eq (get-text-property exp-beg 'tag-attr-beg) 4) (web-mode-looking-at-p "\.\.\." (1+ exp-beg)))
  6024. (put-text-property exp-beg (+ exp-beg 4) 'font-lock-face 'web-mode-block-delimiter-face))
  6025. (put-text-property exp-end (1+ exp-end) 'font-lock-face 'web-mode-block-delimiter-face)
  6026. (web-mode-fontify-tags (1+ exp-beg) exp-end (1+ exp-depth))
  6027. (web-mode-fontify-part (1+ exp-beg) exp-end exp-depth)
  6028. (web-mode-fontify-region (1+ exp-beg) exp-end web-mode-javascript-font-lock-keywords)
  6029. ) ;t
  6030. ) ;cond
  6031. ) ;when
  6032. (goto-char (1+ exp-beg))
  6033. ) ;while exp
  6034. (when (and elt-beg web-mode-jsx-depth-faces)
  6035. (let (depth-beg depth-end jsx-face)
  6036. (goto-char elt-beg)
  6037. (while (setq pair (web-mode-jsx-depth-next reg-end))
  6038. ;;(message "depth-pair=%S" pair)
  6039. (setq depth-beg (car pair)
  6040. depth-end (cdr pair)
  6041. depth (get-text-property depth-beg 'jsx-depth)
  6042. jsx-face (elt web-mode-jsx-depth-faces (1- depth)))
  6043. ;;(message "%S" jsx-face)
  6044. (font-lock-prepend-text-property depth-beg (1+ depth-end) 'face jsx-face)
  6045. (goto-char (+ depth-beg 2))
  6046. )
  6047. ) ;let
  6048. )
  6049. (goto-char (1+ elt-end))
  6050. ) ;while elt
  6051. ) ;let
  6052. ) ;when
  6053. ) ;let
  6054. ) ;save-excursion
  6055. )
  6056. (defun web-mode-fontify-css-rules (part-beg part-end)
  6057. (save-excursion
  6058. (goto-char part-beg)
  6059. (let (rule (continue t) (i 0) (at-rule nil) (var-rule nil))
  6060. (while continue
  6061. (setq rule (web-mode-css-rule-next part-end))
  6062. ;;(message "rule=%S" rule)
  6063. (cond
  6064. ((> (setq i (1+ i)) 1000)
  6065. (message "fontify-css-rules ** too much rules **")
  6066. (setq continue nil))
  6067. ((null rule)
  6068. (setq continue nil))
  6069. ((and (setq at-rule (plist-get rule :at-rule))
  6070. (not (member at-rule '("charset" "font-face" "import" "viewport")))
  6071. (plist-get rule :dec-end))
  6072. (web-mode-fontify-css-rule (plist-get rule :sel-beg)
  6073. (plist-get rule :sel-end)
  6074. nil nil)
  6075. (web-mode-fontify-css-rules (plist-get rule :dec-beg)
  6076. (plist-get rule :dec-end)))
  6077. (t
  6078. (web-mode-fontify-css-rule (plist-get rule :sel-beg)
  6079. (plist-get rule :sel-end)
  6080. (plist-get rule :dec-beg)
  6081. (plist-get rule :dec-end)))
  6082. ) ;cond
  6083. ) ;while
  6084. ) ;let
  6085. ))
  6086. (defun web-mode-fontify-css-rule (sel-beg sel-end dec-beg dec-end)
  6087. (save-excursion
  6088. ;;(let ((end sel-end))
  6089. ;;(message "sel-beg=%S sel-end=%S dec-beg=%S dec-end=%S" sel-beg sel-end dec-beg dec-end)
  6090. (web-mode-fontify-region sel-beg sel-end web-mode-selector-font-lock-keywords)
  6091. (when (and dec-beg dec-end)
  6092. ;;(setq end dec-end)
  6093. (web-mode-fontify-region dec-beg dec-end web-mode-declaration-font-lock-keywords)
  6094. ) ;when
  6095. (when (and dec-beg dec-end)
  6096. (goto-char dec-beg)
  6097. (while (and web-mode-enable-css-colorization
  6098. (re-search-forward "#[0-9a-fA-F]\\{6\\}\\|#[0-9a-fA-F]\\{3\\}\\|rgba?([ ]*\\([[:digit:]]\\{1,3\\}\\)[ ]*,[ ]*\\([[:digit:]]\\{1,3\\}\\)[ ]*,[ ]*\\([[:digit:]]\\{1,3\\}\\)\\(.*?\\))" dec-end t)
  6099. ;;(progn (message "%S %S" end (point)) t)
  6100. (<= (point) dec-end))
  6101. (web-mode-colorize (match-beginning 0) (match-end 0))
  6102. ) ;while
  6103. ) ;when
  6104. ;;) ;let
  6105. ))
  6106. (defun web-mode-colorize-foreground (color)
  6107. (let* ((values (x-color-values color))
  6108. (r (car values))
  6109. (g (cadr values))
  6110. (b (car (cdr (cdr values)))))
  6111. (if (> 128.0 (floor (+ (* .3 r) (* .59 g) (* .11 b)) 256))
  6112. "white" "black")))
  6113. (defun web-mode-colorize (beg end)
  6114. (let (str plist len)
  6115. (setq str (buffer-substring-no-properties beg end))
  6116. (setq len (length str))
  6117. (cond
  6118. ((string= (substring str 0 1) "#")
  6119. (setq plist (list :background str
  6120. :foreground (web-mode-colorize-foreground str)))
  6121. (put-text-property beg end 'face plist))
  6122. ((or (string= (substring str 0 4) "rgb(") (string= (substring str 0 5) "rgba("))
  6123. (setq str (format "#%02X%02X%02X"
  6124. (string-to-number (match-string-no-properties 1))
  6125. (string-to-number (match-string-no-properties 2))
  6126. (string-to-number (match-string-no-properties 3))))
  6127. (setq plist (list :background str
  6128. :foreground (web-mode-colorize-foreground str)))
  6129. (put-text-property beg end 'face plist))
  6130. ) ;cond
  6131. ))
  6132. (defun web-mode-interpolate-block-tag (beg end)
  6133. (save-excursion
  6134. (goto-char (+ 4 beg))
  6135. (setq end (1- end))
  6136. (while (re-search-forward "${.*?}" end t)
  6137. (remove-list-of-text-properties (match-beginning 0) (match-end 0) '(face))
  6138. (web-mode-fontify-region (match-beginning 0) (match-end 0)
  6139. web-mode-uel-font-lock-keywords))
  6140. ))
  6141. (defun web-mode-interpolate-javascript-string (beg end)
  6142. (save-excursion
  6143. (goto-char (1+ beg))
  6144. (setq end (1- end))
  6145. (while (re-search-forward "${.*?}" end t)
  6146. (put-text-property (match-beginning 0) (match-end 0)
  6147. 'font-lock-face
  6148. 'web-mode-variable-name-face)
  6149. )
  6150. ))
  6151. (defun web-mode-interpolate-javascript-literal (beg end)
  6152. (save-excursion
  6153. (goto-char (1+ beg))
  6154. (setq end (1- end))
  6155. (while (re-search-forward "${.*?}" end t)
  6156. (put-text-property (match-beginning 0) (match-end 0)
  6157. 'font-lock-face
  6158. 'web-mode-variable-name-face)
  6159. )
  6160. (cond
  6161. ((web-mode-looking-back "\\(css\\|styled[[:alnum:].]+\\)" beg)
  6162. (goto-char (1+ beg))
  6163. (while (re-search-forward ".*?:" end t)
  6164. (put-text-property (match-beginning 0) (match-end 0)
  6165. 'font-lock-face
  6166. 'web-mode-interpolate-color1-face)
  6167. )
  6168. ) ;case css
  6169. ((web-mode-looking-back "\\(template\\|html\\)" beg)
  6170. (goto-char (1+ beg))
  6171. (while (re-search-forward web-mode-tag-regexp end t)
  6172. (put-text-property (match-beginning 1) (match-end 1)
  6173. 'font-lock-face
  6174. 'web-mode-interpolate-color1-face)
  6175. )
  6176. (goto-char (1+ beg))
  6177. (while (re-search-forward "</?\\|/?>\\| [[:alnum:]]+=" end t)
  6178. (cond
  6179. ((member (char-after (match-beginning 0)) '(?\< ?\/ ?\>))
  6180. (put-text-property (match-beginning 0) (match-end 0)
  6181. 'font-lock-face
  6182. 'web-mode-interpolate-color2-face)
  6183. )
  6184. (t
  6185. (put-text-property (1+ (match-beginning 0)) (1- (match-end 0))
  6186. 'font-lock-face
  6187. 'web-mode-interpolate-color3-face)
  6188. ) ;t
  6189. ) ;cond
  6190. ) ;while
  6191. ) ;case html
  6192. ) ;cond type of literal
  6193. ))
  6194. ;; todo : parsing plus compliqué: {$obj->values[3]->name}
  6195. (defun web-mode-interpolate-block-string (beg end)
  6196. (save-excursion
  6197. (goto-char (1+ beg))
  6198. (setq end (1- end))
  6199. (cond
  6200. ((string= web-mode-engine "php")
  6201. (while (re-search-forward "$[[:alnum:]_]+\\(->[[:alnum:]_]+\\)*\\|{[ ]*$.+?}" end t)
  6202. ;; (message "%S > %S" (match-beginning 0) (match-end 0))
  6203. (remove-list-of-text-properties (match-beginning 0) (match-end 0) '(font-lock-face))
  6204. (web-mode-fontify-region (match-beginning 0) (match-end 0)
  6205. web-mode-php-var-interpolation-font-lock-keywords)
  6206. ))
  6207. ((string= web-mode-engine "erb")
  6208. (while (re-search-forward "#{.*?}" end t)
  6209. (remove-list-of-text-properties (match-beginning 0) (match-end 0) '(font-lock-face))
  6210. (put-text-property (match-beginning 0) (match-end 0)
  6211. 'font-lock-face 'web-mode-variable-name-face)
  6212. ))
  6213. ) ;cond
  6214. ))
  6215. (defun web-mode-interpolate-comment (beg end block-side)
  6216. (save-excursion
  6217. (let ((regexp (concat "\\_<\\(" web-mode-comment-keywords "\\)\\_>")))
  6218. (goto-char beg)
  6219. (while (re-search-forward regexp end t)
  6220. (font-lock-prepend-text-property (match-beginning 1) (match-end 1)
  6221. 'font-lock-face
  6222. 'web-mode-comment-keyword-face)
  6223. ) ;while
  6224. )))
  6225. (defun web-mode-annotate-comment (beg end)
  6226. (save-excursion
  6227. ;;(message "beg=%S end=%S" beg end)
  6228. (goto-char beg)
  6229. (when (looking-at-p "/\\*\\*")
  6230. (while (re-search-forward "\\(.+\\)" end t)
  6231. (font-lock-prepend-text-property (match-beginning 1) (match-end 1)
  6232. 'font-lock-face
  6233. 'web-mode-annotation-face))
  6234. (goto-char beg)
  6235. (while (re-search-forward "[ ]+\\({[^}]+}\\)" end t)
  6236. (font-lock-prepend-text-property (match-beginning 1) (match-end 1)
  6237. 'font-lock-face
  6238. 'web-mode-annotation-type-face))
  6239. (goto-char beg)
  6240. (while (re-search-forward "\\(@[[:alnum:]]+\\)" end t)
  6241. (font-lock-prepend-text-property (match-beginning 1) (match-end 1)
  6242. 'font-lock-face
  6243. 'web-mode-annotation-tag-face))
  6244. (goto-char beg)
  6245. (while (re-search-forward "}[[:blank:]]+\\([[:graph:]]+\\)" end t)
  6246. (font-lock-prepend-text-property (match-beginning 1) (match-end 1)
  6247. 'font-lock-face
  6248. 'web-mode-annotation-value-face))
  6249. (goto-char beg)
  6250. (while (re-search-forward "@see[[:blank:]]+\\([[:graph:]]+\\)" end t)
  6251. (font-lock-prepend-text-property (match-beginning 1) (match-end 1)
  6252. 'font-lock-face
  6253. 'web-mode-annotation-value-face))
  6254. (goto-char beg)
  6255. (while (re-search-forward "{\\(@\\(?:link\\|code\\)\\)\\s-+\\([^}\n]+\\)\\(#.+\\)?}" end t)
  6256. (font-lock-prepend-text-property (match-beginning 2) (match-end 2)
  6257. 'font-lock-face
  6258. 'web-mode-annotation-value-face))
  6259. (goto-char beg)
  6260. (while (re-search-forward "\\(</?\\)\\([[:alnum:]]+\\)\\s-*\\(/?>\\)" end t)
  6261. (font-lock-prepend-text-property (match-beginning 1) (match-end 1)
  6262. 'font-lock-face
  6263. 'web-mode-annotation-html-face)
  6264. (font-lock-prepend-text-property (match-beginning 2) (match-end 2)
  6265. 'font-lock-face
  6266. 'web-mode-annotation-html-face)
  6267. (font-lock-prepend-text-property (match-beginning 3) (match-end 3)
  6268. 'font-lock-face
  6269. 'web-mode-annotation-html-face))
  6270. ) ;when
  6271. ))
  6272. (defun web-mode-interpolate-sql-string (beg end)
  6273. (save-excursion
  6274. (let ((case-fold-search t)
  6275. (regexp (concat "\\_<\\(" web-mode-sql-keywords "\\)\\_>")))
  6276. (goto-char beg)
  6277. (while (re-search-forward regexp end t)
  6278. (font-lock-prepend-text-property (match-beginning 1) (match-end 1)
  6279. 'font-lock-face
  6280. 'web-mode-sql-keyword-face)
  6281. ) ;while
  6282. )))
  6283. ;;---- EFFECTS -----------------------------------------------------------------
  6284. (defun web-mode-fill-paragraph (&optional justify)
  6285. (save-excursion
  6286. (let ((pos (point)) fill-coll
  6287. prop pair beg end delim-beg delim-end chunk fill-col)
  6288. (cond
  6289. ((or (eq (get-text-property pos 'part-token) 'comment)
  6290. (eq (get-text-property pos 'block-token) 'comment))
  6291. (setq prop
  6292. (if (get-text-property pos 'part-token) 'part-token 'block-token))
  6293. (setq pair (web-mode-property-boundaries prop pos))
  6294. (when (and pair (> (- (cdr pair) (car pair)) 6))
  6295. (setq fill-coll (if (< fill-column 10) 70 fill-column))
  6296. (setq beg (car pair)
  6297. end (cdr pair))
  6298. (goto-char beg)
  6299. (setq chunk (buffer-substring-no-properties beg (+ beg 2)))
  6300. (cond
  6301. ((string= chunk "//")
  6302. (setq delim-beg "//"
  6303. delim-end "EOL"))
  6304. ((string= chunk "/*")
  6305. (setq delim-beg "/*"
  6306. delim-end "*/"))
  6307. ((string= chunk "{#")
  6308. (setq delim-beg "{#"
  6309. delim-end "#}"))
  6310. ((string= chunk "<!")
  6311. (setq delim-beg "<!--"
  6312. delim-end "-->"))
  6313. )
  6314. )
  6315. ) ;comment - case
  6316. ((web-mode-is-content)
  6317. (setq pair (web-mode-content-boundaries pos))
  6318. (setq beg (car pair)
  6319. end (cdr pair))
  6320. )
  6321. ) ;cond
  6322. ;;(message "beg(%S) end(%S)" beg end)
  6323. (when (and beg end)
  6324. (fill-region beg end))
  6325. t)))
  6326. (defun web-mode-engine-syntax-check ()
  6327. (interactive)
  6328. (let ((proc nil) (errors nil)
  6329. (file (concat temporary-file-directory "emacs-web-mode-tmp")))
  6330. (write-region (point-min) (point-max) file)
  6331. (cond
  6332. ;; ((null (buffer-file-name))
  6333. ;; )
  6334. ((string= web-mode-engine "php")
  6335. (setq proc (start-process "php-proc" nil "php" "-l" file))
  6336. (set-process-filter
  6337. proc
  6338. (lambda (proc output)
  6339. (cond
  6340. ((string-match-p "No syntax errors" output)
  6341. (message "No syntax errors")
  6342. )
  6343. (t
  6344. ;; (setq output (replace-regexp-in-string temporary-file-directory "" output))
  6345. ;; (message output)
  6346. (message "Syntax error")
  6347. (setq errors t))
  6348. ) ;cond
  6349. ;; (delete-file file)
  6350. ) ;lambda
  6351. )
  6352. ) ;php
  6353. (t
  6354. (message "no syntax checker found")
  6355. ) ;t
  6356. ) ;cond
  6357. errors))
  6358. (defun web-mode-jshint ()
  6359. "Run JSHint on all the JavaScript parts."
  6360. (interactive)
  6361. (let (proc lines)
  6362. (when (buffer-file-name)
  6363. (setq proc (start-process
  6364. "jshint-proc"
  6365. nil
  6366. (or (executable-find "jshint") "/usr/local/bin/jshint")
  6367. "--extract=auto"
  6368. (buffer-file-name)))
  6369. (setq web-mode-jshint-errors 0)
  6370. (set-process-filter proc
  6371. (lambda (proc output)
  6372. (let ((offset 0) overlay pos (old 0) msg)
  6373. (remove-overlays (point-min) (point-max) 'font-lock-face 'web-mode-error-face)
  6374. (while (string-match
  6375. "line \\([[:digit:]]+\\), col \\([[:digit:]]+\\), \\(.+\\)\\.$"
  6376. output offset)
  6377. (setq web-mode-jshint-errors (1+ web-mode-jshint-errors))
  6378. (setq offset (match-end 0))
  6379. (setq pos (web-mode-coord-position
  6380. (match-string-no-properties 1 output)
  6381. (match-string-no-properties 2 output)))
  6382. (when (get-text-property pos 'tag-beg)
  6383. (setq pos (1- pos)))
  6384. (when (not (= pos old))
  6385. (setq old pos)
  6386. (setq overlay (make-overlay pos (1+ pos)))
  6387. (overlay-put overlay 'font-lock-face 'web-mode-error-face)
  6388. )
  6389. (setq msg (or (overlay-get overlay 'help-echo)
  6390. (concat "line="
  6391. (match-string-no-properties 1 output)
  6392. " column="
  6393. (match-string-no-properties 2 output)
  6394. )))
  6395. (overlay-put overlay 'help-echo
  6396. (concat msg " ## " (match-string-no-properties 3 output)))
  6397. ) ;while
  6398. ))
  6399. )
  6400. ) ;when
  6401. ))
  6402. (defun web-mode-dom-errors-show ()
  6403. "Show unclosed tags."
  6404. (interactive)
  6405. (let (beg end tag pos l n tags i cont cell overlay overlays first
  6406. (ori (point))
  6407. (errors 0)
  6408. (continue t)
  6409. )
  6410. (setq overlays (overlays-in (point-min) (point-max)))
  6411. (when overlays
  6412. (dolist (overlay overlays)
  6413. (when (eq (overlay-get overlay 'face) 'web-mode-warning-face)
  6414. (delete-overlay overlay)
  6415. )
  6416. )
  6417. )
  6418. (goto-char (point-min))
  6419. (when (not (or (get-text-property (point) 'tag-beg)
  6420. (web-mode-tag-next)))
  6421. (setq continue nil))
  6422. (while continue
  6423. (setq pos (point))
  6424. (setq tag (get-text-property pos 'tag-name))
  6425. (cond
  6426. ((eq (get-text-property (point) 'tag-type) 'start)
  6427. (setq tags (add-to-list 'tags (list tag pos)))
  6428. ;; (message "(%S) opening %S" pos tag)
  6429. )
  6430. ((eq (get-text-property (point) 'tag-type) 'end)
  6431. (setq i 0
  6432. l (length tags)
  6433. cont t)
  6434. (while (and (< i l) cont)
  6435. (setq cell (nth i tags))
  6436. ;; (message "cell=%S" cell)
  6437. (setq i (1+ i))
  6438. (cond
  6439. ((string= tag (nth 0 cell))
  6440. (setq cont nil)
  6441. )
  6442. (t
  6443. (setq errors (1+ errors))
  6444. (setq beg (nth 1 cell))
  6445. (setq end (web-mode-tag-end-position beg))
  6446. (unless first
  6447. (setq first beg))
  6448. (setq overlay (make-overlay beg (1+ end)))
  6449. (overlay-put overlay 'font-lock-face 'web-mode-warning-face)
  6450. ;; (message "invalid <%S> at %S" (nth 0 cell) (nth 1 cell))
  6451. )
  6452. ) ;cond
  6453. ) ;while
  6454. (dotimes (i i)
  6455. (setq tags (cdr tags)))
  6456. )
  6457. ) ;cond
  6458. (when (not (web-mode-tag-next))
  6459. (setq continue nil))
  6460. ) ;while
  6461. (message "%S error(s) detected" errors)
  6462. (if (< errors 1)
  6463. (goto-char ori)
  6464. (goto-char first)
  6465. (recenter))
  6466. ;; (message "%S" tags)
  6467. ))
  6468. (defun web-mode-fontify-elements (beg end)
  6469. (save-excursion
  6470. (goto-char beg)
  6471. (let ((continue (or (get-text-property (point) 'tag-beg) (web-mode-tag-next)))
  6472. (i 0) (ctx nil) (face nil))
  6473. (while continue
  6474. (cond
  6475. ((> (setq i (1+ i)) 1000)
  6476. (message "fontify-elements ** too much tags **")
  6477. (setq continue nil))
  6478. ((> (point) end)
  6479. (setq continue nil))
  6480. ((not (get-text-property (point) 'tag-beg))
  6481. (setq continue nil))
  6482. ((eq (get-text-property (point) 'tag-type) 'start)
  6483. (when (and (setq ctx (web-mode-element-boundaries (point)))
  6484. (<= (car (cdr ctx)) end)
  6485. (setq face (cdr (assoc (get-text-property (point) 'tag-name) web-mode-element-content-faces))))
  6486. (font-lock-prepend-text-property (1+ (cdr (car ctx))) (car (cdr ctx))
  6487. 'font-lock-face face))
  6488. )
  6489. ) ;cond
  6490. (when (not (web-mode-tag-next))
  6491. (setq continue nil))
  6492. ) ;while
  6493. )))
  6494. (defun web-mode-enable (feature)
  6495. "Enable one feature."
  6496. (interactive
  6497. (list (completing-read
  6498. "Feature: "
  6499. (let (features)
  6500. (dolist (elt web-mode-features)
  6501. (setq features (append features (list (car elt)))))
  6502. features))))
  6503. (when (and (or (not feature) (< (length feature) 1)) web-mode-last-enabled-feature)
  6504. (setq feature web-mode-last-enabled-feature))
  6505. (when feature
  6506. (setq web-mode-last-enabled-feature feature)
  6507. (setq feature (cdr (assoc feature web-mode-features)))
  6508. (cond
  6509. ((eq feature 'web-mode-enable-current-column-highlight)
  6510. (web-mode-column-show))
  6511. ((eq feature 'web-mode-enable-current-element-highlight)
  6512. (when (not web-mode-enable-current-element-highlight)
  6513. (web-mode-toggle-current-element-highlight))
  6514. )
  6515. ((eq feature 'web-mode-enable-whitespace-fontification)
  6516. (web-mode-whitespaces-on))
  6517. (t
  6518. (set feature t)
  6519. (web-mode-buffer-fontify))
  6520. )
  6521. ) ;when
  6522. )
  6523. (defun web-mode-disable (feature)
  6524. "Disable one feature."
  6525. (interactive
  6526. (list (completing-read
  6527. "Feature: "
  6528. (let (features)
  6529. (dolist (elt web-mode-features)
  6530. (setq features (append features (list (car elt)))))
  6531. features))))
  6532. (when (and (or (not feature) (< (length feature) 1)) web-mode-last-enabled-feature)
  6533. (setq feature web-mode-last-enabled-feature))
  6534. (when feature
  6535. (setq feature (cdr (assoc feature web-mode-features)))
  6536. (cond
  6537. ((eq feature 'web-mode-enable-current-column-highlight)
  6538. (web-mode-column-hide))
  6539. ((eq feature 'web-mode-enable-current-element-highlight)
  6540. (when web-mode-enable-current-element-highlight
  6541. (web-mode-toggle-current-element-highlight))
  6542. )
  6543. ((eq feature 'web-mode-enable-whitespace-fontification)
  6544. (web-mode-whitespaces-off))
  6545. (t
  6546. (set feature nil)
  6547. (web-mode-buffer-fontify))
  6548. )
  6549. ) ;when
  6550. )
  6551. (defun web-mode-toggle-current-element-highlight ()
  6552. "Toggle highlighting of the current html element."
  6553. (interactive)
  6554. (if web-mode-enable-current-element-highlight
  6555. (progn
  6556. (web-mode-delete-tag-overlays)
  6557. (setq web-mode-enable-current-element-highlight nil))
  6558. (setq web-mode-enable-current-element-highlight t)
  6559. ))
  6560. (defun web-mode-make-tag-overlays ()
  6561. (unless web-mode-overlay-tag-start
  6562. (setq web-mode-overlay-tag-start (make-overlay 1 1)
  6563. web-mode-overlay-tag-end (make-overlay 1 1))
  6564. (overlay-put web-mode-overlay-tag-start
  6565. 'font-lock-face
  6566. 'web-mode-current-element-highlight-face)
  6567. (overlay-put web-mode-overlay-tag-end
  6568. 'font-lock-face
  6569. 'web-mode-current-element-highlight-face)))
  6570. (defun web-mode-delete-tag-overlays ()
  6571. (when web-mode-overlay-tag-start
  6572. (delete-overlay web-mode-overlay-tag-start)
  6573. (delete-overlay web-mode-overlay-tag-end)))
  6574. (defun web-mode-column-overlay-factory (index)
  6575. (let (overlay)
  6576. (when (null web-mode-column-overlays)
  6577. (dotimes (i 100)
  6578. (setq overlay (make-overlay 1 1))
  6579. (overlay-put overlay 'font-lock-face 'web-mode-current-column-highlight-face)
  6580. (setq web-mode-column-overlays (append web-mode-column-overlays (list overlay)))
  6581. )
  6582. ) ;when
  6583. (setq overlay (nth index web-mode-column-overlays))
  6584. (when (null overlay)
  6585. (setq overlay (make-overlay 1 1))
  6586. (overlay-put overlay 'font-lock-face 'web-mode-current-column-highlight-face)
  6587. (setq web-mode-column-overlays (append web-mode-column-overlays (list overlay)))
  6588. ) ;when
  6589. overlay))
  6590. (defun web-mode-column-hide ()
  6591. (setq web-mode-enable-current-column-highlight nil)
  6592. (remove-overlays (point-min) (point-max)
  6593. 'font-lock-face
  6594. 'web-mode-current-column-highlight-face))
  6595. (defun web-mode-column-show ()
  6596. (let ((index 0) overlay diff column line-to line-from)
  6597. (web-mode-column-hide)
  6598. (setq web-mode-enable-current-column-highlight t)
  6599. (save-excursion
  6600. (back-to-indentation)
  6601. (setq column (current-column)
  6602. line-to (web-mode-line-number))
  6603. (when (and (get-text-property (point) 'tag-beg)
  6604. (member (get-text-property (point) 'tag-type) '(start end))
  6605. (web-mode-tag-match)
  6606. (setq line-from (web-mode-line-number))
  6607. (not (= line-from line-to)))
  6608. (when (> line-from line-to)
  6609. (let (tmp)
  6610. (setq tmp line-from)
  6611. (setq line-from line-to)
  6612. (setq line-to tmp))
  6613. ) ;when
  6614. ;;(message "column(%S) line-from(%S) line-to(%S)" column line-from line-to)
  6615. (goto-char (point-min))
  6616. (when (> line-from 1)
  6617. (forward-line (1- line-from)))
  6618. (while (<= line-from line-to)
  6619. (setq overlay (web-mode-column-overlay-factory index))
  6620. (setq diff (- (line-end-position) (point)))
  6621. (cond
  6622. ((or (and (= column 0) (= diff 0))
  6623. (> column diff))
  6624. (end-of-line)
  6625. (move-overlay overlay (point) (point))
  6626. (overlay-put overlay
  6627. 'after-string
  6628. (concat
  6629. (if (> column diff) (make-string (- column diff) ?\s) "")
  6630. (propertize " "
  6631. 'font-lock-face
  6632. 'web-mode-current-column-highlight-face)
  6633. ) ;concat
  6634. )
  6635. )
  6636. (t
  6637. (move-to-column column)
  6638. (overlay-put overlay 'after-string nil)
  6639. (move-overlay overlay (point) (1+ (point)))
  6640. )
  6641. ) ;cond
  6642. (setq line-from (1+ line-from))
  6643. (forward-line)
  6644. (setq index (1+ index))
  6645. ) ;while
  6646. ) ;when
  6647. ) ;save-excursion
  6648. ) ;let
  6649. )
  6650. (defun web-mode-highlight-current-element ()
  6651. (let ((ctx (web-mode-element-boundaries)) len)
  6652. (cond
  6653. ((null ctx)
  6654. (web-mode-delete-tag-overlays))
  6655. ((eq (get-text-property (caar ctx) 'tag-type) 'void) ;; #1046
  6656. (web-mode-make-tag-overlays)
  6657. (setq len (length (get-text-property (caar ctx) 'tag-name)))
  6658. (move-overlay web-mode-overlay-tag-start (+ (caar ctx) 1) (+ (caar ctx) 1 len))
  6659. )
  6660. (t
  6661. (web-mode-make-tag-overlays)
  6662. (setq len (length (get-text-property (caar ctx) 'tag-name)))
  6663. (move-overlay web-mode-overlay-tag-start (+ (caar ctx) 1) (+ (caar ctx) 1 len))
  6664. (move-overlay web-mode-overlay-tag-end (+ (cadr ctx) 2) (+ (cadr ctx) 2 len))
  6665. ) ;t
  6666. ) ;cond
  6667. ))
  6668. (defun web-mode-fontify-whitespaces (beg end)
  6669. (save-excursion
  6670. (goto-char beg)
  6671. (while (re-search-forward web-mode-whitespaces-regexp end t)
  6672. (add-text-properties (match-beginning 0) (match-end 0)
  6673. '(face web-mode-whitespace-face))
  6674. ) ;while
  6675. ))
  6676. (defun web-mode-whitespaces-show ()
  6677. "Toggle whitespaces."
  6678. (interactive)
  6679. (if web-mode-enable-whitespace-fontification
  6680. (web-mode-whitespaces-off)
  6681. (web-mode-whitespaces-on)))
  6682. (defun web-mode-whitespaces-on ()
  6683. "Show whitespaces."
  6684. (interactive)
  6685. (when web-mode-display-table
  6686. (setq buffer-display-table web-mode-display-table))
  6687. (setq web-mode-enable-whitespace-fontification t))
  6688. (defun web-mode-whitespaces-off ()
  6689. (setq buffer-display-table nil)
  6690. (setq web-mode-enable-whitespace-fontification nil))
  6691. (defun web-mode-use-tabs ()
  6692. "Tweaks vars to be compatible with TAB indentation."
  6693. (let (offset)
  6694. (setq web-mode-block-padding 0)
  6695. (setq web-mode-script-padding 0)
  6696. (setq web-mode-style-padding 0)
  6697. (setq offset
  6698. (cond
  6699. ((and (boundp 'tab-width) tab-width) tab-width)
  6700. ((and (boundp 'standard-indent) standard-indent) standard-indent)
  6701. (t 4)))
  6702. ;; (message "offset(%S)" offset)
  6703. (setq web-mode-attr-indent-offset offset)
  6704. (setq web-mode-code-indent-offset offset)
  6705. (setq web-mode-css-indent-offset offset)
  6706. (setq web-mode-markup-indent-offset offset)
  6707. (setq web-mode-sql-indent-offset offset)
  6708. (add-to-list 'web-mode-indentation-params '("lineup-args" . nil))
  6709. (add-to-list 'web-mode-indentation-params '("lineup-calls" . nil))
  6710. (add-to-list 'web-mode-indentation-params '("lineup-concats" . nil))
  6711. (add-to-list 'web-mode-indentation-params '("lineup-ternary" . nil))
  6712. ))
  6713. (defun web-mode-element-children-fold-or-unfold (&optional pos)
  6714. "Fold/Unfold all the children of the current html element."
  6715. (interactive)
  6716. (unless pos (setq pos (point)))
  6717. (save-excursion
  6718. (dolist (child (reverse (web-mode-element-children pos)))
  6719. (goto-char child)
  6720. (web-mode-fold-or-unfold))
  6721. ))
  6722. (defun web-mode-fold-or-unfold (&optional pos)
  6723. "Toggle folding on an html element or a control block."
  6724. (interactive)
  6725. (web-mode-scan)
  6726. (web-mode-with-silent-modifications
  6727. (save-excursion
  6728. (if pos (goto-char pos))
  6729. (let (beg-inside beg-outside end-inside end-outside overlay overlays regexp)
  6730. (when (looking-back "^[\t ]*" (point-min))
  6731. (back-to-indentation))
  6732. (setq overlays (overlays-at (point)))
  6733. (dolist (elt overlays)
  6734. (when (and (not overlay)
  6735. (eq (overlay-get elt 'font-lock-face) 'web-mode-folded-face))
  6736. (setq overlay elt)))
  6737. (cond
  6738. ;; *** unfolding
  6739. (overlay
  6740. (setq beg-inside (overlay-start overlay)
  6741. end-inside (overlay-end overlay))
  6742. (remove-overlays beg-inside end-inside)
  6743. (put-text-property beg-inside end-inside 'invisible nil)
  6744. )
  6745. ;; *** block folding
  6746. ((and (get-text-property (point) 'block-side)
  6747. (cdr (web-mode-block-is-control (point))))
  6748. (setq beg-outside (web-mode-block-beginning-position (point)))
  6749. (setq beg-inside (1+ (web-mode-block-end-position (point))))
  6750. (when (web-mode-block-match)
  6751. (setq end-inside (point))
  6752. (setq end-outside (1+ (web-mode-block-end-position (point)))))
  6753. )
  6754. ;; *** html comment folding
  6755. ((eq (get-text-property (point) 'tag-type) 'comment)
  6756. (setq beg-outside (web-mode-tag-beginning-position))
  6757. (setq beg-inside (+ beg-outside 4))
  6758. (setq end-outside (web-mode-tag-end-position))
  6759. (setq end-inside (- end-outside 3))
  6760. )
  6761. ;; *** tag folding
  6762. ((or (member (get-text-property (point) 'tag-type) '(start end))
  6763. (web-mode-element-parent))
  6764. (when (not (web-mode-element-is-collapsed (point)))
  6765. (web-mode-tag-beginning)
  6766. (when (eq (get-text-property (point) 'tag-type) 'end)
  6767. (web-mode-tag-match))
  6768. (setq beg-outside (point))
  6769. (web-mode-tag-end)
  6770. (setq beg-inside (point))
  6771. (goto-char beg-outside)
  6772. (when (web-mode-tag-match)
  6773. (setq end-inside (point))
  6774. (web-mode-tag-end)
  6775. (setq end-outside (point)))
  6776. )
  6777. )
  6778. ) ;cond
  6779. (when (and beg-inside beg-outside end-inside end-outside)
  6780. (setq overlay (make-overlay beg-outside end-outside))
  6781. (overlay-put overlay 'font-lock-face 'web-mode-folded-face)
  6782. (put-text-property beg-inside end-inside 'invisible t))
  6783. ))))
  6784. ;;---- TRANSFORMATION ----------------------------------------------------------
  6785. (defun web-mode-buffer-change-tag-case (&optional type)
  6786. "Change html tag case."
  6787. (interactive)
  6788. (save-excursion
  6789. (goto-char (point-min))
  6790. (let ((continue t) f)
  6791. (setq f (if (member type '("upper" "uppercase" "upper-case")) 'uppercase 'downcase))
  6792. (when (and (not (get-text-property (point) 'tag-beg))
  6793. (not (web-mode-tag-next)))
  6794. (setq continue nil))
  6795. (while continue
  6796. (skip-chars-forward "<!/")
  6797. (if (looking-at "\\([[:alnum:]:-]+\\)")
  6798. (replace-match (funcall f (match-string 0)) t))
  6799. ;; (message "tag: %S (%S)"
  6800. ;; (get-text-property (point) 'tag-name)
  6801. ;; (point))
  6802. (unless (web-mode-tag-next)
  6803. (setq continue nil))
  6804. ) ;while
  6805. )))
  6806. (defun web-mode-buffer-change-attr-case (&optional type)
  6807. "Change case of html attribute names."
  6808. (interactive)
  6809. (unless type (setq type "downcase"))
  6810. (save-excursion
  6811. (goto-char (point-min))
  6812. (let ((continue t)
  6813. (fun (if (eq (aref (downcase type) 0) ?u) 'uppercase 'downcase)))
  6814. (while continue
  6815. (cond
  6816. ((not (web-mode-attribute-next))
  6817. (setq continue nil))
  6818. ((looking-at "\\([[:alnum:]-]+\\)")
  6819. (replace-match (funcall fun (match-string 0)) t)
  6820. )
  6821. ) ;cond
  6822. ) ;while
  6823. )))
  6824. ;; tag-case=lower|upper-case , attr-case=lower|upper-case
  6825. ;; special-chars=unicode|html-entities
  6826. ;; smart-apostrophes=bool , smart-quotes=bool , indentation=bool
  6827. (defun web-mode-dom-normalize ()
  6828. "Normalize buffer"
  6829. (interactive)
  6830. (save-excursion
  6831. (let ((rules web-mode-normalization-rules) elt)
  6832. (when (setq elt (cdr (assoc "tag-case" rules)))
  6833. (web-mode-buffer-change-tag-case elt))
  6834. (when (setq elt (cdr (assoc "attr-case" rules)))
  6835. (web-mode-buffer-change-attr-case elt))
  6836. (when (setq elt (cdr (assoc "css-indentation" rules)))
  6837. (web-mode-css-indent))
  6838. (when (setq elt (cdr (assoc "smart-apostrophes" rules)))
  6839. (web-mode-dom-apostrophes-replace))
  6840. (when (setq elt (cdr (assoc "smart-quotes" rules)))
  6841. (web-mode-dom-quotes-replace))
  6842. (when (setq elt (cdr (assoc "special-chars" rules)))
  6843. (if (string= elt "entities")
  6844. (web-mode-dom-entities-encode)
  6845. (web-mode-dom-entities-replace)))
  6846. (when (setq elt (cdr (assoc "whitespaces" rules)))
  6847. (goto-char (point-min))
  6848. (while (not (eobp))
  6849. (forward-line)
  6850. (delete-blank-lines))
  6851. (delete-trailing-whitespace)
  6852. (untabify (point-min) (point-max)))
  6853. (when (setq elt (cdr (assoc "indentation" rules)))
  6854. (web-mode-buffer-indent))
  6855. )))
  6856. (defun web-mode-dom-apostrophes-replace ()
  6857. "Replace char(') with char(’) in the innerText of html elements."
  6858. (interactive)
  6859. (save-excursion
  6860. (let ((min (point-min)) (max (point-max)))
  6861. (when mark-active
  6862. (setq min (region-beginning)
  6863. max (region-end))
  6864. (deactivate-mark))
  6865. (goto-char min)
  6866. (while (web-mode-content-rsf "\\([[:alpha:]]\\)'\\([[:alpha:]]\\)" max)
  6867. (replace-match "\\1’\\2"))
  6868. )))
  6869. (defun web-mode-dom-entities-encode ()
  6870. (save-excursion
  6871. (let (regexp ms elt (min (point-min)) (max (point-max)))
  6872. (when mark-active
  6873. (setq min (region-beginning)
  6874. max (region-end))
  6875. (deactivate-mark))
  6876. (goto-char min)
  6877. (setq regexp "[")
  6878. (dolist (pair web-mode-html-entities)
  6879. (setq regexp (concat regexp (char-to-string (cdr pair))))
  6880. )
  6881. (setq regexp (concat regexp "]"))
  6882. (while (web-mode-content-rsf regexp max)
  6883. (setq elt (match-string-no-properties 0))
  6884. (setq elt (aref elt 0))
  6885. (setq elt (car (rassoc elt web-mode-html-entities)))
  6886. (replace-match (concat "&" elt ";"))
  6887. (setq max (+ max (length elt) 1))
  6888. ) ;while
  6889. )))
  6890. (defun web-mode-dom-entities-replace ()
  6891. "Replace html entities (e.g. &eacute; &#233; or &#x00E9; become é)"
  6892. (interactive)
  6893. (save-excursion
  6894. (let (ms pair elt (min (point-min)) (max (point-max)))
  6895. (when mark-active
  6896. (setq min (region-beginning)
  6897. max (region-end))
  6898. (deactivate-mark))
  6899. (goto-char min)
  6900. (while (web-mode-content-rsf "&\\([#]?[[:alnum:]]\\{2,8\\}\\);" max)
  6901. (setq elt nil)
  6902. (setq ms (match-string-no-properties 1))
  6903. (cond
  6904. ((not (eq (aref ms 0) ?\#))
  6905. (and (setq pair (assoc ms web-mode-html-entities))
  6906. (setq elt (cdr pair))
  6907. (setq elt (char-to-string elt))))
  6908. ((eq (aref ms 1) ?x)
  6909. (setq elt (substring ms 2))
  6910. (setq elt (downcase elt))
  6911. (setq elt (string-to-number elt 16))
  6912. (setq elt (char-to-string elt)))
  6913. (t
  6914. (setq elt (substring ms 1))
  6915. (setq elt (char-to-string (string-to-number elt))))
  6916. ) ;cond
  6917. (when elt (replace-match elt))
  6918. ) ;while
  6919. )))
  6920. (defun web-mode-dom-xml-replace ()
  6921. "Replace &, > and < in html content."
  6922. (interactive)
  6923. (save-excursion
  6924. (let (expr (min (point-min)) (max (point-max)))
  6925. (when mark-active
  6926. (setq min (region-beginning)
  6927. max (region-end))
  6928. (deactivate-mark))
  6929. (goto-char min)
  6930. (while (web-mode-content-rsf "[&<>]" max)
  6931. (replace-match (cdr (assq (char-before) web-mode-xml-chars)) t t))
  6932. )))
  6933. (defun web-mode-dom-quotes-replace ()
  6934. "Replace dumb quotes."
  6935. (interactive)
  6936. (save-excursion
  6937. (let (expr (min (point-min)) (max (point-max)))
  6938. (when mark-active
  6939. (setq min (region-beginning)
  6940. max (region-end))
  6941. (deactivate-mark))
  6942. (goto-char min)
  6943. (setq expr (concat (car web-mode-smart-quotes) "\\2" (cdr web-mode-smart-quotes)))
  6944. (while (web-mode-content-rsf "\\(\"\\)\\(.\\{1,200\\}\\)\\(\"\\)" max)
  6945. (replace-match expr)
  6946. ) ;while
  6947. )))
  6948. ;;---- INDENTATION -------------------------------------------------------------
  6949. ;; todo : passer de règle en règle et mettre un \n à la fin
  6950. (defun web-mode-css-indent ()
  6951. (save-excursion
  6952. (goto-char (point-min))
  6953. (let ((continue t) rule part-end)
  6954. (while continue
  6955. (cond
  6956. ((not (web-mode-part-next))
  6957. (setq continue nil))
  6958. ((eq (get-text-property (point) 'part-side) 'css)
  6959. (setq part-end (web-mode-part-end-position))
  6960. (while (setq rule (web-mode-css-rule-next part-end))
  6961. (when (not (looking-at-p "[[:space:]]*\\($\\|<\\)"))
  6962. (newline)
  6963. (indent-according-to-mode)
  6964. (setq part-end (web-mode-part-end-position)))
  6965. )
  6966. )
  6967. ) ;cond
  6968. )
  6969. )))
  6970. (defun web-mode-buffer-indent ()
  6971. "Indent all buffer."
  6972. (interactive)
  6973. (let ((debug t) (ts (current-time)) (sub nil))
  6974. (indent-region (point-min) (point-max))
  6975. (when debug
  6976. (setq sub (time-subtract (current-time) ts))
  6977. (message "buffer-indent: time elapsed = %Ss %9Sµs" (nth 1 sub) (nth 2 sub)))
  6978. (delete-trailing-whitespace)))
  6979. (defun web-mode-point-context (pos)
  6980. "POS should be at the beginning of the indentation."
  6981. (save-excursion
  6982. (let (curr-char curr-indentation curr-line
  6983. language
  6984. options
  6985. reg-beg reg-col
  6986. prev-char prev-indentation prev-line prev-pos
  6987. token
  6988. part-language
  6989. depth)
  6990. (setq reg-beg (point-min)
  6991. reg-col 0
  6992. token "live"
  6993. options ""
  6994. language ""
  6995. prev-line ""
  6996. prev-char 0
  6997. prev-pos nil)
  6998. (when (get-text-property pos 'part-side)
  6999. (setq part-language (symbol-name (get-text-property pos 'part-side))))
  7000. ;;(message "part-language=%S" part-language)
  7001. (cond
  7002. ((and (bobp) (member web-mode-content-type '("html" "xml")))
  7003. (setq language web-mode-content-type)
  7004. )
  7005. ((string= web-mode-content-type "css")
  7006. (setq language "css"
  7007. curr-indentation web-mode-css-indent-offset))
  7008. ((member web-mode-content-type '("javascript" "json" "typescript"))
  7009. (setq language web-mode-content-type
  7010. curr-indentation web-mode-code-indent-offset))
  7011. ((or (string= web-mode-content-type "jsx")
  7012. (and part-language (string= part-language "jsx")))
  7013. (setq language "jsx"
  7014. curr-indentation web-mode-code-indent-offset)
  7015. (cond
  7016. ((web-mode-jsx-is-html pos)
  7017. (setq curr-indentation web-mode-markup-indent-offset
  7018. options "is-html"))
  7019. ((and (setq depth (get-text-property pos 'jsx-depth)) (> depth 1))
  7020. (when (get-text-property pos 'jsx-beg)
  7021. (setq depth (1- depth)))
  7022. (setq reg-beg (web-mode-jsx-depth-beginning-position pos depth))
  7023. (setq reg-beg (1+ reg-beg))
  7024. ;;(message "%S" (point))
  7025. (save-excursion
  7026. (goto-char reg-beg)
  7027. ;;(message "pt=%S" reg-beg)
  7028. (cond
  7029. ((and (not (looking-at-p "[ ]*$"))
  7030. (looking-back "^[[:space:]]*{" (point-min)))
  7031. (setq reg-col (+ (current-indentation) ;; #1027
  7032. (cond
  7033. ((looking-at "[ ]+") (1+ (length (match-string-no-properties 0))))
  7034. (t 0))
  7035. ))
  7036. )
  7037. ((looking-at-p "[ ]*\\[[ ]*$") ;; #0659
  7038. (setq reg-col (current-indentation))
  7039. )
  7040. ((and (looking-back "=[ ]*{" (point-min)) ;; #0739 #1022
  7041. (not (looking-at-p "[[:space:]]*<")))
  7042. (setq reg-col (current-indentation))
  7043. )
  7044. ;;((and (looking-back "=[ ]*{" (point-min)) ;; #0739
  7045. ;; (looking-at-p "{[ ]*"))
  7046. ;; (setq reg-col (current-indentation))
  7047. ;; )
  7048. ((get-text-property (1- (point)) 'tag-beg)
  7049. ;;(message "point=%S" (point))
  7050. (setq reg-col (current-indentation))
  7051. )
  7052. (t
  7053. (message "%S : %S %S" (point) (current-indentation) web-mode-code-indent-offset)
  7054. ;;(setq reg-col (+ (current-indentation) web-mode-code-indent-offset web-mode-jsx-expression-padding)))
  7055. (setq reg-col (+ (current-indentation) web-mode-code-indent-offset)))
  7056. )
  7057. ;;(message "%S %S %S" (point) (current-indentation) reg-col)
  7058. ) ;save-excursion
  7059. )
  7060. ((string= web-mode-content-type "jsx")
  7061. (setq reg-beg (point-min)))
  7062. (t
  7063. (setq reg-beg (or (web-mode-part-beginning-position pos) (point-min)))
  7064. (save-excursion
  7065. (goto-char reg-beg)
  7066. (search-backward "<" nil t)
  7067. (setq reg-col (current-column))
  7068. ) ;save-excursion
  7069. )
  7070. ) ;cond
  7071. ;;(message "jsx reg-beg=%S" reg-beg)
  7072. ) ;jsx
  7073. ((string= web-mode-content-type "php")
  7074. (setq language "php"
  7075. curr-indentation web-mode-code-indent-offset))
  7076. ((or (string= web-mode-content-type "xml"))
  7077. (setq language "xml"
  7078. curr-indentation web-mode-markup-indent-offset))
  7079. ;; TODO: est ce util ?
  7080. ((and (get-text-property pos 'tag-beg)
  7081. (get-text-property pos 'tag-name)
  7082. ;;(not (get-text-property pos 'part-side))
  7083. )
  7084. (setq language "html"
  7085. curr-indentation web-mode-markup-indent-offset))
  7086. ((and (get-text-property pos 'block-side)
  7087. (not (get-text-property pos 'block-beg)))
  7088. (setq reg-beg (or (web-mode-block-beginning-position pos) (point-min)))
  7089. (goto-char reg-beg)
  7090. (setq reg-col (current-column))
  7091. ;;(message "%S %S" reg-beg reg-col)
  7092. (setq language web-mode-engine)
  7093. (setq curr-indentation web-mode-code-indent-offset)
  7094. (cond
  7095. ((string= web-mode-engine "blade")
  7096. (save-excursion
  7097. (when (web-mode-rsf "{[{!]+[ ]*")
  7098. (setq reg-col (current-column))))
  7099. (setq reg-beg (+ reg-beg 2))
  7100. )
  7101. ((string= web-mode-engine "razor")
  7102. ;;(setq reg-beg (+ reg-beg 2))
  7103. ;;(setq reg-col (current-column))
  7104. )
  7105. ;; tests/demo.chtml
  7106. ((string= web-mode-engine "ctemplate")
  7107. (save-excursion
  7108. (when (web-mode-rsf "{{#?")
  7109. (setq reg-col (current-column))))
  7110. )
  7111. ((string= web-mode-engine "dust")
  7112. (save-excursion
  7113. (when (web-mode-rsf "{@")
  7114. (setq reg-col (current-column))))
  7115. )
  7116. ((string= web-mode-engine "svelte")
  7117. (save-excursion
  7118. (when (web-mode-rsf "{@")
  7119. (setq reg-col (current-column))))
  7120. )
  7121. ((string= web-mode-engine "template-toolkit")
  7122. (setq reg-beg (+ reg-beg 3)
  7123. reg-col (+ reg-col 3))
  7124. )
  7125. ((and (string= web-mode-engine "jsp")
  7126. (web-mode-looking-at "<%@" reg-beg))
  7127. (save-excursion
  7128. (goto-char reg-beg)
  7129. (looking-at "<%@[ ]*[[:alpha:]]+[ ]+\\|</?[[:alpha:]]+[:.][[:alpha:]]+[ ]+")
  7130. (goto-char (match-end 0))
  7131. (setq reg-col (current-column))
  7132. )
  7133. )
  7134. ((and (string= web-mode-engine "freemarker")
  7135. (web-mode-looking-at "<@\\|<%@\\|<[[:alpha:]]" reg-beg))
  7136. (save-excursion
  7137. (goto-char reg-beg)
  7138. (looking-at "<@[[:alpha:].]+[ ]+\\|<%@[ ]*[[:alpha:]]+[ ]+\\|<[[:alpha:]]+:[[:alpha:]]+[ ]+")
  7139. (goto-char (match-end 0))
  7140. (setq reg-col (current-column))
  7141. )
  7142. )
  7143. ) ;cond
  7144. ) ;block-side
  7145. ((and part-language (member part-language
  7146. '("css" "javascript" "json" "sql" "markdown"
  7147. "pug" "ruby" "sass" "stylus" "typescript")))
  7148. (setq reg-beg (or (web-mode-part-beginning-position pos) (point-min)))
  7149. (goto-char reg-beg)
  7150. (if (and (string= web-mode-engine "mojolicious")
  7151. (looking-back "javascript begin"))
  7152. (search-backward "%" nil t)
  7153. (search-backward "<" nil t))
  7154. (setq reg-col (current-column))
  7155. (setq language part-language)
  7156. (cond
  7157. ((string= language "css")
  7158. (setq curr-indentation web-mode-css-indent-offset))
  7159. ((string= language "sql")
  7160. (setq curr-indentation web-mode-sql-indent-offset))
  7161. ((string= language "markdown")
  7162. (setq curr-indentation web-mode-code-indent-offset))
  7163. ((string= language "pug")
  7164. (setq curr-indentation web-mode-code-indent-offset))
  7165. ((string= language "sass")
  7166. (setq curr-indentation web-mode-code-indent-offset))
  7167. ((string= language "stylus")
  7168. (setq curr-indentation web-mode-code-indent-offset))
  7169. ((string= language "ruby")
  7170. (setq curr-indentation web-mode-code-indent-offset))
  7171. ((string= language "typescript")
  7172. (setq curr-indentation web-mode-code-indent-offset))
  7173. (t
  7174. (setq language "javascript"
  7175. curr-indentation web-mode-code-indent-offset))
  7176. )
  7177. ) ;part-side
  7178. (t
  7179. (setq language "html"
  7180. curr-indentation web-mode-markup-indent-offset)
  7181. )
  7182. ) ;cond
  7183. (cond
  7184. ((or (and (> pos (point-min))
  7185. (eq (get-text-property pos 'part-token) 'comment)
  7186. (eq (get-text-property (1- pos) 'part-token) 'comment)
  7187. (progn
  7188. (setq reg-beg (previous-single-property-change pos 'part-token))
  7189. t))
  7190. (and (> pos (point-min))
  7191. (eq (get-text-property pos 'block-token) 'comment)
  7192. (eq (get-text-property (1- pos) 'block-token) 'comment)
  7193. (progn
  7194. (setq reg-beg (previous-single-property-change pos 'block-token))
  7195. t))
  7196. (and (> pos (point-min))
  7197. (eq (get-text-property pos 'tag-type) 'comment)
  7198. (not (get-text-property pos 'tag-beg))
  7199. (progn
  7200. (setq reg-beg (web-mode-tag-beginning-position pos))
  7201. t))
  7202. )
  7203. (setq token "comment"))
  7204. ((or (and (> pos (point-min))
  7205. (member (get-text-property pos 'part-token)
  7206. '(string context key))
  7207. (member (get-text-property (1- pos) 'part-token)
  7208. '(string context key)))
  7209. (and (eq (get-text-property pos 'block-token) 'string)
  7210. (eq (get-text-property (1- pos) 'block-token) 'string)))
  7211. (setq token "string"))
  7212. )
  7213. (goto-char pos)
  7214. (setq curr-line (web-mode-trim
  7215. (buffer-substring-no-properties
  7216. (line-beginning-position)
  7217. (line-end-position))))
  7218. (setq curr-char (if (string= curr-line "") 0 (aref curr-line 0)))
  7219. (when (or (member language '("php" "blade" "javascript" "typescript" "jsx" "razor" "css"))
  7220. (and (member language '("html" "xml"))
  7221. (not (eq ?\< curr-char))))
  7222. (let (prev)
  7223. (cond
  7224. ((member language '("html" "xml" "javascript" "jsx" "css"))
  7225. (when (setq prev (web-mode-part-previous-live-line reg-beg))
  7226. (setq prev-line (nth 0 prev)
  7227. prev-indentation (nth 1 prev)
  7228. prev-pos (nth 2 prev))
  7229. )
  7230. )
  7231. ((setq prev (web-mode-block-previous-live-line))
  7232. (setq prev-line (car prev)
  7233. prev-indentation (cdr prev))
  7234. (setq prev-line (web-mode-clean-block-line prev-line)))
  7235. ) ;cond
  7236. ) ;let
  7237. (when (>= (length prev-line) 1)
  7238. (setq prev-char (aref prev-line (1- (length prev-line))))
  7239. (setq prev-line (substring-no-properties prev-line))
  7240. )
  7241. )
  7242. (cond
  7243. ((not (member web-mode-content-type '("html" "xml")))
  7244. )
  7245. ((member language '("javascript" "typescript" "jsx" "ruby"))
  7246. (setq reg-col (if web-mode-script-padding (+ reg-col web-mode-script-padding) 0)))
  7247. ((member language '("css" "sql" "markdown" "pug" "sass" "stylus"))
  7248. (setq reg-col (if web-mode-style-padding (+ reg-col web-mode-style-padding) 0)))
  7249. ((not (member language '("html" "xml")))
  7250. (setq reg-col
  7251. (cond
  7252. ((not web-mode-block-padding) reg-col)
  7253. ((eq web-mode-block-padding -1) 0)
  7254. (t (+ reg-col web-mode-block-padding))
  7255. ) ;cond
  7256. ) ;setq
  7257. )
  7258. )
  7259. (list :curr-char curr-char
  7260. :curr-indentation curr-indentation
  7261. :curr-line curr-line
  7262. :language language
  7263. :options options
  7264. :prev-char prev-char
  7265. :prev-indentation prev-indentation
  7266. :prev-line prev-line
  7267. :prev-pos prev-pos
  7268. :reg-beg reg-beg
  7269. :reg-col reg-col
  7270. :token token)
  7271. )))
  7272. (defun web-mode-indent-line ()
  7273. (web-mode-scan)
  7274. (let ((offset nil)
  7275. (char nil)
  7276. (debug nil)
  7277. (inhibit-modification-hooks nil)
  7278. (adjust t))
  7279. (save-excursion
  7280. (back-to-indentation)
  7281. (setq char (char-after))
  7282. (let* ((pos (point))
  7283. (ctx (web-mode-point-context pos))
  7284. (curr-char (plist-get ctx :curr-char))
  7285. (curr-indentation (plist-get ctx :curr-indentation))
  7286. (curr-line (plist-get ctx :curr-line))
  7287. (language (plist-get ctx :language))
  7288. (prev-char (plist-get ctx :prev-char))
  7289. (prev-indentation (plist-get ctx :prev-indentation))
  7290. (prev-line (plist-get ctx :prev-line))
  7291. (prev-pos (plist-get ctx :prev-pos))
  7292. (reg-beg (plist-get ctx :reg-beg))
  7293. (reg-col (plist-get ctx :reg-col))
  7294. (token (plist-get ctx :token))
  7295. (options (plist-get ctx :options))
  7296. (chars (list curr-char prev-char))
  7297. (tmp nil)
  7298. (is-js (member language '("javascript" "jsx" "ejs"))))
  7299. (when (member language '("json" "typescript"))
  7300. (setq language "javascript"))
  7301. ;;(message "%S" language)
  7302. ;;(message "curr-char=[%c] prev-char=[%c]\n%S" curr-char prev-char ctx)
  7303. ;;(message "options=%S" ctx)
  7304. (cond
  7305. ((or (bobp) (= (line-number-at-pos pos) 1))
  7306. (when debug (message "I100(%S) first line" pos))
  7307. (setq offset 0))
  7308. ;; #1073
  7309. ((get-text-property pos 'invisible)
  7310. (when debug (message "I110(%S) invible" pos))
  7311. (setq offset nil))
  7312. ((string= token "string")
  7313. (when debug (message "I120(%S) string" pos))
  7314. (cond
  7315. ((web-mode-is-token-end pos)
  7316. (if (get-text-property pos 'block-side)
  7317. (web-mode-block-token-beginning)
  7318. (web-mode-part-token-beginning))
  7319. (setq offset (current-indentation))
  7320. )
  7321. ((and web-mode-enable-sql-detection
  7322. (web-mode-block-token-starts-with (concat "[ \n]*" web-mode-sql-queries)))
  7323. (save-excursion
  7324. (let (col)
  7325. (web-mode-block-string-beginning)
  7326. (skip-chars-forward "[ \"'\n]")
  7327. (setq col (current-column))
  7328. (goto-char pos)
  7329. (if (looking-at-p "\\(SELECT\\|INSERT\\|DELETE\\|UPDATE\\|FROM\\|LEFT\\|JOIN\\|WHERE\\|GROUP BY\\|LIMIT\\|HAVING\\|\)\\)")
  7330. (setq offset col)
  7331. (setq offset (+ col web-mode-sql-indent-offset)))
  7332. )
  7333. ) ;save-excursion
  7334. )
  7335. ((and is-js
  7336. (web-mode-is-ql-string pos "Relay\.QL"))
  7337. (setq offset (web-mode-relayql-indentation pos))
  7338. )
  7339. ((and is-js
  7340. (web-mode-is-ql-string pos "gql"))
  7341. (setq offset (web-mode-relayql-indentation pos "gql"))
  7342. )
  7343. ((and is-js
  7344. (web-mode-is-ql-string pos "graphql"))
  7345. (setq offset (web-mode-relayql-indentation pos "graphql"))
  7346. )
  7347. ((and is-js
  7348. (web-mode-is-css-string pos))
  7349. (when debug (message "I127(%S) css string" pos))
  7350. (setq offset (web-mode-token-css-indentation pos))
  7351. )
  7352. ((and is-js
  7353. (web-mode-is-html-string pos))
  7354. (when debug (message "I128(%S) html string" pos))
  7355. (setq offset (web-mode-token-html-indentation pos))
  7356. )
  7357. (t
  7358. (setq offset nil))
  7359. ) ;cond
  7360. ) ;case string
  7361. ((string= token "comment")
  7362. (when debug (message "I130(%S) comment" pos))
  7363. (if (eq (get-text-property pos 'tag-type) 'comment)
  7364. (web-mode-tag-beginning)
  7365. (goto-char (car
  7366. (web-mode-property-boundaries
  7367. (if (eq (get-text-property pos 'part-token) 'comment)
  7368. 'part-token
  7369. 'block-token)
  7370. pos))))
  7371. (setq offset (current-column))
  7372. (cond
  7373. ((string= web-mode-engine "freemarker")
  7374. (setq offset (+ (current-indentation) 2)))
  7375. ((member (buffer-substring-no-properties (point) (+ (point) 2)) '("/*" "{*" "@*"))
  7376. (cond
  7377. ((eq ?\* curr-char)
  7378. (setq offset (+ offset 1)))
  7379. (t
  7380. (setq offset (+ offset 3)))
  7381. ) ;cond
  7382. )
  7383. ((string= (buffer-substring-no-properties (point) (+ (point) 4)) "<!--")
  7384. (cond
  7385. ((string-match-p "^<!\\[endif" curr-line)
  7386. )
  7387. ((looking-at-p "<!--\\[if")
  7388. (setq offset (+ offset web-mode-markup-indent-offset)))
  7389. ((string-match-p "^-->" curr-line)
  7390. (setq offset offset))
  7391. ((string-match-p "^-" curr-line)
  7392. (setq offset (+ offset 3)))
  7393. (t
  7394. (setq offset (+ offset 5)))
  7395. ) ;cond
  7396. )
  7397. ((and (string= web-mode-engine "django") (looking-back "{% comment %}" (point-min)))
  7398. (setq offset (- offset 12)))
  7399. ((and (string= web-mode-engine "mako") (looking-back "<%doc%>" (point-min)))
  7400. (setq offset (- offset 6)))
  7401. ((and (string= web-mode-engine "mason") (looking-back "<%doc%>" (point-min)))
  7402. (setq offset (- offset 6)))
  7403. ) ;cond
  7404. ) ;case comment
  7405. ((and (string= web-mode-engine "mason")
  7406. (string-match-p "^%" curr-line))
  7407. (when debug (message "I140(%S) mason" pos))
  7408. (setq offset 0))
  7409. ((and (get-text-property pos 'block-beg)
  7410. (or (web-mode-block-is-close pos)
  7411. (web-mode-block-is-inside pos)))
  7412. (when debug (message "I150(%S) block-match" pos))
  7413. (cond
  7414. ((not (web-mode-block-match))
  7415. )
  7416. ((and (string= web-mode-engine "closure")
  7417. (string-match-p "{\\(case\\|default\\)" curr-line))
  7418. (setq offset (+ (current-indentation) web-mode-markup-indent-offset)))
  7419. (t
  7420. (setq offset (current-indentation))
  7421. (if (and (string= web-mode-engine "blade")
  7422. (string-match-p "@break" curr-line))
  7423. (setq offset (+ (current-indentation) offset)))
  7424. )
  7425. ) ;cond
  7426. )
  7427. ((eq (get-text-property pos 'block-token) 'delimiter-end)
  7428. (when debug (message "I160(%S) block-beginning" pos))
  7429. (when (web-mode-block-beginning)
  7430. (setq reg-col (current-indentation))
  7431. (setq offset (current-column))))
  7432. ((or (and (get-text-property pos 'tag-beg)
  7433. (eq (get-text-property pos 'tag-type) 'end))
  7434. (and (eq (get-text-property pos 'tag-type) 'comment)
  7435. (string-match-p "<!--#\\(else\\|elif\\|endif\\)" curr-line)))
  7436. (when debug (message "I170(%S) tag-match" pos))
  7437. (when (web-mode-tag-match)
  7438. (setq offset (current-indentation))))
  7439. ((and (member language '("jsx"))
  7440. (eq curr-char ?\})
  7441. (get-text-property pos 'jsx-end))
  7442. (when debug (message "I180(%S) jsx-expr-end" pos))
  7443. (web-mode-go (1- reg-beg))
  7444. (setq reg-col nil)
  7445. ;;(setq offset (current-column)))
  7446. (setq offset (current-indentation)))
  7447. ((and (member language '("html" "xml" "javascript" "jsx"))
  7448. (get-text-property pos 'tag-type)
  7449. (not (get-text-property pos 'tag-beg))
  7450. ;;(or (not (string= language "jsx"))
  7451. ;; (string= options "is-html"))
  7452. (not (and (string= language "jsx")
  7453. (or (string= options "is-html")
  7454. (web-mode-jsx-is-expr pos))))
  7455. )
  7456. (when debug (message "I190(%S) attr-indent" pos))
  7457. (cond
  7458. ((and (not (get-text-property pos 'tag-attr-beg))
  7459. (get-text-property pos 'tag-attr)
  7460. (get-text-property (1- pos) 'tag-attr)
  7461. (web-mode-attribute-beginning)
  7462. (not (string-match-p "^/?>" curr-line))
  7463. ;;(progn (message "pos=%S point=%S" pos (point)) t)
  7464. )
  7465. (cond
  7466. ((eq (logand (get-text-property (point) 'tag-attr-beg) 8) 8)
  7467. (setq offset nil))
  7468. ((not (web-mode-tag-beginning))
  7469. (message "** tag-beginning ** failure")
  7470. (setq offset nil))
  7471. (web-mode-attr-value-indent-offset
  7472. (setq offset (+ (current-column) web-mode-attr-value-indent-offset)))
  7473. ((web-mode-dom-rsf "=[ ]*[\"']?" pos)
  7474. ;;(message "%S" (point))
  7475. (setq offset (current-column)))
  7476. (t
  7477. (setq offset (+ (current-column) web-mode-markup-indent-offset)))
  7478. ) ;cond
  7479. ) ;and
  7480. ((not (web-mode-tag-beginning))
  7481. (message "** error ** unable to jump to tag beg"))
  7482. ((string-match-p "^/?>" curr-line)
  7483. (setq offset (web-mode-column-at-pos (web-mode-tag-beginning-position pos)))
  7484. )
  7485. (web-mode-attr-indent-offset
  7486. (setq offset (+ (current-column) web-mode-attr-indent-offset)))
  7487. ((looking-at-p (concat web-mode-start-tag-regexp "[ ]*\n"))
  7488. ;;(message "%S: %S" (point) (web-mode-inside-block-control pos))
  7489. (setq offset (+ (current-column) (or web-mode-attr-indent-offset web-mode-code-indent-offset)))
  7490. ;; #1109
  7491. (setq tmp (web-mode-inside-block-control pos))
  7492. (when (and tmp (> tmp (point)))
  7493. (setq offset (+ offset (or web-mode-attr-indent-offset web-mode-code-indent-offset))))
  7494. )
  7495. ((web-mode-attribute-next)
  7496. (setq offset (current-column)))
  7497. ) ;cond
  7498. ) ;attr-indent
  7499. ((or (member language '("html" "xml"))
  7500. (and (member language '("jsx"))
  7501. (string= options "is-html")))
  7502. (when debug (message "I200(%S) web-mode-markup-indentation" pos))
  7503. ;; https://www.w3.org/TR/html5/syntax.html#optional-tags
  7504. (when web-mode-enable-optional-tags
  7505. (save-excursion
  7506. (let (tag-name parent-tag-name parent-tag-pos)
  7507. (when (and (setq tag-name (get-text-property pos 'tag-name))
  7508. (setq parent-tag-pos (web-mode-element-parent-position pos))
  7509. (setq parent-tag-name (get-text-property parent-tag-pos 'tag-name))
  7510. (or (and (string= parent-tag-name "p") (member tag-name '("p" "address", "article", "aside", "blockquote", "div", "dl", "fieldset", "footer", "form", "h1", "h2", "h3", "h4", "h5", "h6", "header", "hgroup", "hr", "main", "nav", "ol", "pre", "section", "table", "ul")))
  7511. (and (string= parent-tag-name "li") (member tag-name '("li")))
  7512. (and (string= parent-tag-name "dt") (member tag-name '("dt" "dd")))
  7513. (and (string= parent-tag-name "td") (member tag-name '("td" "th")))
  7514. (and (string= parent-tag-name "th") (member tag-name '("td" "th")))
  7515. ))
  7516. (when debug (message "I205(%S) %S(%S) auto-closing" pos parent-tag-name parent-tag-pos))
  7517. (setq offset (web-mode-indentation-at-pos parent-tag-pos))
  7518. )))) ; when let save-excursion when
  7519. (when (string= web-mode-engine "closure")
  7520. (save-excursion
  7521. (when (and (re-search-backward "{/?switch" nil t)
  7522. (string= (match-string-no-properties 0) "{switch"))
  7523. (setq offset (+ (current-indentation) (* 2 web-mode-markup-indent-offset)))
  7524. )
  7525. ))
  7526. (cond
  7527. ((not (null offset))
  7528. )
  7529. ((get-text-property pos 'tag-beg)
  7530. (setq offset (web-mode-markup-indentation pos))
  7531. )
  7532. ((and web-mode-indentless-elements
  7533. (not (string= language "jsx"))
  7534. (null (get-text-property pos 'block-side))
  7535. (null (get-text-property pos 'part-side))
  7536. (and (null (get-text-property pos 'tag-beg))
  7537. (save-excursion
  7538. (and (web-mode-element-parent)
  7539. (member (get-text-property (point) 'tag-name) web-mode-indentless-elements))))
  7540. )
  7541. (setq offset nil))
  7542. ((or (eq (length curr-line) 0)
  7543. (= web-mode-indent-style 2)
  7544. (get-text-property pos 'tag-beg)
  7545. (get-text-property pos 'reg-beg))
  7546. (setq offset (web-mode-markup-indentation pos))
  7547. )
  7548. )
  7549. )
  7550. ((string= language "ctemplate")
  7551. (when debug (message "I210(%S) ctemplate" pos))
  7552. (setq offset reg-col))
  7553. ((string= language "expressionengine")
  7554. (when debug (message "I212(%S) expressionengine" pos))
  7555. (setq offset (+ reg-col (or web-mode-attr-indent-offset web-mode-code-indent-offset))))
  7556. ((string= language "asp")
  7557. (when debug (message "I230(%S) asp" pos))
  7558. (setq offset (web-mode-asp-indentation pos
  7559. curr-line
  7560. reg-col
  7561. curr-indentation
  7562. reg-beg)))
  7563. ((member language '("lsp" "cl-emb" "artanis"))
  7564. (when debug (message "I240(%S) lsp" pos))
  7565. (setq offset (web-mode-lisp-indentation pos ctx)))
  7566. ((and (member curr-char '(?\}))
  7567. (string= language "razor")
  7568. (get-text-property pos 'block-end))
  7569. (when debug (message "I245(%S) razor closing" pos))
  7570. (goto-char reg-beg)
  7571. ;;(message "%S %S" (point) (current-column))
  7572. (setq offset (current-column)
  7573. reg-col nil)
  7574. )
  7575. ((member curr-char '(?\} ?\) ?\]))
  7576. (when debug (message "I250(%S) closing-paren" pos))
  7577. (let (ori pos2)
  7578. (setq pos2 pos)
  7579. ;; #1096
  7580. (when (looking-at-p ".[\]})]+")
  7581. (skip-chars-forward "[\]})]")
  7582. (backward-char)
  7583. (setq pos2 (point))
  7584. ) ;when
  7585. (if (get-text-property pos 'block-side)
  7586. (setq ori (web-mode-block-opening-paren-position pos2 reg-beg))
  7587. (setq ori (web-mode-part-opening-paren-position pos2 reg-beg)))
  7588. ;;(message "ori=%S" ori)
  7589. (cond
  7590. ((null ori)
  7591. (setq offset reg-col))
  7592. ((and (goto-char ori)
  7593. (looking-back ")[ ]*" (point-min)) ;; peut-on se passer du looking-back ?
  7594. (re-search-backward ")[ ]*" nil t)
  7595. (web-mode-block-opening-paren reg-beg))
  7596. (back-to-indentation)
  7597. (setq offset (current-indentation))
  7598. )
  7599. (t
  7600. (goto-char ori)
  7601. (back-to-indentation)
  7602. (setq offset (current-indentation))
  7603. ;;(message "ori=%S offset=%S" ori offset)
  7604. (when (get-text-property pos 'jsx-depth)
  7605. ;;(when (get-text-property pos 'jsx-end)
  7606. (setq adjust nil))
  7607. ) ;t
  7608. ) ;cond
  7609. ) ;let
  7610. )
  7611. ((member language '("mako" "web2py"))
  7612. (when debug (message "I254(%S) python (mako/web2py)" pos))
  7613. (setq offset (web-mode-python-indentation pos
  7614. curr-line
  7615. reg-col
  7616. curr-indentation
  7617. reg-beg)))
  7618. ((member language '("erb" "ruby"))
  7619. (when debug (message "I260(%S) erb" pos))
  7620. (setq offset (web-mode-ruby-indentation pos
  7621. curr-line
  7622. reg-col
  7623. curr-indentation
  7624. reg-beg)))
  7625. ((string= language "css")
  7626. (when debug (message "I270(%S) css-indentation" pos))
  7627. ;;(message "prev=%c" prev-char)
  7628. (cond
  7629. ((eq prev-char ?:)
  7630. (setq offset (+ prev-indentation web-mode-css-indent-offset)))
  7631. ((eq prev-char ?,)
  7632. (setq offset prev-indentation))
  7633. (t
  7634. (setq offset (car (web-mode-css-indentation pos
  7635. reg-col
  7636. curr-indentation
  7637. language
  7638. reg-beg))))))
  7639. ((string= language "sql")
  7640. (when debug (message "I280(%S) sql" pos))
  7641. (setq offset (car (web-mode-sql-indentation pos
  7642. reg-col
  7643. curr-indentation
  7644. language
  7645. reg-beg))))
  7646. ((string= language "markdown")
  7647. (when debug (message "I290(%S) markdown" pos))
  7648. (setq offset (car (web-mode-markdown-indentation pos
  7649. reg-col
  7650. curr-indentation
  7651. language
  7652. reg-beg))))
  7653. ((string= language "stylus")
  7654. (when debug (message "I294(%S) stylus" pos))
  7655. (setq offset (car (web-mode-stylus-indentation pos
  7656. reg-col
  7657. curr-indentation
  7658. language
  7659. reg-beg))))
  7660. ((string= language "sass")
  7661. (when debug (message "I296(%S) sass" pos))
  7662. (setq offset (car (web-mode-stylus-indentation pos
  7663. reg-col
  7664. curr-indentation
  7665. language
  7666. reg-beg))))
  7667. ((string= language "pug")
  7668. (when debug (message "I298(%S) pug" pos))
  7669. (setq offset (car (web-mode-pug-indentation pos
  7670. reg-col
  7671. curr-indentation
  7672. language
  7673. reg-beg))))
  7674. ((and (string= language "razor")
  7675. (string-match-p "^\\." curr-line)
  7676. (string-match-p "^\\." prev-line))
  7677. (when debug (message "I300(%S) razor" pos))
  7678. (setq offset prev-indentation))
  7679. ((and (string= language "razor")
  7680. (string-match-p "^case " curr-line)
  7681. (string-match-p "^case " prev-line))
  7682. (when debug (message "I310(%S) razor case" pos))
  7683. (search-backward "case ")
  7684. (setq offset (current-column)))
  7685. ((and is-js
  7686. (member ?\. chars)
  7687. (not (string-match-p "^\\.\\.\\." curr-line)))
  7688. (when debug (message "I320(%S) javascript-calls" pos))
  7689. (let (pair)
  7690. (setq pair (web-mode-javascript-calls-beginning-position pos reg-beg))
  7691. ;;(message "%S" pair)
  7692. (when pair
  7693. (goto-char (car pair))
  7694. ;;(message "%S %S" (point) pair)
  7695. (cond
  7696. ((cdr (assoc "lineup-calls" web-mode-indentation-params))
  7697. ;;(message "ici")
  7698. ;;(search-forward ".")
  7699. (if (cdr pair)
  7700. (progn
  7701. (goto-char (cdr pair))
  7702. (setq offset (current-column))
  7703. (looking-at "\\.\\([ \t\n]*\\)")
  7704. (setq offset (- offset (length (match-string-no-properties 1))))
  7705. (unless (eq curr-char ?\.) (setq offset (1+ offset)))
  7706. ) ;progn
  7707. ;; TODO: cela devrait etre fait dans web-mode-javascript-calls-beginning-position
  7708. (skip-chars-forward " \t\n")
  7709. (setq offset (+ (current-indentation) web-mode-code-indent-offset))
  7710. ) ;if
  7711. )
  7712. (t
  7713. (setq offset (+ (current-indentation) web-mode-code-indent-offset))
  7714. ) ;t
  7715. ) ;cond
  7716. ) ;when
  7717. ) ;let
  7718. )
  7719. ((and is-js
  7720. (member ?\+ chars))
  7721. (when debug (message "I330(%S) javascript-string" pos))
  7722. ;;(message "js-concat")
  7723. (cond
  7724. ((not (web-mode-javascript-string-beginning pos reg-beg))
  7725. )
  7726. ((null (cdr (assoc "lineup-concats" web-mode-indentation-params)))
  7727. (setq offset (+ (current-indentation) web-mode-code-indent-offset)))
  7728. ((not (eq curr-char ?\+))
  7729. (setq offset (current-column)))
  7730. (t
  7731. (setq offset (current-column))
  7732. (when (not (looking-back "\\(^[ \t]+\\|if[ ]*[(]?\\)" (point-min)))
  7733. (goto-char pos)
  7734. (looking-at "\\+[ \t\n]*")
  7735. (setq offset (- offset (length (match-string-no-properties 0)))))
  7736. )
  7737. )
  7738. )
  7739. ;; #579 , #742
  7740. ((and (member language '("javascript" "jsx" "ejs" "php"))
  7741. (string-match-p "=[>]?$" prev-line))
  7742. (when debug (message "I340(%S)" pos))
  7743. (setq offset (+ prev-indentation web-mode-code-indent-offset))
  7744. ;;(message "ici%S" offset)
  7745. )
  7746. ;; #1016
  7747. ((and (member language '("javascript" "jsx" "ejs"))
  7748. (string-match-p "^[ \t]*|}" curr-line))
  7749. (when debug (message "I346(%S) flow-exact-object-type-end" pos))
  7750. (when (re-search-backward "{|" reg-beg t)
  7751. (setq offset (current-indentation))
  7752. )
  7753. )
  7754. ;; #446, #638, #800, #978, #998
  7755. ((and (member language '("javascript" "jsx" "ejs" "php"))
  7756. (or (string-match-p "[&|?:+-]$" prev-line)
  7757. (string-match-p "^[&|?:+-]" curr-line))
  7758. (not (and (string= language "php")
  7759. (string-match-p "^->" curr-line)))
  7760. (not (and (string= language "php")
  7761. (string-match-p "\\(else[ ]?:\\|if[ ]?([^)]*)[ ]?:\\)" prev-line)))
  7762. (not (string-match-p "^\\(++\\|--\\)" curr-line))
  7763. (not (and is-js
  7764. (string-match-p "]:\\|{|$" prev-line)))
  7765. (not (and (eq prev-char ?\:)
  7766. (string-match-p "^\\(case\\|default\\)" prev-line)))
  7767. )
  7768. ;;(message "prev=%S" prev-line)
  7769. (when debug (message "I350(%S) multiline statement" pos))
  7770. (let (is-ternary)
  7771. (setq is-ternary (or (string-match-p "[?:]$" prev-line)
  7772. (string-match-p "^[?:]" curr-line)))
  7773. (cond
  7774. ((not (funcall (if is-js
  7775. 'web-mode-javascript-statement-beginning
  7776. 'web-mode-block-statement-beginning)
  7777. pos reg-beg is-ternary))
  7778. )
  7779. ((null (cdr (assoc "lineup-ternary" web-mode-indentation-params)))
  7780. (setq offset (+ (current-indentation) web-mode-code-indent-offset)))
  7781. (t
  7782. (setq offset (current-column))
  7783. (when (and (member curr-char '(?\+ ?\- ?\& ?\| ?\? ?\:))
  7784. (not (looking-back "\\(^[ \t]+\\|if[ ]*[(]?\\)" (point-min)))) ; #743
  7785. (goto-char pos)
  7786. (looking-at "\\(||\\|&&\\|[&|?:+-]\\)[ \t\n]*")
  7787. (setq offset (- offset (length (match-string-no-properties 0)))))
  7788. )
  7789. ) ;cond
  7790. ) ;let
  7791. )
  7792. ((and is-js
  7793. (eq prev-char ?\()
  7794. (string-match-p "=>[ ]*([ ]*$" prev-line))
  7795. (when debug (message "I355(%S) => (" pos))
  7796. (setq offset (+ prev-indentation web-mode-code-indent-offset))
  7797. )
  7798. ((and is-js
  7799. (or (member ?\, chars)
  7800. (member prev-char '(?\( ?\[))))
  7801. (when debug (message "I360(%S) javascript-args" pos))
  7802. (cond
  7803. ((not (web-mode-javascript-args-beginning pos reg-beg))
  7804. (message "no js args beg")
  7805. )
  7806. ((or (not (cdr (assoc "lineup-args" web-mode-indentation-params)))
  7807. (looking-at-p "|?\n") ;; #1016
  7808. ;;(eq (char-after) ?\n)
  7809. )
  7810. (if (and reg-col (> reg-col (current-indentation)))
  7811. (setq offset (+ reg-col web-mode-code-indent-offset))
  7812. (setq offset (+ (current-indentation) web-mode-code-indent-offset)))
  7813. )
  7814. ((not (eq curr-char ?\,))
  7815. (setq offset (current-column)))
  7816. (t
  7817. (setq offset (current-column))
  7818. (goto-char pos)
  7819. (looking-at ",[ \t\n]*")
  7820. (setq offset (- offset (length (match-string-no-properties 0)))))
  7821. ) ;cond
  7822. )
  7823. ((and is-js
  7824. (or (eq prev-char ?\))
  7825. (string-match-p "\\(^\\|[}[:space:]]+\\)else$" prev-line)))
  7826. (when debug (message "I370(%S)" pos))
  7827. (cond
  7828. ((and (string-match-p "else$" prev-line)
  7829. (not (string-match-p "^{" curr-line)))
  7830. (setq offset (+ prev-indentation web-mode-code-indent-offset))
  7831. )
  7832. ((setq tmp (web-mode-part-is-opener prev-pos reg-beg))
  7833. ;;(message "is-opener")
  7834. (if (looking-at-p "{") ;; #1020, #1053
  7835. (setq offset tmp)
  7836. (setq offset (+ tmp web-mode-code-indent-offset)))
  7837. )
  7838. (t
  7839. (setq offset
  7840. (car (web-mode-javascript-indentation pos
  7841. reg-col
  7842. curr-indentation
  7843. language
  7844. reg-beg)))
  7845. ) ;t
  7846. ) ;cond
  7847. )
  7848. ;; TODO : a retoucher completement car le code js a ete place ci-dessus
  7849. ;;((and (member language '("javascript" "jsx" "ejs" "php"))
  7850. ((and (member language '("php"))
  7851. (or (and (eq prev-char ?\))
  7852. (string-match-p "^\\(for\\|if\\|else[ ]*if\\|while\\)[ ]*(" prev-line))
  7853. (and is-js
  7854. (web-mode-part-is-opener prev-pos reg-beg))
  7855. (string-match-p "^else$" prev-line))
  7856. (not (string-match-p "^\\([{.]\\|->\\)" curr-line)))
  7857. (when debug (message "I380(%S)" pos))
  7858. (cond
  7859. ((and (eq prev-char ?\))
  7860. (string-match-p "^\\(for\\|if\\|while\\)[ ]*(" prev-line))
  7861. (setq offset (+ prev-indentation web-mode-code-indent-offset))
  7862. )
  7863. ((member language '("javascript" "jsx"))
  7864. (setq offset
  7865. (+ (car (web-mode-javascript-indentation pos
  7866. reg-col
  7867. curr-indentation
  7868. language
  7869. reg-beg))
  7870. web-mode-code-indent-offset))
  7871. )
  7872. (t
  7873. (setq offset (+ prev-indentation web-mode-code-indent-offset))
  7874. )
  7875. )
  7876. )
  7877. ((and (member language '("php" "blade")) (string-match-p "^->" curr-line))
  7878. (when debug (message "I390(%S) block-calls" pos))
  7879. (cond
  7880. ((not (web-mode-block-calls-beginning pos reg-beg))
  7881. )
  7882. ((cdr (assoc "lineup-calls" web-mode-indentation-params))
  7883. ;;(message "point=%S" (point))
  7884. (if (looking-back "::[ ]*" (point-min))
  7885. (progn
  7886. (re-search-backward "::[ ]*")
  7887. (setq offset (current-column))
  7888. ;;(message "ici%S offset=%S" (point) offset)
  7889. )
  7890. (search-forward "->")
  7891. (setq offset (- (current-column) 2)))
  7892. )
  7893. (t
  7894. (setq offset (+ (current-indentation) web-mode-code-indent-offset)))
  7895. ))
  7896. ((member ?\, chars)
  7897. (when debug (message "I400(%S) block-args" pos))
  7898. (cond
  7899. ((not (web-mode-block-args-beginning pos reg-beg))
  7900. ;;(message "ici")
  7901. )
  7902. ((cdr (assoc "lineup-args" web-mode-indentation-params))
  7903. (setq offset (current-column))
  7904. (when (eq curr-char ?\,)
  7905. (goto-char pos)
  7906. (looking-at ",[ \t\n]*")
  7907. (setq offset (- offset (length (match-string-no-properties 0)))))
  7908. )
  7909. (t
  7910. (setq offset (+ (current-indentation) web-mode-code-indent-offset)))
  7911. ))
  7912. ((and (string= language "php") (member ?\. chars))
  7913. (when debug (message "I410(%S) block-string" pos))
  7914. (cond
  7915. ((not (web-mode-block-string-beginning pos reg-beg))
  7916. )
  7917. ((null (cdr (assoc "lineup-concats" web-mode-indentation-params)))
  7918. (setq offset (+ (current-indentation) web-mode-code-indent-offset)))
  7919. ((not (eq curr-char ?\.))
  7920. (setq offset (current-column)))
  7921. (t
  7922. (setq offset (current-column))
  7923. (goto-char pos)
  7924. (when (cdr (assoc "lineup-quotes" web-mode-indentation-params))
  7925. (looking-at "\\.[ \t\n]*")
  7926. (setq offset (- offset (length (match-string-no-properties 0)))))
  7927. )))
  7928. ((member language '("javascript" "jsx" "ejs" "underscore"))
  7929. (when debug (message "I420(%S) javascript-indentation" pos))
  7930. (setq offset (car (web-mode-javascript-indentation pos
  7931. reg-col
  7932. curr-indentation
  7933. language
  7934. reg-beg))))
  7935. (t
  7936. (when debug (message "I430(%S) bracket-indentation" pos))
  7937. (setq offset (car (web-mode-bracket-indentation pos
  7938. reg-col
  7939. curr-indentation
  7940. language
  7941. reg-beg))))
  7942. ) ;cond
  7943. (when (and offset reg-col adjust (< offset reg-col)) (setq offset reg-col))
  7944. ) ;let
  7945. ) ;save-excursion
  7946. (when offset
  7947. ;;(message "offset=%S" offset)
  7948. (let ((diff (- (current-column) (current-indentation))))
  7949. (when (not (= offset (current-indentation)))
  7950. (setq web-mode-change-beg (line-beginning-position)
  7951. web-mode-change-end (+ web-mode-change-beg offset)))
  7952. (setq offset (max 0 offset))
  7953. (indent-line-to offset)
  7954. (if (> diff 0) (move-to-column (+ (current-column) diff)))
  7955. (when (and (string= web-mode-engine "mason")
  7956. (= offset 0)
  7957. (eq char ?\%))
  7958. (save-excursion
  7959. (font-lock-fontify-region (line-beginning-position) (line-end-position)))
  7960. ) ;when
  7961. ) ;let
  7962. ) ;when
  7963. ))
  7964. (defun web-mode-bracket-level (pos limit)
  7965. (save-excursion
  7966. (let ((continue t)
  7967. (regexp "[\]\[}{)(]")
  7968. (char nil)
  7969. (map nil)
  7970. (key nil)
  7971. (value 0)
  7972. (open '(?\( ?\{ ?\[)))
  7973. (goto-char pos)
  7974. (while (and continue (re-search-backward regexp limit t))
  7975. (setq char (aref (match-string-no-properties 0) 0))
  7976. (setq key (cond ((eq char ?\)) ?\()
  7977. ((eq char ?\}) ?\{)
  7978. ((eq char ?\]) ?\[)
  7979. (t char)))
  7980. (setq value (or (plist-get map key) 0))
  7981. (setq value (if (member char open) (1+ value) (1- value)))
  7982. (setq map (plist-put map key value))
  7983. (setq continue (< value 1))
  7984. ;;(message "pos=%S char=%c key=%c value=%S" (point) char key value)
  7985. ) ;while
  7986. (if (>= value 1) (current-indentation) nil)
  7987. )))
  7988. (defun web-mode-token-html-indentation (pos)
  7989. (save-excursion
  7990. (let (beg (continue t) end level map offset regexp tag val void (css-beg 0))
  7991. (goto-char pos)
  7992. ;;(message "pos=%S" pos)
  7993. (setq beg (web-mode-part-token-beginning-position pos))
  7994. (save-excursion
  7995. (when (and (> (- pos beg) 5)
  7996. (re-search-backward "</?[a-zA-Z0-9]+" beg t)
  7997. (string= "<style" (downcase (match-string-no-properties 0))))
  7998. (setq css-beg (point))
  7999. )
  8000. )
  8001. ;;(message "beg=%S" beg)
  8002. (cond
  8003. ((eq (char-after pos) ?\`)
  8004. (setq offset (web-mode-indentation-at-pos beg)))
  8005. ((web-mode-looking-back "`[ \n\t]*" pos)
  8006. (setq offset (+ (web-mode-indentation-at-pos beg) web-mode-markup-indent-offset)))
  8007. ((looking-at "</\\([a-zA-Z0-9]+\\)")
  8008. (setq tag (match-string-no-properties 1)
  8009. regexp (concat "</?" tag)
  8010. level -1)
  8011. (while (and continue (re-search-backward regexp beg t))
  8012. (cond
  8013. ((eq (aref (match-string-no-properties 0) 1) ?\/)
  8014. (setq level (1- level)))
  8015. (t
  8016. (setq level (1+ level)))
  8017. ) ;cond
  8018. (when (= level 0)
  8019. (setq continue nil
  8020. offset (current-indentation)))
  8021. ) ;while
  8022. )
  8023. ((> css-beg 0)
  8024. ;;(message "CSS")
  8025. (cond
  8026. ((member (char-after) '(?\) ?\} ?\]))
  8027. (web-mode-go (web-mode-token-opening-paren-position pos (+ css-beg 8) ""))
  8028. (setq offset (current-indentation))
  8029. )
  8030. ((setq level (web-mode-bracket-level pos (+ css-beg 8)))
  8031. (setq offset (+ level web-mode-css-indent-offset))
  8032. )
  8033. (t
  8034. (setq offset (+ (web-mode-indentation-at-pos css-beg) web-mode-style-padding))
  8035. ) ;t
  8036. )
  8037. )
  8038. ((looking-at "[a-zA-Z-]+[ ]?=")
  8039. (re-search-backward "<[a-zA-Z]+[ ]*" beg t)
  8040. (setq offset (+ (current-column) (length (match-string-no-properties 0))))
  8041. )
  8042. ((looking-at-p "/>")
  8043. (search-backward "<" beg t)
  8044. (setq offset (current-column))
  8045. )
  8046. (t
  8047. (setq regexp "</?\\([a-zA-Z0-9]+\\)")
  8048. ;;(message "point=%S" (point))
  8049. (while (and continue (re-search-backward regexp beg t))
  8050. (setq tag (downcase (match-string-no-properties 1))
  8051. end nil
  8052. void nil)
  8053. (cond
  8054. ((eq (aref (match-string-no-properties 0) 1) ?/)
  8055. (setq end t))
  8056. ((web-mode-element-is-void tag)
  8057. (setq void t))
  8058. (t
  8059. (save-excursion
  8060. (when (and (search-forward ">" pos t) (eq (char-before (1- (point))) ?\/))
  8061. (setq void t))
  8062. ) ;save-excursion
  8063. ) ;t
  8064. ) ;cond
  8065. (unless void
  8066. (setq val (or (lax-plist-get map tag) 0))
  8067. (setq val (if end (1- val) (1+ val)))
  8068. (setq map (lax-plist-put map tag val))
  8069. ;;(message "val=%S tag=%S end=%S | %S" val tag end (plist-get map tag))
  8070. (setq continue (not (> val 0)))
  8071. ) ;unless
  8072. ;(message "pos=%S tag=%S val=%S end=%S void=%S" (point) tag val end void)
  8073. ) ;while
  8074. (cond
  8075. ((> val 0)
  8076. ;;(message "point=%S" (point))
  8077. ;;(goto-char (1+ beg))
  8078. ;;(forward-char)
  8079. ;;(re-search-forward "[[:space:]]*")
  8080. (setq offset (+ (current-indentation) web-mode-markup-indent-offset)))
  8081. (t
  8082. (setq offset (current-indentation)))
  8083. )
  8084. ) ;t
  8085. ) ;cond
  8086. offset)))
  8087. (defun web-mode-token-css-indentation (pos)
  8088. (save-excursion
  8089. (let (offset)
  8090. (goto-char pos)
  8091. (web-mode-part-token-beginning)
  8092. (setq offset (+ web-mode-css-indent-offset (current-indentation)))
  8093. ) ;let
  8094. ))
  8095. (defun web-mode-relayql-indentation (pos &optional prefix)
  8096. (unless prefix (setq prefix "relayql"))
  8097. (let (beg offset level char)
  8098. (setq char (char-after))
  8099. (setq beg (web-mode-part-token-beginning-position pos))
  8100. (goto-char beg)
  8101. (cond
  8102. ((member char '(?\`))
  8103. (setq offset (current-indentation))
  8104. )
  8105. ((member char '(?\) ?\} ?\]))
  8106. (web-mode-go (web-mode-token-opening-paren-position pos beg prefix))
  8107. (setq offset (current-indentation))
  8108. )
  8109. ((setq level (web-mode-bracket-level pos beg))
  8110. (setq offset (+ level web-mode-code-indent-offset))
  8111. )
  8112. (t
  8113. (setq offset (+ (current-indentation) web-mode-code-indent-offset))
  8114. )
  8115. )
  8116. offset))
  8117. (defun web-mode-markup-indentation (pos)
  8118. (let (offset beg ret jsx-depth)
  8119. (when (and (setq jsx-depth (get-text-property pos 'jsx-depth))
  8120. (get-text-property pos 'jsx-beg)
  8121. (not (get-text-property pos 'tag-beg)))
  8122. (setq jsx-depth (1- jsx-depth)))
  8123. ;;(when (setq beg (web-mode-markup-indentation-origin pos jsx-depth))
  8124. (cond
  8125. ((not (setq beg (web-mode-markup-indentation-origin pos jsx-depth)))
  8126. (setq offset 0))
  8127. ((null (setq ret (web-mode-element-is-opened beg pos)))
  8128. (setq offset (web-mode-indentation-at-pos beg)))
  8129. ((eq ret t)
  8130. (setq offset (+ (web-mode-indentation-at-pos beg)
  8131. web-mode-markup-indent-offset)))
  8132. (t
  8133. (setq offset ret))
  8134. ) ;cond
  8135. ;;(message "markup-indentation-origin=%S (jsx-depth=%S)" beg jsx-depth)
  8136. ;;) ;when beg
  8137. offset))
  8138. (defun web-mode-css-indentation (pos initial-column language-offset language &optional limit)
  8139. (let ((open-ctx (web-mode-bracket-up pos language limit)) offset)
  8140. (cond
  8141. ((or (null open-ctx) (null (plist-get open-ctx :pos)))
  8142. (setq offset initial-column))
  8143. (t
  8144. (setq offset (+ (plist-get open-ctx :indentation) language-offset)))
  8145. ) ;cond
  8146. (cons (if (< offset initial-column) initial-column offset) open-ctx)
  8147. ))
  8148. (defun web-mode-sql-indentation (pos initial-column language-offset language &optional limit)
  8149. (let ((open-ctx (web-mode-bracket-up pos language limit)) offset)
  8150. ;;(message "%S %S %S %S %S" pos (point) initial-column language-offset open-ctx)
  8151. (cond
  8152. ((and (not (null open-ctx)) (not (null (plist-get open-ctx :pos))))
  8153. (setq offset (+ (plist-get open-ctx :column) 1)))
  8154. ((looking-at-p "\\(SELECT\\|INSERT\\|DELETE\\|UPDATE\\|FROM\\|LEFT\\|JOIN\\|WHERE\\|GROUP BY\\|LIMIT\\|HAVING\\|ON\\|select\\|insert\\|delete\\|update\\|from\\|left\\|join\\|where\\|group by\\|limit\\|having\\|on\\|AND\\|and\\|OR\\|or\\)")
  8155. (setq offset initial-column))
  8156. (t
  8157. (setq offset (+ initial-column language-offset)))
  8158. ) ;cond
  8159. (cons (if (< offset initial-column) initial-column offset) open-ctx)
  8160. ))
  8161. (defun web-mode-markdown-indentation (pos initial-column language-offset language &optional limit)
  8162. (let (offset)
  8163. (save-excursion
  8164. (goto-char pos)
  8165. (setq offset (current-column))
  8166. ) ;save-excursion
  8167. ;;(message "%S %S %S %S" pos (point) initial-column language-offset)
  8168. (cons (if (<= offset initial-column) initial-column offset) nil)))
  8169. (defun web-mode-stylus-indentation (pos initial-column language-offset language &optional limit)
  8170. (let (offset)
  8171. (save-excursion
  8172. (goto-char pos)
  8173. (setq offset (current-column))
  8174. (if (looking-at-p "[[:alnum:]-]+:")
  8175. (setq offset (+ initial-column language-offset))
  8176. (setq offset initial-column))
  8177. ) ;save-excursion
  8178. ;;(message "%S %S %S %S" pos (point) initial-column language-offset)
  8179. (cons (if (<= offset initial-column) initial-column offset) nil)))
  8180. (defun web-mode-sass-indentation (pos initial-column language-offset language &optional limit)
  8181. (let (offset)
  8182. (save-excursion
  8183. (goto-char pos)
  8184. (setq offset (current-column))
  8185. (if (looking-at-p "[[:alnum:]-]+:")
  8186. (setq offset (+ initial-column language-offset))
  8187. (setq offset initial-column))
  8188. ) ;save-excursion
  8189. ;;(message "%S %S %S %S" pos (point) initial-column language-offset)
  8190. (cons (if (<= offset initial-column) initial-column offset) nil)))
  8191. (defun web-mode-pug-indentation (pos initial-column language-offset language &optional limit)
  8192. nil
  8193. )
  8194. (defun web-mode-javascript-indentation (pos initial-column language-offset language &optional limit)
  8195. (let (open-ctx indentation offset sub)
  8196. (setq open-ctx (web-mode-bracket-up pos language limit))
  8197. ;;(message "pos(%S) initial-column(%S) language-offset(%S) language(%S) limit(%S)" pos initial-column language-offset language limit)
  8198. ;;(message "javascript-indentation: %S\nchar=%c" open-ctx (plist-get open-ctx :char))
  8199. (setq indentation (plist-get open-ctx :indentation))
  8200. (when (and initial-column (> initial-column indentation))
  8201. (setq indentation initial-column)
  8202. )
  8203. (setq case-fold-search nil) ; #1006
  8204. (cond
  8205. ((or (null open-ctx) (null (plist-get open-ctx :pos)))
  8206. (setq offset initial-column))
  8207. ((and (member language '("javascript" "jsx" "ejs"))
  8208. (eq (plist-get open-ctx :char) ?\{)
  8209. (web-mode-looking-back "switch[ ]*" (plist-get open-ctx :pos)))
  8210. (setq sub (if (cdr (assoc "case-extra-offset" web-mode-indentation-params)) 0 1))
  8211. (cond
  8212. ((looking-at-p "case\\|default")
  8213. (setq offset (+ indentation (* language-offset (- 1 sub)))))
  8214. (t
  8215. (setq offset (+ indentation (* language-offset (- 2 sub)))))
  8216. ) ;cond switch
  8217. )
  8218. (t
  8219. (setq offset (+ indentation language-offset)))
  8220. ) ;cond
  8221. (setq case-fold-search t)
  8222. (cons (if (< offset initial-column) initial-column offset) open-ctx)
  8223. ))
  8224. (defun web-mode-bracket-indentation (pos initial-column language-offset language &optional limit)
  8225. (save-excursion
  8226. (let* ((ctx (web-mode-bracket-up pos language limit))
  8227. (char (plist-get ctx :char))
  8228. (pos (plist-get ctx :pos))
  8229. (indentation (plist-get ctx :indentation)))
  8230. ;;(message "pos(%S) initial-column(%S) language-offset(%S) language(%S) limit(%S)" pos initial-column language-offset language limit)
  8231. ;;(message "bracket-up: %S, %c" ctx char)
  8232. (cond
  8233. ((null pos)
  8234. (setq indentation initial-column))
  8235. ((and (member language '("php"))
  8236. (eq char ?\{)
  8237. (web-mode-looking-back "switch[ ]*" pos)
  8238. (not (looking-at-p "case\\|default")))
  8239. (setq indentation (+ indentation (* language-offset 2)))
  8240. )
  8241. ((and (member language '("php"))
  8242. (eq char ?\{)
  8243. (goto-char pos)
  8244. (web-mode-looking-back "[)][ ]*" pos)
  8245. (search-backward ")")
  8246. (web-mode-block-opening-paren limit))
  8247. (setq indentation (+ (current-indentation) language-offset))
  8248. )
  8249. (t
  8250. (setq indentation (+ indentation language-offset))
  8251. )
  8252. ) ;cond
  8253. (cons (if (< indentation initial-column) initial-column indentation) ctx)
  8254. )))
  8255. (defun web-mode-ruby-indentation (pos line initial-column language-offset limit)
  8256. (unless limit (setq limit nil))
  8257. (let (h offset prev-line prev-indentation open-ctx)
  8258. (setq open-ctx (web-mode-bracket-up pos "ruby" limit))
  8259. ;;(message "%S" open-ctx)
  8260. (if (plist-get open-ctx :pos)
  8261. (cond
  8262. ((web-mode-looking-at-p ".[ \t\n]+" (plist-get open-ctx :pos))
  8263. (setq offset (+ (plist-get open-ctx :indentation) language-offset)))
  8264. (t
  8265. (setq offset (1+ (plist-get open-ctx :column))))
  8266. )
  8267. (setq h (web-mode-previous-line pos limit))
  8268. (setq offset initial-column)
  8269. (when h
  8270. (setq prev-line (car h))
  8271. (setq prev-indentation (cdr h))
  8272. (cond
  8273. ((string-match-p ",$" prev-line)
  8274. (save-excursion
  8275. (goto-char limit)
  8276. (looking-at "<%=? [a-z]+ ")
  8277. (setq offset (+ initial-column (length (match-string-no-properties 0))))
  8278. ) ;save-excursion
  8279. )
  8280. ((string-match-p "^[ ]*\\(end\\|else\\|elsif\\|when\\)" line)
  8281. (setq offset (- prev-indentation language-offset))
  8282. )
  8283. ((string-match-p "[ ]+\\(do\\)" prev-line)
  8284. (setq offset (+ prev-indentation language-offset))
  8285. )
  8286. ((string-match-p "^[ ]*\\(when\\|if\\|else\\|elsif\\|unless\\|for\\|while\\|def\\|class\\)" prev-line)
  8287. (setq offset (+ prev-indentation language-offset))
  8288. )
  8289. (t
  8290. (setq offset prev-indentation)
  8291. )
  8292. )
  8293. ) ;when
  8294. ) ;if
  8295. offset))
  8296. (defun web-mode-python-indentation (pos line initial-column language-offset limit)
  8297. (unless limit (setq limit nil))
  8298. (let (h offset prev-line prev-indentation ctx)
  8299. (setq ctx (web-mode-bracket-up pos "python" limit))
  8300. ;;(message "point-ctx=%S" ctx)
  8301. (if (plist-get ctx :pos)
  8302. (cond
  8303. ((web-mode-looking-at-p ".[ \t\n]+" (plist-get ctx :pos))
  8304. (setq offset (+ (plist-get ctx :indentation) language-offset)))
  8305. (t
  8306. (setq offset (1+ (plist-get ctx :column))))
  8307. )
  8308. ;; else
  8309. (setq h (web-mode-previous-line pos limit))
  8310. (setq offset initial-column)
  8311. (when h
  8312. (setq prev-line (car h))
  8313. (setq prev-indentation (cdr h))
  8314. (cond
  8315. ((string-match-p "^\\(pass\\|else\\|elif\\|when\\|except\\)" line)
  8316. (setq offset (- prev-indentation language-offset))
  8317. )
  8318. ((string-match-p "\\(if\\|else\\|elif\\|for\\|while\\|try\\|except\\)" prev-line)
  8319. (setq offset (+ prev-indentation language-offset))
  8320. )
  8321. (t
  8322. (setq offset prev-indentation)
  8323. )
  8324. ) ;cond
  8325. ) ;when
  8326. ) ;if
  8327. ;;offset
  8328. (if (< offset initial-column) initial-column offset)
  8329. ))
  8330. (defun web-mode-lisp-indentation (pos point-ctx)
  8331. (let (offset open-ctx)
  8332. (setq open-ctx (web-mode-bracket-up pos "lsp" (plist-get point-ctx :reg-beg)))
  8333. ;;(message "point-ctx=%S" point-ctx)
  8334. ;;(message "open-ctx=%S" open-ctx)
  8335. (cond
  8336. ((null (plist-get open-ctx :pos))
  8337. (setq offset (plist-get point-ctx :reg-col)))
  8338. ((member (plist-get point-ctx :curr-char) '(?\( ?\)))
  8339. (if (web-mode-looking-at-p "((" (plist-get open-ctx :pos))
  8340. (setq offset (+ (plist-get open-ctx :column) 1))
  8341. (setq offset (+ (plist-get open-ctx :column) web-mode-code-indent-offset)))
  8342. )
  8343. (t
  8344. (goto-char (plist-get open-ctx :pos))
  8345. (forward-char)
  8346. (web-mode-rsf "[[:alnum:]-:]+ ")
  8347. (setq offset (current-column))
  8348. )
  8349. ) ;cond
  8350. offset))
  8351. (defun web-mode-asp-indentation (pos line initial-column language-offset limit)
  8352. (unless limit (setq limit nil))
  8353. (let (h out prev-line prev-indentation)
  8354. (setq h (web-mode-previous-line pos limit))
  8355. (setq out initial-column)
  8356. (when h
  8357. (setq prev-line (car h))
  8358. (setq prev-indentation (cdr h))
  8359. (cond
  8360. ;; ----------------------------------------------------------------------
  8361. ;; unindent
  8362. ((string-match-p "\\_<\\(\\(end \\(if\\|function\\|class\\|sub\\|with\\)\\)\\|else\\|elseif\\|next\\|loop\\)\\_>" line)
  8363. (setq out (- prev-indentation language-offset)))
  8364. ;; ----------------------------------------------------------------------
  8365. ;; select case statement
  8366. ((string-match-p "\\_<\\(select case\\)\\_>" line)
  8367. (setq out (- prev-indentation 0)))
  8368. ((string-match-p "\\_<\\(end select\\)" line)
  8369. (setq out (- prev-indentation (* 2 language-offset))))
  8370. ((and (string-match-p "\\_<\\(case\\)\\_>" line) (not (string-match-p "\\_<\\(select case\\)\\_>" prev-line)))
  8371. (setq out (- prev-indentation language-offset)))
  8372. ;; ----------------------------------------------------------------------
  8373. ;; do nothing
  8374. ((string-match-p "\\_<\\(\\(end \\(if\\|function\\|class\\|sub\\|select\\|with\\)\\)\\|loop\\( until\\| while\\)?\\)\\_>" prev-line)
  8375. (setq out (+ prev-indentation 0)))
  8376. ;; indent
  8377. ((string-match-p "\\_<\\(\\(select \\)?case\\|else\\|elseif\\|unless\\|for\\|class\\|with\\|do\\( until\\| while\\)?\\|while\\|\\(public \\|private \\)?\\(function\\|sub\\|class\\)\\)\\_>" prev-line)
  8378. (setq out (+ prev-indentation language-offset)))
  8379. ;; single line if statement
  8380. ((string-match-p "\\_<if\\_>.*\\_<then\\_>[ \t]*[[:alpha:]]+" prev-line)
  8381. (setq out (+ prev-indentation 0)))
  8382. ;; normal if statement
  8383. ((string-match-p "\\_<\\if\\_>" prev-line)
  8384. (setq out (+ prev-indentation language-offset)))
  8385. (t
  8386. (setq out prev-indentation))
  8387. )
  8388. ) ;when
  8389. out))
  8390. (defun web-mode-block-previous-live-line ()
  8391. (save-excursion
  8392. (let ((continue t) (line "") (pos (point)))
  8393. (beginning-of-line)
  8394. (while (and continue (not (bobp)) (forward-line -1))
  8395. (when (not (web-mode-block-is-token-line))
  8396. (setq line (web-mode-trim (buffer-substring (point) (line-end-position)))))
  8397. (when (not (string= line ""))
  8398. (setq continue nil))
  8399. ) ;while
  8400. (if (string= line "")
  8401. (progn (goto-char pos) nil)
  8402. (cons line (current-indentation)))
  8403. )))
  8404. (defun web-mode-part-is-opener (pos reg-beg)
  8405. (save-excursion
  8406. (save-match-data
  8407. (if (and pos
  8408. (web-mode-go (web-mode-part-opening-paren-position pos))
  8409. (>= (point) reg-beg)
  8410. (looking-back "\\(^\\|[ \t]\\)\\(if\\|for\\|while\\)[ ]*" (point-min)))
  8411. (current-indentation)
  8412. nil)
  8413. )))
  8414. (defun web-mode-part-previous-live-line (reg-beg)
  8415. (unless reg-beg (setq reg-beg (point-min)))
  8416. ;;(message "reg-beg=%S" reg-beg)
  8417. (save-excursion
  8418. (let ((continue (> (point) reg-beg))
  8419. (line "")
  8420. bol-pos
  8421. eol-pos
  8422. pos)
  8423. (beginning-of-line)
  8424. (while (and continue (> (point) reg-beg) (forward-line -1))
  8425. (setq bol-pos (point)
  8426. eol-pos (line-end-position))
  8427. (when (> reg-beg bol-pos)
  8428. (setq bol-pos reg-beg))
  8429. (when (not (web-mode-part-is-token-line bol-pos))
  8430. (setq line (web-mode-trim (buffer-substring bol-pos eol-pos)))
  8431. (when (not (string= line "")) (setq continue nil))
  8432. ) ;when
  8433. ) ;while
  8434. (cond
  8435. ((string= line "")
  8436. nil)
  8437. (t
  8438. (setq continue t)
  8439. (setq pos (1- eol-pos))
  8440. (while (and (>= pos bol-pos) continue)
  8441. (cond
  8442. ((eq (char-after pos) ?\s)
  8443. (setq pos (1- pos)))
  8444. ((get-text-property pos 'part-token)
  8445. (setq pos (1- pos)))
  8446. (t
  8447. (setq continue nil))
  8448. ) ;cond
  8449. ) ;while
  8450. ;;(message "%S %S : %S" bol-pos eol-pos pos)
  8451. (setq line (web-mode-clean-part-line line))
  8452. (list line (current-indentation) pos))
  8453. ) ;cond
  8454. )))
  8455. (defun web-mode-in-code-block (open close &optional prop)
  8456. (save-excursion
  8457. (let ((pos (point)) pos-open pos-close start end ret)
  8458. (when prop
  8459. (setq start pos
  8460. end pos)
  8461. (when (eq (get-text-property pos prop) (get-text-property (1- pos) prop))
  8462. (setq start (or (previous-single-property-change pos prop) (point-min))))
  8463. (when (eq (get-text-property pos prop) (get-text-property (1+ pos) prop))
  8464. (setq end (next-single-property-change pos prop)))
  8465. ;; (message "start(%S) end(%S)" start end)
  8466. )
  8467. (setq ret (and (web-mode-sb open start t)
  8468. (setq pos-open (point))
  8469. (web-mode-sf close end t)
  8470. (setq pos-close (point))
  8471. (>= pos-close pos)))
  8472. (if ret
  8473. (cons pos-open pos-close)
  8474. ret)
  8475. )))
  8476. (defun web-mode-clean-part-line (input)
  8477. (let ((out "")
  8478. (beg 0)
  8479. (keep t)
  8480. (n (length input)))
  8481. (dotimes (i n)
  8482. (if (or (get-text-property i 'block-side input)
  8483. (eq (get-text-property i 'part-token input) 'comment)
  8484. (eq (get-text-property i 'tag-type input) 'comment))
  8485. (when keep
  8486. (setq out (concat out (substring input beg i))
  8487. beg 0
  8488. keep nil))
  8489. (when (null keep)
  8490. (setq beg i
  8491. keep t))
  8492. ) ;if
  8493. ) ;dotimes
  8494. (if (> beg 0) (setq out (concat out (substring input beg n))))
  8495. (setq out (if (= (length out) 0) input out))
  8496. (web-mode-trim out)
  8497. ))
  8498. (defun web-mode-clean-block-line (input)
  8499. (let ((out "")
  8500. (beg 0)
  8501. (keep t)
  8502. (n (length input)))
  8503. (dotimes (i n)
  8504. (if (or (not (get-text-property i 'block-side input))
  8505. (member (get-text-property i 'block-token input)
  8506. '(comment delimiter-beg delimiter-end)))
  8507. (when keep
  8508. (setq out (concat out (substring input beg i))
  8509. beg 0
  8510. keep nil))
  8511. (when (null keep)
  8512. (setq beg i
  8513. keep t))
  8514. ) ;if
  8515. ) ;dotimes
  8516. (if (> beg 0) (setq out (concat out (substring input beg n))))
  8517. (setq out (if (= (length out) 0) input out))
  8518. (web-mode-trim out)
  8519. ;; (message "%S [%s] > [%s]" beg input out)
  8520. ))
  8521. (defun web-mode-language-at-pos (&optional pos)
  8522. (unless pos (setq pos (point)))
  8523. (cond
  8524. ((get-text-property pos 'block-side)
  8525. web-mode-engine)
  8526. ((get-text-property pos 'part-side)
  8527. (symbol-name (get-text-property pos 'part-side)))
  8528. (t
  8529. web-mode-content-type)
  8530. ) ;cond
  8531. )
  8532. (defun web-mode-coord-position (line column)
  8533. (save-excursion
  8534. (when (stringp line) (setq line (string-to-number line)))
  8535. (when (stringp column) (setq column (string-to-number column)))
  8536. (goto-char (point-min))
  8537. (forward-line (1- line))
  8538. (move-to-column (1- column))
  8539. (point)))
  8540. (defun web-mode-is-single-line-block (pos)
  8541. (= (web-mode-line-number (web-mode-block-beginning-position pos))
  8542. (web-mode-line-number (web-mode-block-end-position pos))))
  8543. (defun web-mode-line-number (&optional pos)
  8544. (setq pos (or pos (point)))
  8545. (+ (count-lines 1 pos) (if (= (web-mode-column-at-pos pos) 0) 1 0)))
  8546. (defun web-mode-block-is-control (pos)
  8547. (save-excursion
  8548. (let (control state controls pair)
  8549. (goto-char pos)
  8550. (setq controls (web-mode-block-controls-get pos))
  8551. (setq pair (car controls))
  8552. (cond
  8553. ((eq (car pair) 'inside)
  8554. )
  8555. ((eq (car pair) 'open)
  8556. (setq state t
  8557. control (cdr pair)))
  8558. ((eq (car pair) 'close)
  8559. (setq state nil
  8560. control (cdr pair)))
  8561. ) ;cond
  8562. ;; (message "engine=%S control=%S state=%S" web-mode-engine control state)
  8563. (if control (cons control state) nil)
  8564. )))
  8565. (defun web-mode-block-is-opening-control (pos)
  8566. (save-excursion
  8567. (let (controls pair)
  8568. (goto-char pos)
  8569. (if (and (setq controls (web-mode-block-controls-get pos))
  8570. (= (length controls) 1)
  8571. (setq pair (car controls))
  8572. (eq (car pair) 'open))
  8573. (cdr pair)
  8574. nil)
  8575. )))
  8576. (defun web-mode-markup-indentation-origin (pos jsx-depth)
  8577. (save-excursion
  8578. (let* ((found (bobp))
  8579. (jsx-beg nil)
  8580. (types '(start end void))
  8581. (type nil))
  8582. (when jsx-depth
  8583. (setq jsx-beg (web-mode-jsx-depth-beginning-position pos jsx-depth)))
  8584. (while (not found)
  8585. (forward-line -1)
  8586. (if (bobp)
  8587. (setq pos (point)
  8588. found t)
  8589. (back-to-indentation)
  8590. (when (and jsx-beg (< (point) jsx-beg))
  8591. (goto-char jsx-beg))
  8592. (setq pos (point))
  8593. (setq type (get-text-property pos 'tag-type))
  8594. (setq found (or (and (null jsx-depth)
  8595. (null (get-text-property pos 'part-side))
  8596. (get-text-property pos 'tag-beg)
  8597. (member type types)
  8598. (null (get-text-property (1- pos) 'invisible)))
  8599. (and (null jsx-depth)
  8600. (null (get-text-property pos 'part-side))
  8601. (eq (get-text-property pos 'tag-type) 'comment)
  8602. (web-mode-looking-at-p "<!--#\\(endif\\|if\\)" pos)
  8603. (null (get-text-property (1- pos) 'invisible)))
  8604. (and jsx-depth
  8605. (get-text-property pos 'tag-beg)
  8606. (member type types)
  8607. (null (get-text-property (1- pos) 'invisible))
  8608. (eq (get-text-property pos 'jsx-depth) jsx-depth))
  8609. (and (get-text-property pos 'block-beg)
  8610. (not type)
  8611. (web-mode-block-is-control pos)
  8612. (not (looking-at-p "{% commen\\|@break")))))
  8613. ) ;if
  8614. ) ;while
  8615. ;;(message "indent-origin=%S" pos)
  8616. pos)))
  8617. ;;TODO : prendre en compte part-token
  8618. ;; state=t <=> start tag
  8619. (defun web-mode-element-is-opened (pos limit)
  8620. (let (tag
  8621. last-end-tag
  8622. tag-pos block-pos
  8623. state
  8624. n
  8625. ret
  8626. (continue t)
  8627. controls
  8628. control
  8629. (buffer (current-buffer))
  8630. (h (make-hash-table :test 'equal))
  8631. (h2 (make-hash-table :test 'equal)))
  8632. ;; (message "pos-ori=%S limit=%S" pos limit)
  8633. (while continue
  8634. (setq control nil
  8635. controls nil
  8636. last-end-tag nil
  8637. tag nil)
  8638. (cond
  8639. ((and (eq (get-text-property pos 'tag-type) 'comment)
  8640. (web-mode-looking-at "<!--#\\(endif\\|if\\)" pos))
  8641. ;;(message "pos=%S" pos)
  8642. (setq tag "#if")
  8643. (setq n (gethash tag h 0))
  8644. (if (string= (match-string-no-properties 1) "if")
  8645. (puthash tag (1+ n) h)
  8646. (puthash tag (1- n) h))
  8647. ;;(setq tag-pos pos)
  8648. )
  8649. ((get-text-property pos 'tag-beg)
  8650. (when (member (get-text-property pos 'tag-type) '(start end))
  8651. (setq tag (get-text-property pos 'tag-name)
  8652. state (eq (get-text-property pos 'tag-type) 'start))
  8653. (if (null state) (setq last-end-tag (cons tag pos)))
  8654. (setq n (gethash tag h 0))
  8655. (cond
  8656. ((null state)
  8657. (when (> n 0) (puthash tag (1- n) h))
  8658. (puthash tag (1- n) h2))
  8659. ((member tag web-mode-offsetless-elements)
  8660. )
  8661. (t
  8662. (puthash tag (1+ n) h)
  8663. (puthash tag (1+ n) h2))
  8664. ) ;cond
  8665. ) ;when
  8666. (when (setq pos (web-mode-tag-end-position pos))
  8667. (setq tag-pos nil)
  8668. (when (and block-pos (> pos block-pos))
  8669. (setq block-pos nil))
  8670. ) ;when
  8671. )
  8672. ((and web-mode-enable-control-block-indentation
  8673. (get-text-property pos 'block-beg))
  8674. (when (setq controls (web-mode-block-controls-get pos))
  8675. (dolist (control controls)
  8676. (setq tag (cdr control))
  8677. (setq n (gethash tag h 0))
  8678. (cond
  8679. ((eq (car control) 'inside)
  8680. )
  8681. ((eq (car control) 'open)
  8682. (puthash tag (1+ n) h))
  8683. ((> n 0)
  8684. (puthash tag (1- n) h))
  8685. ) ;cond
  8686. ) ;dolist
  8687. )
  8688. (when (setq pos (web-mode-block-end-position pos))
  8689. (setq block-pos nil)
  8690. (when (and tag-pos (> pos tag-pos))
  8691. (setq tag-pos nil))
  8692. )
  8693. )
  8694. ) ;cond
  8695. ;; (message "tag=%S end-pos=%S" tag pos)
  8696. (when (and pos (< pos limit))
  8697. (when (or (null tag-pos) (>= pos tag-pos))
  8698. (setq tag-pos (web-mode-tag-next-position pos limit))
  8699. ;; (message "from=%S tag-next-pos=%S" pos tag-pos)
  8700. )
  8701. (when (or (null block-pos) (>= pos block-pos))
  8702. (setq block-pos (web-mode-block-next-position pos limit))
  8703. ;; (message "from=%S block-next-pos=%S" pos block-pos)
  8704. )
  8705. )
  8706. (cond
  8707. ((null pos)
  8708. )
  8709. ((and (null tag-pos)
  8710. (null block-pos))
  8711. (setq pos nil))
  8712. ((and tag-pos block-pos)
  8713. (if (< tag-pos block-pos)
  8714. (progn
  8715. (setq pos tag-pos)
  8716. (setq tag-pos nil))
  8717. (setq pos block-pos)
  8718. (setq block-pos nil))
  8719. )
  8720. ((null tag-pos)
  8721. (setq pos block-pos)
  8722. (setq block-pos nil))
  8723. (t
  8724. (setq pos tag-pos)
  8725. (setq tag-pos nil))
  8726. )
  8727. (when (or (null pos)
  8728. (>= pos limit))
  8729. (setq continue nil))
  8730. ) ;while
  8731. ;;(message "hashtable=%S" h)
  8732. (maphash (lambda (k v) (if (> v 0) (setq ret t))) h)
  8733. (when (and (null ret)
  8734. last-end-tag
  8735. (> (hash-table-count h2) 1)
  8736. (< (gethash (car last-end-tag) h2) 0))
  8737. ;; (message "last-end-tag=%S" last-end-tag)
  8738. (save-excursion
  8739. (goto-char (cdr last-end-tag))
  8740. (web-mode-tag-match)
  8741. (when (not (= (point) (cdr last-end-tag)))
  8742. (setq n (point))
  8743. (back-to-indentation)
  8744. (if (= n (point)) (setq ret (current-indentation))))
  8745. ))
  8746. ret))
  8747. (defun web-mode-previous-line (pos limit)
  8748. (save-excursion
  8749. (let (beg end line (continue t))
  8750. (goto-char pos)
  8751. (while continue
  8752. (forward-line -1)
  8753. (setq end (line-end-position))
  8754. (setq line (buffer-substring-no-properties (point) end))
  8755. (when (or (not (string-match-p "^[ \t]*$" line))
  8756. (bobp)
  8757. (<= (point) limit))
  8758. (setq continue nil))
  8759. )
  8760. (if (<= (point) limit)
  8761. ;;todo : affiner (le + 3 n est pas générique cf. <?php <% <%- etc.)
  8762. (setq beg (if (< (+ limit 3) end) (+ limit 3) end))
  8763. (setq beg (line-beginning-position))
  8764. ) ;if
  8765. (setq line (buffer-substring-no-properties beg end))
  8766. (cons line (current-indentation))
  8767. )))
  8768. (defun web-mode-bracket-up (pos language &optional limit)
  8769. (unless limit (setq limit nil))
  8770. ;;(message "pos(%S) language(%S) limit(%S)" pos language limit)
  8771. (save-excursion
  8772. (goto-char pos)
  8773. (let ((continue t)
  8774. (regexp "[\]\[}{)(]")
  8775. (char nil)
  8776. (column nil)
  8777. (indentation nil)
  8778. (map nil)
  8779. (key nil)
  8780. (value 0)
  8781. (open '(?\( ?\{ ?\[))
  8782. (searcher nil)
  8783. (opener nil))
  8784. (cond
  8785. ((get-text-property pos 'block-side)
  8786. (setq searcher 'web-mode-block-rsb
  8787. opener 'web-mode-block-opening-paren-position))
  8788. (t
  8789. (setq searcher 'web-mode-part-rsb
  8790. opener 'web-mode-part-opening-paren-position))
  8791. )
  8792. (while (and continue (funcall searcher regexp limit))
  8793. (setq char (aref (match-string-no-properties 0) 0))
  8794. (setq key (cond ((eq char ?\)) ?\()
  8795. ((eq char ?\}) ?\{)
  8796. ((eq char ?\]) ?\[)
  8797. (t char)))
  8798. (setq value (or (plist-get map key) 0))
  8799. (setq value (if (member char open) (1+ value) (1- value)))
  8800. (setq map (plist-put map key value))
  8801. (setq continue (< value 1))
  8802. ;;(message "pos=%S char=%c key=%c value=%S map=%S" (point) char key value map)
  8803. ) ;while
  8804. (setq column (current-column)
  8805. indentation (current-indentation))
  8806. (when (and (> value 0)
  8807. (eq char ?\{)
  8808. (looking-back ")[ ]*" (point-min)))
  8809. (search-backward ")")
  8810. (when (setq pos (funcall opener (point) limit))
  8811. (goto-char pos)
  8812. ;;(message "pos=%S" pos)
  8813. (setq indentation (current-indentation)))
  8814. ) ;when
  8815. (list :pos (if (> value 0) (point) nil)
  8816. :char char
  8817. :column column
  8818. :indentation indentation)
  8819. ) ;let
  8820. ))
  8821. (defun web-mode-count-char-in-string (char string)
  8822. (let ((n 0))
  8823. (dotimes (i (length string))
  8824. (if (eq (elt string i) char)
  8825. (setq n (1+ n))))
  8826. n))
  8827. (defun web-mode-mark-and-expand ()
  8828. "Mark and expand."
  8829. (interactive)
  8830. (web-mode-mark (point)))
  8831. (defun web-mode-mark (pos)
  8832. (let ((beg pos) (end pos) prop reg-beg boundaries)
  8833. (if mark-active
  8834. (setq reg-beg (region-beginning))
  8835. (setq web-mode-expand-initial-pos (point)
  8836. web-mode-expand-initial-scroll (window-start))
  8837. )
  8838. ;; (message "regs=%S %S %S %S" (region-beginning) (region-end) (point-min) (point-max))
  8839. ;; (message "before=%S" web-mode-expand-previous-state)
  8840. (cond
  8841. ((and mark-active
  8842. (= (region-beginning) (point-min))
  8843. (or (= (region-end) (point-max))
  8844. (= (1+ (region-end)) (point-max))))
  8845. (deactivate-mark)
  8846. (goto-char (or web-mode-expand-initial-pos (point-min)))
  8847. (setq web-mode-expand-previous-state nil)
  8848. (when web-mode-expand-initial-scroll
  8849. (set-window-start (selected-window) web-mode-expand-initial-scroll))
  8850. )
  8851. ((string= web-mode-expand-previous-state "elt-content")
  8852. (web-mode-element-parent)
  8853. ;;(message "pos=%S" (point))
  8854. (web-mode-element-select)
  8855. (setq web-mode-expand-previous-state "html-parent"))
  8856. ((and (member (get-text-property pos 'block-token) '(comment string))
  8857. (not (member web-mode-expand-previous-state '("block-token" "block-body" "block-side"))))
  8858. (when (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token))
  8859. (setq beg (or (previous-single-property-change pos 'block-token) (point-min))))
  8860. (when (eq (get-text-property pos 'block-token) (get-text-property (1+ pos) 'block-token))
  8861. (setq end (next-single-property-change pos 'block-token)))
  8862. (set-mark beg)
  8863. (goto-char end)
  8864. (exchange-point-and-mark)
  8865. (setq web-mode-expand-previous-state "block-token"))
  8866. ((and (get-text-property pos 'block-side)
  8867. (not (member web-mode-expand-previous-state '("block-body" "block-side")))
  8868. (not (member web-mode-engine '(django go)))
  8869. (setq boundaries (web-mode-in-code-block "{" "}" 'block-side)))
  8870. (set-mark (car boundaries))
  8871. (goto-char (cdr boundaries))
  8872. (exchange-point-and-mark)
  8873. (setq web-mode-expand-previous-state "block-body"))
  8874. ((and (get-text-property pos 'block-side)
  8875. (not (member web-mode-expand-previous-state '("block-side"))))
  8876. (set-mark (web-mode-block-beginning-position pos))
  8877. (goto-char (1+ (web-mode-block-end-position pos)))
  8878. (exchange-point-and-mark)
  8879. (setq web-mode-expand-previous-state "block-side"))
  8880. ((and (get-text-property pos 'part-token)
  8881. (not (string= web-mode-expand-previous-state "part-token")))
  8882. (when (eq (get-text-property pos 'part-token) (get-text-property (1- pos) 'part-token))
  8883. (setq beg (previous-single-property-change pos 'part-token)))
  8884. (when (eq (get-text-property pos 'part-token) (get-text-property (1+ pos) 'part-token))
  8885. (setq end (next-single-property-change pos 'part-token)))
  8886. (set-mark beg)
  8887. (goto-char end)
  8888. (exchange-point-and-mark)
  8889. (setq web-mode-expand-previous-state "part-token"))
  8890. ((and (get-text-property pos 'part-side)
  8891. (not (string= web-mode-expand-previous-state "client-part"))
  8892. (setq boundaries (web-mode-in-code-block "{" "}" 'part-side)))
  8893. (set-mark (car boundaries))
  8894. (goto-char (cdr boundaries))
  8895. (exchange-point-and-mark)
  8896. (setq web-mode-expand-previous-state "client-part"))
  8897. ((and (get-text-property pos 'part-side)
  8898. (not (string= web-mode-expand-previous-state "part-side")))
  8899. (when (eq (get-text-property pos 'part-side) (get-text-property (1- pos) 'part-side))
  8900. (setq beg (previous-single-property-change pos 'part-side)))
  8901. (when (eq (get-text-property pos 'part-side) (get-text-property (1+ pos) 'part-side))
  8902. (setq end (next-single-property-change pos 'part-side)))
  8903. (when (eq (char-after beg) ?\n)
  8904. (setq beg (1+ beg)))
  8905. (set-mark beg)
  8906. (goto-char end)
  8907. (when (looking-back "^[ \t]+" (point-min))
  8908. (beginning-of-line))
  8909. (exchange-point-and-mark)
  8910. (setq web-mode-expand-previous-state "part-side"))
  8911. ((and (get-text-property pos 'tag-attr)
  8912. (not (member web-mode-expand-previous-state '("html-attr" "html-tag"))))
  8913. (web-mode-attribute-select pos)
  8914. (setq web-mode-expand-previous-state "html-attr"))
  8915. ((and (eq (get-text-property pos 'tag-type) 'comment)
  8916. (not (member web-mode-expand-previous-state '("html-tag" "html-comment" "html-elt" "html-parent"))))
  8917. (web-mode-tag-select)
  8918. (setq web-mode-expand-previous-state "html-comment"))
  8919. ((and (get-text-property pos 'tag-name)
  8920. (not (member web-mode-expand-previous-state '("html-tag" "html-elt" "html-parent"))))
  8921. (web-mode-tag-select)
  8922. (setq web-mode-expand-previous-state "html-tag"))
  8923. ((and (get-text-property pos 'tag-beg)
  8924. (string= web-mode-expand-previous-state "html-tag"))
  8925. (web-mode-element-select)
  8926. (setq web-mode-expand-previous-state "html-elt"))
  8927. (t
  8928. (cond
  8929. ((not (web-mode-element-parent))
  8930. (push-mark (point))
  8931. (push-mark (point-max) nil t)
  8932. (goto-char (point-min))
  8933. (setq web-mode-expand-previous-state "mark-whole"))
  8934. ((not (= (web-mode-tag-end-position (point)) (1- beg)))
  8935. (web-mode-element-content-select)
  8936. (setq web-mode-expand-previous-state "elt-content"))
  8937. (t
  8938. (web-mode-element-select)
  8939. (setq web-mode-expand-previous-state "html-parent"))
  8940. )
  8941. ) ;t
  8942. ) ;cond
  8943. ;;(message "w=%S" (window-end))
  8944. ;;(message "after=%S" web-mode-expand-previous-state)
  8945. ))
  8946. (defun web-mode-block-kill ()
  8947. "Kill the current block."
  8948. (interactive)
  8949. (web-mode-block-select)
  8950. (when mark-active
  8951. (kill-region (region-beginning) (region-end))))
  8952. (defun web-mode-block-select ()
  8953. "Select the current block."
  8954. (interactive)
  8955. (let (beg)
  8956. (when (setq beg (web-mode-block-beginning-position (point)))
  8957. (goto-char beg)
  8958. (set-mark (point))
  8959. (web-mode-block-end)
  8960. (exchange-point-and-mark))
  8961. beg))
  8962. (defun web-mode-tag-select ()
  8963. "Select the current html tag."
  8964. (interactive)
  8965. (let (beg)
  8966. (when (setq beg (web-mode-tag-beginning-position (point)))
  8967. (goto-char beg)
  8968. (set-mark (point))
  8969. (web-mode-tag-end)
  8970. (exchange-point-and-mark))
  8971. beg))
  8972. (defun web-mode-element-content-select ()
  8973. "Select the content of a html element."
  8974. (interactive)
  8975. (let (pos beg end)
  8976. (web-mode-element-select)
  8977. (when mark-active
  8978. (setq pos (point))
  8979. (deactivate-mark)
  8980. (web-mode-tag-match)
  8981. (setq end (point))
  8982. (goto-char pos)
  8983. (web-mode-tag-end)
  8984. (set-mark (point))
  8985. (goto-char end)
  8986. (exchange-point-and-mark)
  8987. )))
  8988. (defun web-mode-element-select ()
  8989. "Select the current html element (including opening and closing tags)."
  8990. (interactive)
  8991. (let* ((pos (point))
  8992. (type (get-text-property pos 'tag-type)))
  8993. (cond
  8994. ((not type)
  8995. (web-mode-element-parent)
  8996. (unless (= (point) pos) (web-mode-element-select)))
  8997. ((member type '(start void))
  8998. (web-mode-tag-beginning)
  8999. (set-mark (point))
  9000. (web-mode-tag-match)
  9001. (web-mode-tag-end)
  9002. (exchange-point-and-mark))
  9003. (t
  9004. (web-mode-tag-match)
  9005. (set-mark (point))
  9006. (web-mode-tag-match)
  9007. (web-mode-tag-end)
  9008. (exchange-point-and-mark))
  9009. )))
  9010. (defun web-mode-element-is-collapsed (&optional pos)
  9011. (unless pos (setq pos (point)))
  9012. (let (boundaries)
  9013. (and (setq boundaries (web-mode-element-boundaries pos))
  9014. (or (= (car (car boundaries)) (car (cdr boundaries)))
  9015. (= (cdr (car boundaries)) (1- (car (cdr boundaries)))))
  9016. )))
  9017. (defun web-mode-element-contract ()
  9018. "Flatten elements."
  9019. (interactive)
  9020. (let (beg end (continue t) replacement boundaries)
  9021. (cond
  9022. ((or (not (get-text-property (point) 'tag-type))
  9023. (not (member (get-text-property (point) 'tag-type) '(start end))))
  9024. (web-mode-element-parent))
  9025. ((eq (get-text-property (point) 'tag-type) 'end)
  9026. (web-mode-tag-match))
  9027. ) ;cond
  9028. (setq boundaries (web-mode-element-boundaries (point)))
  9029. (setq beg (car (car boundaries))
  9030. end (cdr (cdr boundaries)))
  9031. (goto-char beg)
  9032. ;;(message "beg(%S) end(%S)" beg end)
  9033. (while continue
  9034. (if (or (not (re-search-forward ">[ \t\r\n]+\\|[ \t\r\n]+<"))
  9035. (>= (point) end))
  9036. (setq continue nil)
  9037. (setq end (+ (- end (length (match-string-no-properties 0))) 1))
  9038. (setq replacement (if (eq (char-before) ?\<) "<" ">"))
  9039. (replace-match replacement nil nil)
  9040. ;;(message "end(%S)" end))
  9041. )
  9042. ) ;while
  9043. (goto-char beg)
  9044. ))
  9045. (defun web-mode-element-extract ()
  9046. "Flatten element."
  9047. (interactive)
  9048. (let (beg end (continue t) save boundaries)
  9049. (cond
  9050. ((or (not (get-text-property (point) 'tag-type))
  9051. (not (member (get-text-property (point) 'tag-type) '(start end))))
  9052. (web-mode-element-parent))
  9053. ((eq (get-text-property (point) 'tag-type) 'end)
  9054. (web-mode-tag-match))
  9055. ) ;cond
  9056. (setq boundaries (web-mode-element-boundaries (point)))
  9057. (setq beg (car (car boundaries))
  9058. end (cdr (cdr boundaries)))
  9059. (goto-char beg)
  9060. (while continue
  9061. (if (or (not (and (or (get-text-property (point) 'tag-type) (web-mode-tag-next))
  9062. (web-mode-tag-end)))
  9063. (>= (point) end))
  9064. (setq continue nil)
  9065. (setq save (point))
  9066. ;;(message "point(%S)" (point))
  9067. (skip-chars-forward "\n\t ")
  9068. (when (get-text-property (point) 'tag-type)
  9069. (newline)
  9070. (indent-according-to-mode)
  9071. (setq end (+ end (- (point) save))))
  9072. ) ;if
  9073. ) ;while
  9074. (goto-char beg)
  9075. ))
  9076. (defun web-mode-element-transpose ()
  9077. "Transpose two html elements."
  9078. (interactive)
  9079. (let (pos start1 end1 start2 end2)
  9080. (save-excursion
  9081. (setq pos (point))
  9082. (cond
  9083. ((get-text-property pos 'tag-type)
  9084. (setq start1 (web-mode-element-beginning-position pos)
  9085. end1 (1+ (web-mode-element-end-position pos)))
  9086. )
  9087. ((setq start1 (web-mode-element-parent-position pos))
  9088. (setq end1 (1+ (web-mode-element-end-position pos)))
  9089. )
  9090. ) ;cond
  9091. (when (and start1 end1 (> end1 0))
  9092. (goto-char end1)
  9093. (unless (get-text-property (point) 'tag-beg)
  9094. (skip-chars-forward "\n\t "))
  9095. (when (get-text-property (point) 'tag-beg)
  9096. (setq start2 (web-mode-element-beginning-position (point))
  9097. end2 (1+ (web-mode-element-end-position (point))))
  9098. )
  9099. )
  9100. (transpose-regions start1 end1 start2 end2)
  9101. ) ;save-excursion
  9102. start2))
  9103. (defun web-mode-element-children-comment (&optional pos)
  9104. "Comment all the children of the current html element."
  9105. (interactive)
  9106. (unless pos (setq pos (point)))
  9107. (save-excursion
  9108. (dolist (child (reverse (web-mode-element-children pos)))
  9109. (goto-char child)
  9110. (web-mode-comment (point)))
  9111. ))
  9112. (defun web-mode-element-mute-blanks ()
  9113. "Mute blanks."
  9114. (interactive)
  9115. (let (pos parent beg end children elt)
  9116. (setq pos (point))
  9117. (save-excursion
  9118. (when (and (setq parent (web-mode-element-boundaries pos))
  9119. (web-mode-element-child-position (point)))
  9120. (setq children (reverse (web-mode-element-children)))
  9121. (goto-char (car (cdr parent)))
  9122. (dolist (child children)
  9123. (setq elt (web-mode-element-boundaries child))
  9124. (when (> (point) (1+ (cddr elt)))
  9125. (when (and (not (eq (get-text-property (point) 'part-token) 'comment))
  9126. (not (eq (get-text-property (1+ (cddr elt)) 'part-token) 'comment)))
  9127. (web-mode-insert-text-at-pos "-->" (point))
  9128. (web-mode-insert-text-at-pos "<!--" (1+ (cddr elt))))
  9129. )
  9130. (goto-char child)
  9131. )
  9132. (when (and (> (point) (1+ (cdr (car parent))))
  9133. (not (eq (get-text-property (point) 'part-token) 'comment))
  9134. (not (eq (get-text-property (1+ (cdr (car parent))) 'part-token) 'comment)))
  9135. (web-mode-insert-text-at-pos "-->" (point))
  9136. (web-mode-insert-text-at-pos "<!--" (1+ (cdr (car parent)))))
  9137. ) ;when
  9138. )))
  9139. (defun web-mode-element-children (&optional pos)
  9140. (unless pos (setq pos (point)))
  9141. (let ((continue t) (i 0) child children)
  9142. (save-excursion
  9143. (when (and (member (get-text-property pos 'tag-type) '(start end))
  9144. (setq child (web-mode-element-child-position pos)))
  9145. (while continue
  9146. (cond
  9147. ((> (setq i (1+ i)) 100)
  9148. (setq continue nil)
  9149. (message "element-children ** warning **"))
  9150. ((= i 1)
  9151. (goto-char child))
  9152. ((web-mode-element-sibling-next)
  9153. )
  9154. (t
  9155. (setq continue nil))
  9156. ) ;cond
  9157. (when continue
  9158. (setq children (append children (list (point)))))
  9159. ) ;while
  9160. ) ;when
  9161. ) ;save-excursion
  9162. ;;(message "%S" children)
  9163. children))
  9164. (defun web-mode-property-boundaries (prop &optional pos)
  9165. "property boundaries (cdr is 1+)"
  9166. (unless pos (setq pos (point)))
  9167. (let (beg end val)
  9168. (setq val (get-text-property pos prop))
  9169. (if (null val)
  9170. val
  9171. (if (or (bobp)
  9172. (not (eq (get-text-property (1- pos) prop) val)))
  9173. (setq beg pos)
  9174. (setq beg (previous-single-property-change pos prop))
  9175. (when (null beg) (setq beg (point-min))))
  9176. (if (or (eobp)
  9177. (not (eq (get-text-property (1+ pos) prop) val)))
  9178. (setq end pos)
  9179. (setq end (next-single-property-change pos prop))
  9180. (when (null end) (setq end (point-min))))
  9181. (cons beg end))))
  9182. (defun web-mode-content-boundaries (&optional pos)
  9183. (unless pos (setq pos (point)))
  9184. (let (beg end)
  9185. (setq beg (or (previous-property-change pos (current-buffer))
  9186. (point-max)))
  9187. (setq end (or (next-property-change pos (current-buffer))
  9188. (point-min)))
  9189. (while (and (< beg end) (member (char-after beg) '(?\s ?\n)))
  9190. (setq beg (1+ beg)))
  9191. (while (and (> end beg) (member (char-after (1- end)) '(?\s ?\n)))
  9192. (setq end (1- end)))
  9193. ;; (message "beg(%S) end(%S)" beg end)
  9194. (cons beg end)
  9195. ))
  9196. (defun web-mode-element-boundaries (&optional pos)
  9197. "Return ((start-tag-beg . start-tag-end) . (end-tag-beg . end-tag-end))
  9198. First level car and cdr are the same with void elements.
  9199. Pos should be in a tag."
  9200. (unless pos (setq pos (point)))
  9201. (let (start-tag-beg start-tag-end end-tag-beg end-tag-end)
  9202. (cond
  9203. ((eq (get-text-property pos 'tag-type) 'start)
  9204. (setq start-tag-beg (web-mode-tag-beginning-position pos)
  9205. start-tag-end (web-mode-tag-end-position pos))
  9206. (when (setq pos (web-mode-tag-match-position pos))
  9207. (setq end-tag-beg pos
  9208. end-tag-end (web-mode-tag-end-position pos)))
  9209. )
  9210. ((eq (get-text-property pos 'tag-type) 'end)
  9211. (setq end-tag-beg (web-mode-tag-beginning-position pos)
  9212. end-tag-end (web-mode-tag-end-position pos))
  9213. (when (setq pos (web-mode-tag-match-position pos))
  9214. (setq start-tag-beg pos
  9215. start-tag-end (web-mode-tag-end-position pos)))
  9216. )
  9217. ((eq (get-text-property pos 'tag-type) 'void)
  9218. (setq start-tag-beg (web-mode-tag-beginning-position pos)
  9219. start-tag-end (web-mode-tag-end-position pos))
  9220. (setq end-tag-beg start-tag-beg
  9221. end-tag-end start-tag-end)
  9222. )
  9223. ) ;cond
  9224. (if (and start-tag-beg start-tag-end end-tag-beg end-tag-end)
  9225. (cons (cons start-tag-beg start-tag-end) (cons end-tag-beg end-tag-end))
  9226. nil)
  9227. ))
  9228. (defun web-mode-surround ()
  9229. "Surround each line of the current REGION with a start/end tag."
  9230. (interactive)
  9231. (when mark-active
  9232. (let (beg end line-beg line-end pos tag tag-start tag-end)
  9233. (save-excursion
  9234. (setq tag (read-from-minibuffer "Tag name? ")
  9235. tag-start (concat "<" tag ">")
  9236. tag-end (concat "</" tag ">")
  9237. pos (point)
  9238. beg (region-beginning)
  9239. end (region-end)
  9240. line-beg (web-mode-line-number beg)
  9241. line-end (web-mode-line-number end))
  9242. (goto-char end)
  9243. (unless (bolp)
  9244. (insert tag-end)
  9245. (back-to-indentation)
  9246. (when (> beg (point))
  9247. (goto-char beg))
  9248. (insert tag-start))
  9249. (while (> line-end line-beg)
  9250. (forward-line -1)
  9251. (setq line-end (1- line-end))
  9252. (unless (looking-at-p "[[:space:]]*$")
  9253. (end-of-line)
  9254. (insert tag-end)
  9255. (back-to-indentation)
  9256. (when (> beg (point))
  9257. (goto-char beg))
  9258. (insert tag-start))
  9259. ) ;while
  9260. (deactivate-mark)
  9261. ))))
  9262. (defun web-mode-lify-region ()
  9263. "Transform current REGION in an html list (<li>line1</li>...)"
  9264. (interactive)
  9265. (let (beg end lines)
  9266. (save-excursion
  9267. (when mark-active
  9268. (setq beg (region-beginning)
  9269. end (region-end))
  9270. (setq lines (buffer-substring beg end))
  9271. (kill-region beg end)
  9272. (setq lines (replace-regexp-in-string "^[ \t]*" "<li>" lines))
  9273. (setq lines (replace-regexp-in-string "$" "</li>" lines))
  9274. (web-mode-insert-and-indent lines)
  9275. ) ;when
  9276. ) ; save-excursion
  9277. ) ;let
  9278. )
  9279. (defun web-mode-element-wrap (&optional tag-name)
  9280. "Wrap current REGION with start and end tags.
  9281. Prompt user if TAG-NAME isn't provided."
  9282. (interactive)
  9283. (let (beg end pos tag sep)
  9284. (save-excursion
  9285. (setq tag (or tag-name (read-from-minibuffer "Tag name? ")))
  9286. (setq pos (point))
  9287. (cond
  9288. (mark-active
  9289. (setq beg (region-beginning)
  9290. end (region-end)))
  9291. ((get-text-property pos 'tag-type)
  9292. (setq beg (web-mode-element-beginning-position pos)
  9293. end (1+ (web-mode-element-end-position pos))))
  9294. ((setq beg (web-mode-element-parent-position pos))
  9295. (setq end (1+ (web-mode-element-end-position pos))))
  9296. )
  9297. ;; (message "beg(%S) end(%S)" beg end)
  9298. (when (and beg end (> end 0))
  9299. (setq sep (if (get-text-property beg 'tag-beg) "\n" ""))
  9300. (web-mode-insert-text-at-pos (concat sep "</" tag ">") end)
  9301. (web-mode-insert-text-at-pos (concat "<" tag ">" sep) beg)
  9302. (when (string= sep "\n") (indent-region beg (+ end (* (+ 3 (length tag)) 2))))
  9303. )
  9304. ) ;save-excursion
  9305. (web-mode-go beg)))
  9306. (defun web-mode-element-vanish (&optional arg)
  9307. "Vanish the current html element. The content of the element is kept."
  9308. (interactive "p")
  9309. (let (type (pos (point)) start-b start-e end-b end-e)
  9310. (while (>= arg 1)
  9311. (setq type (get-text-property pos 'tag-type))
  9312. (when type
  9313. (cond
  9314. ((member type '(void))
  9315. (web-mode-element-kill)
  9316. (set-mark (point))
  9317. (web-mode-tag-match)
  9318. (web-mode-tag-end)
  9319. (exchange-point-and-mark))
  9320. ((member type '(start))
  9321. (setq start-b (web-mode-tag-beginning-position)
  9322. start-e (web-mode-tag-end-position))
  9323. (when (web-mode-tag-match)
  9324. (setq end-b (web-mode-tag-beginning-position)
  9325. end-e (web-mode-tag-end-position)))
  9326. )
  9327. (t
  9328. (setq end-b (web-mode-tag-beginning-position)
  9329. end-e (web-mode-tag-end-position))
  9330. (when (web-mode-tag-match)
  9331. (setq start-b (web-mode-tag-beginning-position)
  9332. start-e (web-mode-tag-end-position)))
  9333. ) ;t
  9334. ) ;cond
  9335. (when (and start-b end-b)
  9336. (goto-char end-b)
  9337. (delete-region end-b (1+ end-e))
  9338. (delete-blank-lines)
  9339. (goto-char start-b)
  9340. (delete-region start-b (1+ start-e))
  9341. (delete-blank-lines)
  9342. (web-mode-buffer-indent)
  9343. )
  9344. ;; (message "start %S %S - end %S %S" start-b start-e end-b end-e))
  9345. ) ;when
  9346. (skip-chars-forward "[:space:]\n")
  9347. (setq arg (1- arg))
  9348. ) ;while
  9349. ) ;let
  9350. )
  9351. (defun web-mode-element-kill (&optional arg)
  9352. "Kill the current html element."
  9353. (interactive "p")
  9354. (while (>= arg 1)
  9355. (setq arg (1- arg))
  9356. (web-mode-element-select)
  9357. (when mark-active
  9358. (kill-region (region-beginning) (region-end)))
  9359. ) ;while
  9360. )
  9361. (defun web-mode-element-clone (&optional arg)
  9362. "Clone the current html element."
  9363. (interactive "p")
  9364. (let (col pos)
  9365. (while (>= arg 1)
  9366. (setq arg (1- arg)
  9367. col 0)
  9368. (web-mode-element-select)
  9369. (when mark-active
  9370. (save-excursion
  9371. (goto-char (region-beginning))
  9372. (setq col (current-column)))
  9373. (kill-region (region-beginning) (region-end))
  9374. (yank)
  9375. (newline)
  9376. (indent-line-to col)
  9377. (setq pos (point))
  9378. (yank)
  9379. (goto-char pos))
  9380. )
  9381. ) ;let
  9382. )
  9383. (defun web-mode-element-insert ()
  9384. "Insert an html element."
  9385. (interactive)
  9386. (let (tag-name)
  9387. (cond
  9388. ((and (get-text-property (point) 'tag-type)
  9389. (not (get-text-property (point) 'tag-beg)))
  9390. (message "element-insert ** invalid context **"))
  9391. ((not (and (setq tag-name (read-from-minibuffer "Tag name? "))
  9392. (> (length tag-name) 0)))
  9393. (message "element-insert ** failure **"))
  9394. ((web-mode-element-is-void tag-name)
  9395. (insert (concat "<" (replace-regexp-in-string "/" "" tag-name) "/>"))
  9396. )
  9397. (mark-active
  9398. (let ((beg (region-beginning)) (end (region-end)))
  9399. (deactivate-mark)
  9400. (goto-char end)
  9401. (insert "</" tag-name ">")
  9402. (goto-char beg)
  9403. (insert "<" tag-name ">")
  9404. )
  9405. )
  9406. (t
  9407. (insert (concat "<" tag-name ">" "</" tag-name ">"))
  9408. (web-mode-sb "</")
  9409. )
  9410. ) ;cond
  9411. ))
  9412. (defun web-mode-element-insert-at-point ()
  9413. "Replace the word at point with a html tag of it."
  9414. (interactive)
  9415. (let ((tag-name (thing-at-point 'word)))
  9416. (cond
  9417. ((web-mode-element-is-void tag-name)
  9418. (backward-kill-word 1)
  9419. (insert (concat "<" (replace-regexp-in-string "/" "" tag-name) "/>"))
  9420. )
  9421. (mark-active
  9422. (setq tag-name (buffer-substring (region-beginning) (region-end)))
  9423. (delete-region (region-beginning) (region-end))
  9424. (insert (concat "<" tag-name ">" "</" tag-name ">"))
  9425. (web-mode-sb "</")
  9426. )
  9427. (tag-name ; do nothing is there isn's word at point
  9428. (backward-kill-word 1)
  9429. (insert (concat "<" tag-name ">" "</" tag-name ">"))
  9430. (web-mode-sb "</")
  9431. )
  9432. ) ;cond
  9433. ))
  9434. (defun web-mode-element-rename (&optional tag-name)
  9435. "Rename the current html element."
  9436. (interactive)
  9437. (save-excursion
  9438. (let (pos)
  9439. (unless tag-name (setq tag-name (read-from-minibuffer "New tag name? ")))
  9440. (when (and (> (length tag-name) 0)
  9441. (web-mode-element-beginning)
  9442. (looking-at "<\\([[:alnum:]]+\\(:?[-][[:alpha:]]+\\)?\\)"))
  9443. (setq pos (point))
  9444. (unless (web-mode-element-is-void)
  9445. (save-match-data
  9446. (web-mode-tag-match)
  9447. (if (looking-at "</[ ]*\\([[:alnum:]]+\\(:?[-][[:alpha:]]+\\)?\\)")
  9448. (replace-match (concat "</" tag-name))
  9449. )))
  9450. (goto-char pos)
  9451. (replace-match (concat "<" tag-name))
  9452. ))))
  9453. (defun web-mode-current-trimmed-line ()
  9454. (web-mode-trim (buffer-substring-no-properties
  9455. (line-beginning-position)
  9456. (line-end-position))))
  9457. (defun web-mode-trim (string)
  9458. (replace-regexp-in-string "\\`[ \t\n]*" "" (replace-regexp-in-string "[ \t\n]*\\'" "" string)))
  9459. (defun web-mode-is-token-end (pos)
  9460. (let (block-token part-token)
  9461. (setq block-token (get-text-property pos 'block-token))
  9462. (setq part-token (get-text-property pos 'part-token))
  9463. (cond
  9464. ((not (or block-token part-token))
  9465. nil)
  9466. ((>= (1+ pos) (point-max))
  9467. t)
  9468. ((and block-token
  9469. (not (string= (get-text-property (1+ pos) 'block-token) block-token)))
  9470. t)
  9471. ((and part-token
  9472. (not (string= (get-text-property (1+ pos) 'part-token) part-token)))
  9473. t)
  9474. (t
  9475. nil)
  9476. ) ;cond
  9477. ))
  9478. (defun web-mode-block-is-token-line ()
  9479. (save-excursion
  9480. (let ((continue t) (counter 0))
  9481. (beginning-of-line)
  9482. (back-to-indentation)
  9483. (while (and continue (not (eolp)))
  9484. (cond
  9485. ((get-text-property (point) 'block-token)
  9486. (setq counter (1+ counter)))
  9487. ((not (member (following-char) '(?\s ?\t)))
  9488. (setq continue nil
  9489. counter 0))
  9490. ) ;cond
  9491. (forward-char)
  9492. ) ;while
  9493. (> counter 0)
  9494. )))
  9495. (defun web-mode-part-is-token-line (pos)
  9496. (save-excursion
  9497. (let ((continue t)
  9498. (counter 0))
  9499. (goto-char pos)
  9500. (setq continue (not (eolp)))
  9501. (while continue
  9502. (forward-char)
  9503. (cond
  9504. ((eolp)
  9505. (setq continue nil))
  9506. ((or (get-text-property (point) 'block-side)
  9507. (member (get-text-property (point) 'part-token) '(comment string)))
  9508. (setq counter (1+ counter)))
  9509. ((not (member (following-char) '(?\s ?\t)))
  9510. (setq continue nil
  9511. counter 0))
  9512. )
  9513. ) ;while
  9514. (> counter 0))))
  9515. (defun web-mode-is-content (&optional pos)
  9516. (unless pos (setq pos (point)))
  9517. (not (or (get-text-property pos 'part-side)
  9518. (get-text-property pos 'tag-type)
  9519. (get-text-property pos 'block-side)
  9520. )))
  9521. (defun web-mode-is-comment-or-string (&optional pos)
  9522. (unless pos (setq pos (point)))
  9523. (not (null (or (eq (get-text-property pos 'tag-type) 'comment)
  9524. (member (get-text-property pos 'block-token) '(comment string))
  9525. (member (get-text-property pos 'part-token) '(comment string))))))
  9526. ;; NOTE: we look at the firt one
  9527. (defun web-mode-block-is-open (&optional pos)
  9528. (unless pos (setq pos (point))))
  9529. ;; NOTE: we look at the last one
  9530. (defun web-mode-block-is-close (&optional pos)
  9531. (unless pos (setq pos (point)))
  9532. (and (get-text-property pos 'block-side)
  9533. (eq (caar (web-mode-block-controls-get pos)) 'close)))
  9534. ;; NOTE: we look at the first one
  9535. (defun web-mode-block-is-inside (&optional pos)
  9536. (unless pos (setq pos (point)))
  9537. (and (get-text-property pos 'block-side)
  9538. (eq (caar (web-mode-block-controls-get pos)) 'inside)))
  9539. (defun web-mode-element-is-void (&optional tag)
  9540. (cond
  9541. ((and (not tag) (eq (get-text-property (point) 'tag-type) 'void))
  9542. t)
  9543. ((and tag (member tag '("div" "li" "a" "p" "h1" "h2" "h3" "ul" "span" "article" "section" "td" "tr")))
  9544. nil)
  9545. ((and tag (string-suffix-p "/" tag))
  9546. t)
  9547. ((and tag (string= web-mode-content-type "jsx"))
  9548. (member (downcase tag) '("img" "br" "hr")))
  9549. (tag
  9550. (car (member (downcase tag) web-mode-void-elements)))
  9551. (t
  9552. nil)
  9553. ))
  9554. ;;---- COMMENT ------------------------------------------------------------------
  9555. (defun web-mode-toggle-comments ()
  9556. "Toggle comments visbility."
  9557. (interactive)
  9558. (web-mode-with-silent-modifications
  9559. (save-excursion
  9560. (if web-mode-comments-invisible
  9561. (remove-overlays))
  9562. (setq web-mode-comments-invisible (null web-mode-comments-invisible))
  9563. (let ((continue t)
  9564. (pos (point-min))
  9565. (visibility web-mode-comments-invisible)
  9566. overlay end)
  9567. (while continue
  9568. (setq pos (next-single-property-change pos 'font-lock-face))
  9569. (if (null pos)
  9570. (setq continue nil)
  9571. (when (eq (get-text-property pos 'font-lock-face) 'web-mode-comment-face)
  9572. (setq end (next-single-property-change pos 'font-lock-face))
  9573. (put-text-property pos end 'invisible visibility)
  9574. (when visibility
  9575. (setq overlay (make-overlay pos end)))
  9576. (goto-char pos)
  9577. )
  9578. )
  9579. )
  9580. ) ;let
  9581. )))
  9582. (defun web-mode-comment-or-uncomment-region (beg end &optional arg)
  9583. (interactive)
  9584. (save-excursion
  9585. (push-mark end)
  9586. (goto-char beg)
  9587. (setq mark-active t)
  9588. (web-mode-comment-or-uncomment)
  9589. (pop-mark)))
  9590. (defun web-mode-comment-or-uncomment ()
  9591. "Comment or uncomment line(s), block or region at POS."
  9592. (interactive)
  9593. ;; TODO : if mark is at eol, mark--
  9594. (if (and (not mark-active) (looking-at-p "[[:space:]]*$"))
  9595. (web-mode-comment-insert)
  9596. (when (and (use-region-p) (eq (point) (region-end)))
  9597. (if (bolp) (backward-char))
  9598. (exchange-point-and-mark))
  9599. (if (eq (get-text-property (point) 'block-token) 'delimiter-beg)
  9600. (web-mode-block-skip-blank-forward (point) '(delimiter-beg))
  9601. (skip-chars-forward "[:space:]" (line-end-position)))
  9602. (cond
  9603. ((or (eq (get-text-property (point) 'tag-type) 'comment)
  9604. (eq (get-text-property (point) 'block-token) 'comment)
  9605. (eq (get-text-property (point) 'part-token) 'comment))
  9606. (web-mode-uncomment (point)))
  9607. (t
  9608. (web-mode-comment (point)))
  9609. )
  9610. ) ;if
  9611. )
  9612. (defun web-mode-comment-indent-new-line (&optional soft)
  9613. (interactive)
  9614. (let (ctx)
  9615. (setq ctx (web-mode-comment-context))
  9616. (cond
  9617. ((null ctx)
  9618. (newline 1))
  9619. (t
  9620. (newline 1)
  9621. (indent-line-to (plist-get ctx :col))
  9622. (insert (concat (plist-get ctx :prefix) "")))
  9623. ) ;cond
  9624. ))
  9625. (defun web-mode-comment-context (&optional pos)
  9626. (cond
  9627. (pos
  9628. )
  9629. ((and (eolp) (not (bobp)))
  9630. (setq pos (1- (point))))
  9631. (t
  9632. (setq pos (point)))
  9633. ) ;cond
  9634. (let (beg col prefix type format)
  9635. (cond
  9636. ((eq (get-text-property pos 'block-token) 'comment)
  9637. (setq type "block"))
  9638. ((eq (get-text-property pos 'tag-type) 'comment)
  9639. (setq type "tag"))
  9640. ((eq (get-text-property pos 'part-token) 'comment)
  9641. (setq type "part"))
  9642. )
  9643. (if (null type) nil
  9644. (save-excursion
  9645. (goto-char pos)
  9646. (web-mode-comment-beginning)
  9647. (setq beg (point)
  9648. col (current-column))
  9649. (cond
  9650. ((looking-at-p "/\\*")
  9651. (setq format "/*"
  9652. prefix " * "))
  9653. ((looking-at-p "//")
  9654. (setq format "//"
  9655. prefix "//"))
  9656. ((looking-at-p "#")
  9657. (setq format "#"
  9658. prefix "#"))
  9659. ((looking-at-p ";")
  9660. (setq format ";"
  9661. prefix ";"))
  9662. ) ;cond
  9663. (list :beg beg :col col :prefix prefix :type type :format format)))))
  9664. (defun web-mode-comment-insert ()
  9665. (let ((alt nil) (language nil) (pos (point)))
  9666. (setq language (web-mode-language-at-pos pos))
  9667. (setq alt (cdr (assoc language web-mode-comment-formats)))
  9668. ;;(message "language=%S" language)
  9669. (cond
  9670. ((get-text-property pos 'block-side)
  9671. (cond
  9672. ((and alt (string= alt "//"))
  9673. (insert "// "))
  9674. (t
  9675. (insert "/* */")
  9676. (search-backward " */"))
  9677. ) ;cond
  9678. ) ;case block-side
  9679. ((get-text-property pos 'part-side)
  9680. (cond
  9681. ((and alt (string= alt "//"))
  9682. (insert "// "))
  9683. (t
  9684. (insert "/* */")
  9685. (search-backward " */"))
  9686. ) ;cond
  9687. ) ;case part-side
  9688. (t
  9689. (insert "<!-- -->")
  9690. (search-backward " -->")
  9691. ) ;case html
  9692. ) ;cond
  9693. ))
  9694. (defun web-mode-comment (pos)
  9695. (let (ctx language col sel beg end tmp block-side single-line-block pos-after content)
  9696. (setq pos-after pos)
  9697. (setq block-side (get-text-property pos 'block-side))
  9698. (setq single-line-block (web-mode-is-single-line-block pos))
  9699. (cond
  9700. ((and block-side (string= web-mode-engine "erb"))
  9701. (web-mode-comment-erb-block pos)
  9702. )
  9703. ((and block-side (string= web-mode-engine "artanis"))
  9704. (web-mode-comment-artanis-block pos)
  9705. )
  9706. ((and single-line-block block-side
  9707. (intern-soft (concat "web-mode-comment-" web-mode-engine "-block")))
  9708. (funcall (intern (concat "web-mode-comment-" web-mode-engine "-block")) pos)
  9709. )
  9710. (t
  9711. (setq ctx (web-mode-point-context
  9712. (if mark-active (region-beginning) (line-beginning-position))))
  9713. ;;(message "%S" ctx)
  9714. (setq language (plist-get ctx :language))
  9715. (setq col (current-column))
  9716. (cond
  9717. (mark-active
  9718. ;;(message "%S %S" (point) col)
  9719. )
  9720. ((and (member language '("html" "xml"))
  9721. (get-text-property (progn (back-to-indentation) (point)) 'tag-beg))
  9722. (web-mode-element-select))
  9723. (t
  9724. (end-of-line)
  9725. (set-mark (line-beginning-position)))
  9726. ) ;cond
  9727. (setq beg (region-beginning)
  9728. end (region-end))
  9729. (when (> (point) (mark))
  9730. (exchange-point-and-mark))
  9731. (if (and (eq (char-before end) ?\n)
  9732. (not (eq (char-after end) ?\n)))
  9733. (setq end (1- end)))
  9734. (setq sel (buffer-substring-no-properties beg end))
  9735. (cond
  9736. ((member language '("html" "xml"))
  9737. (cond
  9738. ((and (= web-mode-comment-style 2) (string= web-mode-engine "django"))
  9739. (setq content (concat "{# " sel " #}")))
  9740. ((and (= web-mode-comment-style 2) (member web-mode-engine '("ejs" "erb")))
  9741. (setq content (concat "<%# " sel " %>")))
  9742. ((and (= web-mode-comment-style 2) (string= web-mode-engine "artanis"))
  9743. (setq content (concat "<%; " sel " %>")))
  9744. ((and (= web-mode-comment-style 2) (string= web-mode-engine "aspx"))
  9745. (setq content (concat "<%-- " sel " --%>")))
  9746. ((and (= web-mode-comment-style 2) (string= web-mode-engine "smarty"))
  9747. (setq content (concat "{* " sel " *}")))
  9748. ((and (= web-mode-comment-style 2) (string= web-mode-engine "expressionengine"))
  9749. (setq content (concat "{!-- " sel " --}")))
  9750. ((and (= web-mode-comment-style 2) (string= web-mode-engine "xoops"))
  9751. (setq content (concat "<{* " sel " *}>")))
  9752. ((and (= web-mode-comment-style 2) (string= web-mode-engine "hero"))
  9753. (setq content (concat "<%# " sel " %>")))
  9754. ((and (= web-mode-comment-style 2) (string= web-mode-engine "blade"))
  9755. (setq content (concat "{{-- " sel " --}}")))
  9756. ((and (= web-mode-comment-style 2) (string= web-mode-engine "ctemplate"))
  9757. (setq content (concat "{{!-- " sel " --}}")))
  9758. ((and (= web-mode-comment-style 2) (string= web-mode-engine "razor"))
  9759. (setq content (concat "@* " sel " *@")))
  9760. (t
  9761. (setq content (concat "<!-- " sel " -->"))
  9762. (when (< (length sel) 1)
  9763. (search-backward " -->")
  9764. (setq pos-after nil))
  9765. ))
  9766. ) ;case html
  9767. ((member language '("php" "javascript" "typescript" "java" "jsx"))
  9768. (let (alt)
  9769. (setq alt (cdr (assoc language web-mode-comment-formats)))
  9770. ;;(message "language=%S alt=%S sel=%S col=%S" language alt sel col)
  9771. (cond
  9772. ((and alt (string= alt "//"))
  9773. (setq content (replace-regexp-in-string (concat "\n[ ]\\{" (number-to-string col) "\\}") "\n" sel))
  9774. (setq content (replace-regexp-in-string (concat "\n") "\n// " content))
  9775. (setq content (concat "// " content)))
  9776. ((get-text-property pos 'jsx-depth)
  9777. (setq content (concat "{/* " sel " */}")))
  9778. (web-mode-comment-prefixing
  9779. (setq content (replace-regexp-in-string (concat "\n[ ]\\{" (number-to-string col) "\\}") "\n* " sel))
  9780. (setq content (concat "/* " content " */")))
  9781. (t
  9782. (setq content (concat "/* " sel " */")))
  9783. ) ;cond
  9784. ) ;let
  9785. )
  9786. ((member language '("erb"))
  9787. (setq content (replace-regexp-in-string "^[ ]*" "#" sel)))
  9788. ((member language '("asp"))
  9789. (setq content (replace-regexp-in-string "^[ ]*" "''" sel)))
  9790. (t
  9791. (setq content (concat "/* " sel " */")))
  9792. ) ;cond
  9793. (when content
  9794. (delete-region beg end)
  9795. (deactivate-mark)
  9796. (let (beg end)
  9797. (setq beg (point-at-bol))
  9798. (insert content)
  9799. (setq end (point-at-eol))
  9800. (indent-region beg end)
  9801. )
  9802. ) ;when
  9803. ) ;t
  9804. ) ;cond
  9805. (when pos-after (goto-char pos-after))
  9806. ))
  9807. (defun web-mode-comment-ejs-block (pos)
  9808. (let (beg end)
  9809. (setq beg (web-mode-block-beginning-position pos)
  9810. end (web-mode-block-end-position pos))
  9811. (web-mode-insert-text-at-pos "//" (+ beg 2))))
  9812. (defun web-mode-comment-erb-block (pos)
  9813. (let (beg end)
  9814. (setq beg (web-mode-block-beginning-position pos)
  9815. end (web-mode-block-end-position pos))
  9816. (web-mode-insert-text-at-pos "#" (+ beg 2))))
  9817. (defun web-mode-comment-artanis-block (pos)
  9818. (let (beg end)
  9819. (setq beg (web-mode-block-beginning-position pos)
  9820. end (web-mode-block-end-position pos))
  9821. (web-mode-insert-text-at-pos ";" (+ beg 2))))
  9822. (defun web-mode-comment-django-block (pos)
  9823. (let (beg end)
  9824. (setq beg (web-mode-block-beginning-position pos)
  9825. end (web-mode-block-end-position pos))
  9826. (web-mode-insert-text-at-pos "#" end)
  9827. (web-mode-insert-text-at-pos "#" (1+ beg))))
  9828. (defun web-mode-comment-dust-block (pos)
  9829. (let (beg end)
  9830. (setq beg (web-mode-block-beginning-position pos)
  9831. end (web-mode-block-end-position pos))
  9832. (web-mode-insert-text-at-pos "!" end)
  9833. (web-mode-insert-text-at-pos "!" (1+ beg))))
  9834. (defun web-mode-comment-aspx-block (pos)
  9835. (let (beg end)
  9836. (setq beg (web-mode-block-beginning-position pos)
  9837. end (web-mode-block-end-position pos))
  9838. (web-mode-insert-text-at-pos "#" end)
  9839. (web-mode-insert-text-at-pos "#" (1+ beg))))
  9840. (defun web-mode-comment-jsp-block (pos)
  9841. (let (beg end)
  9842. (setq beg (web-mode-block-beginning-position pos)
  9843. end (web-mode-block-end-position pos))
  9844. (web-mode-insert-text-at-pos "--" (+ beg 2))))
  9845. (defun web-mode-comment-go-block (pos)
  9846. (let (beg end)
  9847. (setq beg (web-mode-block-beginning-position pos)
  9848. end (web-mode-block-end-position pos))
  9849. (web-mode-insert-text-at-pos "*/" (1- end))
  9850. (web-mode-insert-text-at-pos "/*" (+ beg (if (web-mode-looking-at "{{" beg) 2 0)))))
  9851. (defun web-mode-comment-php-block (pos)
  9852. (let (beg end)
  9853. (setq beg (web-mode-block-beginning-position pos)
  9854. end (web-mode-block-end-position pos))
  9855. (web-mode-insert-text-at-pos "*/" (- end 2))
  9856. (web-mode-insert-text-at-pos "/*" (+ beg 1 (if (web-mode-looking-at "<\\?php" beg) 5 3)))))
  9857. (defun web-mode-comment-svelte-block (pos)
  9858. (let (beg end)
  9859. (setq beg (web-mode-block-beginning-position pos)
  9860. end (web-mode-block-end-position pos))
  9861. (web-mode-insert-text-at-pos "!" end)
  9862. (web-mode-insert-text-at-pos "!" (1+ beg))))
  9863. (defun web-mode-comment-boundaries (&optional pos)
  9864. (interactive)
  9865. (unless pos (setq pos (point)))
  9866. (let ((beg pos) (end pos) prop)
  9867. (save-excursion
  9868. (goto-char pos)
  9869. (setq prop
  9870. (cond
  9871. ((eq (get-text-property pos 'block-token) 'comment) 'block-token)
  9872. ((eq (get-text-property pos 'tag-type) 'comment) 'tag-type)
  9873. ((eq (get-text-property pos 'part-token) 'comment) 'part-token)
  9874. (t nil)
  9875. ))
  9876. (if (null prop)
  9877. (setq beg nil
  9878. end nil)
  9879. (when (and (not (bobp))
  9880. (eq (get-text-property pos prop) (get-text-property (1- pos) prop)))
  9881. (setq beg (or (previous-single-property-change pos prop) (point-min))))
  9882. (when (and (not (eobp))
  9883. (eq (get-text-property pos prop) (get-text-property (1+ pos) prop)))
  9884. (setq end (or (next-single-property-change pos prop) (point-max)))))
  9885. (message "beg(%S) end(%S) point-max(%S)" beg end (point-max))
  9886. (when (and beg (string= (buffer-substring-no-properties beg (+ beg 2)) "//"))
  9887. (goto-char end)
  9888. (while (and (looking-at-p "\n[ ]*//")
  9889. (not (eobp)))
  9890. (search-forward "//")
  9891. (backward-char 2)
  9892. ;;(message "%S" (point))
  9893. (setq end (next-single-property-change (point) prop))
  9894. (goto-char end)
  9895. ;;(message "%S" (point))
  9896. ) ;while
  9897. ) ;when
  9898. ;;(when end (setq end (1- end))) ;; #1021
  9899. ) ;save-excursion
  9900. ;;(message "beg=%S end=%S" beg end)
  9901. (if (and beg end) (cons beg end) nil)
  9902. ))
  9903. (defun web-mode-uncomment (pos)
  9904. (let ((beg pos) (end pos) (sub2 "") comment boundaries)
  9905. (save-excursion
  9906. (cond
  9907. ((and (get-text-property pos 'block-side)
  9908. (intern-soft (concat "web-mode-uncomment-" web-mode-engine "-block")))
  9909. (funcall (intern (concat "web-mode-uncomment-" web-mode-engine "-block")) pos))
  9910. ((and (setq boundaries (web-mode-comment-boundaries pos))
  9911. (setq beg (car boundaries))
  9912. (setq end (1+ (cdr boundaries)))
  9913. (> (- end beg) 4))
  9914. (message "%S" boundaries)
  9915. ;;(message "beg(%S) end(%S)" beg end)
  9916. (setq comment (buffer-substring-no-properties beg end))
  9917. (setq sub2 (substring comment 0 2))
  9918. (cond
  9919. ((member sub2 '("<!" "<%"))
  9920. (setq comment (replace-regexp-in-string "\\(^<[!%]--[ ]?\\|[ ]?--[%]?>$\\)" "" comment)))
  9921. ((string= sub2 "{#")
  9922. (setq comment (replace-regexp-in-string "\\(^{#[ ]?\\|[ ]?#}$\\)" "" comment)))
  9923. ((string= sub2 "{/") ;jsx comments
  9924. (setq comment (replace-regexp-in-string "\\(^{/\\*[ ]?\\|[ ]?\\*/}$\\)" "" comment)))
  9925. ((string= sub2 "/*")
  9926. ;;(message "%S" comment)
  9927. ;;(setq comment (replace-regexp-in-string "\\(\\*/\\|^/\\*[ ]?\\|^[ \t]*\\*\\)" "" comment))
  9928. (setq comment (replace-regexp-in-string "\\([ ]?\\*/$\\|^/\\*[ ]?\\)" "" comment))
  9929. (setq comment (replace-regexp-in-string "\\(^[ \t]*\\*\\)" "" comment))
  9930. ;;(message "%S" comment)
  9931. )
  9932. ((string= sub2 "//")
  9933. (setq comment (replace-regexp-in-string "^ *//" "" comment)))
  9934. ) ;cond
  9935. (delete-region beg end)
  9936. (web-mode-insert-and-indent comment)
  9937. (goto-char beg)
  9938. )
  9939. ) ;cond
  9940. (indent-according-to-mode)
  9941. )))
  9942. (defun web-mode-uncomment-erb-block (pos)
  9943. (let (beg end)
  9944. (setq beg (web-mode-block-beginning-position pos)
  9945. end (web-mode-block-end-position pos))
  9946. (cond
  9947. ((string= (buffer-substring-no-properties beg (+ beg 4)) "<%#=")
  9948. (web-mode-remove-text-at-pos 1 (+ beg 2)))
  9949. ((string-match-p "<[%[:alpha:]]" (buffer-substring-no-properties (+ beg 2) (- end 2)))
  9950. (web-mode-remove-text-at-pos 2 (1- end))
  9951. (web-mode-remove-text-at-pos 3 beg))
  9952. (t
  9953. (web-mode-remove-text-at-pos 1 (+ beg 2)))
  9954. ) ;cond
  9955. )
  9956. )
  9957. (defun web-mode-uncomment-artanis-block (pos)
  9958. (let (beg end)
  9959. (setq beg (web-mode-block-beginning-position pos)
  9960. end (web-mode-block-end-position pos))
  9961. (cond
  9962. ((string= (buffer-substring-no-properties beg (+ beg 4)) "<%;=")
  9963. (web-mode-remove-text-at-pos 1 (+ beg 2)))
  9964. ((string-match-p "<[%[:alpha:]]" (buffer-substring-no-properties (+ beg 2) (- end 2)))
  9965. (web-mode-remove-text-at-pos 2 (1- end))
  9966. (web-mode-remove-text-at-pos 3 beg))
  9967. (t
  9968. (web-mode-remove-text-at-pos 1 (+ beg 2)))
  9969. ) ;cond
  9970. )
  9971. )
  9972. (defun web-mode-uncomment-ejs-block (pos)
  9973. (let (beg end)
  9974. (setq beg (web-mode-block-beginning-position pos)
  9975. end (web-mode-block-end-position pos))
  9976. (web-mode-remove-text-at-pos 1 (+ beg 2))))
  9977. (defun web-mode-uncomment-django-block (pos)
  9978. (let (beg end)
  9979. (setq beg (web-mode-block-beginning-position pos)
  9980. end (web-mode-block-end-position pos))
  9981. (cond
  9982. ((web-mode-looking-at-p "{#[{%]" beg)
  9983. (web-mode-remove-text-at-pos 1 (1- end))
  9984. (web-mode-remove-text-at-pos 1 (1+ beg))
  9985. )
  9986. (t
  9987. (web-mode-remove-text-at-pos 2 (1- end))
  9988. (web-mode-remove-text-at-pos 2 beg))
  9989. ) ;cond
  9990. ))
  9991. (defun web-mode-uncomment-ctemplate-block (pos)
  9992. (let (beg end)
  9993. (setq beg (web-mode-block-beginning-position pos)
  9994. end (web-mode-block-end-position pos))
  9995. (web-mode-remove-text-at-pos 5 (- end 4))
  9996. (web-mode-remove-text-at-pos 5 beg)))
  9997. (defun web-mode-uncomment-dust-block (pos)
  9998. (let (beg end)
  9999. (setq beg (web-mode-block-beginning-position pos)
  10000. end (web-mode-block-end-position pos))
  10001. (web-mode-remove-text-at-pos 1 (1- end))
  10002. (web-mode-remove-text-at-pos 1 (1+ beg))))
  10003. (defun web-mode-uncomment-aspx-block (pos)
  10004. (let (beg end)
  10005. (setq beg (web-mode-block-beginning-position pos)
  10006. end (web-mode-block-end-position pos))
  10007. (web-mode-remove-text-at-pos 1 (1- end))
  10008. (web-mode-remove-text-at-pos 1 (1+ beg))))
  10009. (defun web-mode-uncomment-jsp-block (pos)
  10010. (let (beg end)
  10011. (setq beg (web-mode-block-beginning-position pos)
  10012. end (web-mode-block-end-position pos))
  10013. (web-mode-remove-text-at-pos 2 (+ beg 2))))
  10014. (defun web-mode-uncomment-go-block (pos)
  10015. (let (beg end)
  10016. (setq beg (web-mode-block-beginning-position pos)
  10017. end (web-mode-block-end-position pos))
  10018. (web-mode-remove-text-at-pos 2 (+ beg 2))
  10019. (web-mode-remove-text-at-pos 2 (- end 5))))
  10020. (defun web-mode-uncomment-svelte-block (pos)
  10021. (let (beg end)
  10022. (setq beg (web-mode-block-beginning-position pos)
  10023. end (web-mode-block-end-position pos))
  10024. (web-mode-remove-text-at-pos 1 (1- end))
  10025. (web-mode-remove-text-at-pos 1 (1+ beg))))
  10026. (defun web-mode-snippet-names ()
  10027. (let (codes)
  10028. (dolist (snippet web-mode-snippets)
  10029. (add-to-list 'codes (car snippet) t))
  10030. codes))
  10031. (defun web-mode-snippet-insert (code)
  10032. "Insert a snippet."
  10033. (interactive
  10034. (list (completing-read "Snippet: " (web-mode-snippet-names))))
  10035. (let (beg
  10036. (continue t)
  10037. (counter 0)
  10038. end
  10039. sel
  10040. snippet
  10041. (l (length web-mode-snippets))
  10042. pos)
  10043. (when mark-active
  10044. (setq sel (web-mode-trim (buffer-substring-no-properties
  10045. (region-beginning) (region-end))))
  10046. (delete-region (region-beginning) (region-end)))
  10047. (while (and continue (< counter l))
  10048. (setq snippet (nth counter web-mode-snippets))
  10049. (when (string= (car snippet) code)
  10050. (setq continue nil))
  10051. (setq counter (1+ counter)))
  10052. (when snippet
  10053. (setq snippet (cdr snippet))
  10054. (setq beg (point-at-bol))
  10055. (insert snippet)
  10056. (setq pos (point)
  10057. end (point))
  10058. (cond
  10059. ((string-match-p "¦" snippet)
  10060. (search-backward "¦")
  10061. (delete-char 1)
  10062. (setq pos (point)
  10063. end (1- end)))
  10064. ((string-match-p "|" snippet)
  10065. (search-backward "|")
  10066. (delete-char 1)
  10067. (setq pos (point)
  10068. end (1- end)))
  10069. ) ;cond
  10070. (when sel
  10071. (insert sel)
  10072. (setq pos (point)
  10073. end (+ end (length sel))))
  10074. (goto-char end)
  10075. (setq end (point-at-eol))
  10076. (unless sel (goto-char pos))
  10077. (indent-region beg end))
  10078. ))
  10079. (defun web-mode-looking-at (regexp pos)
  10080. (save-excursion
  10081. (goto-char pos)
  10082. (looking-at regexp)))
  10083. (defun web-mode-looking-at-p (regexp pos)
  10084. (save-excursion
  10085. (goto-char pos)
  10086. (looking-at-p regexp)))
  10087. (defun web-mode-looking-back (regexp pos &optional limit greedy)
  10088. (save-excursion
  10089. (goto-char pos)
  10090. (if limit
  10091. (looking-back regexp limit greedy)
  10092. (looking-back regexp (point-min)))))
  10093. (defun web-mode-insert-text-at-pos (text pos)
  10094. (let ((mem web-mode-enable-auto-pairing))
  10095. (setq web-mode-enable-auto-pairing nil)
  10096. (save-excursion
  10097. (goto-char pos)
  10098. (insert text)
  10099. (setq web-mode-enable-auto-pairing mem)
  10100. )))
  10101. (defun web-mode-remove-text-at-pos (n &optional pos)
  10102. (unless pos (setq pos (point)))
  10103. (delete-region pos (+ pos n)))
  10104. (defun web-mode-insert-and-indent (text)
  10105. (let (beg end)
  10106. (setq beg (point-at-bol))
  10107. (insert text)
  10108. (setq end (point-at-eol))
  10109. (indent-region beg end)
  10110. ))
  10111. (defun web-mode-column-at-pos (pos)
  10112. (save-excursion
  10113. (goto-char pos)
  10114. (current-column)))
  10115. (defun web-mode-indentation-at-pos (pos)
  10116. (save-excursion
  10117. (goto-char pos)
  10118. (current-indentation)))
  10119. (defun web-mode-navigate (&optional pos)
  10120. "Move point to the matching opening/closing tag/block."
  10121. (interactive)
  10122. (unless pos (setq pos (point)))
  10123. (let (init)
  10124. (goto-char pos)
  10125. (setq init (point))
  10126. (when (> (current-indentation) (current-column))
  10127. (back-to-indentation))
  10128. (setq pos (point))
  10129. (cond
  10130. ((and (get-text-property pos 'block-side)
  10131. (web-mode-block-beginning)
  10132. (web-mode-block-controls-get (point)))
  10133. (web-mode-block-match))
  10134. ((member (get-text-property pos 'tag-type) '(start end))
  10135. (web-mode-tag-beginning)
  10136. (web-mode-tag-match))
  10137. (t
  10138. (goto-char init))
  10139. )
  10140. ))
  10141. (defun web-mode-block-match (&optional pos)
  10142. (unless pos (setq pos (point)))
  10143. (let (pos-ori controls control (counter 1) type (continue t) pair)
  10144. (setq pos-ori pos)
  10145. (goto-char pos)
  10146. (setq controls (web-mode-block-controls-get pos))
  10147. ;;(message "controls=%S" controls)
  10148. (cond
  10149. (controls
  10150. (setq pair (car controls))
  10151. (setq control (cdr pair))
  10152. (setq type (car pair))
  10153. (when (eq type 'inside) (setq type 'close))
  10154. (while continue
  10155. (cond
  10156. ((and (> pos-ori 1) (bobp))
  10157. (setq continue nil))
  10158. ((or (and (eq type 'open) (not (web-mode-block-next)))
  10159. (and (eq type 'close) (not (web-mode-block-previous))))
  10160. (setq continue nil)
  10161. )
  10162. ((null (setq controls (web-mode-block-controls-get (point))))
  10163. )
  10164. (t
  10165. ;;TODO : est il nécessaire de faire un reverse sur controls si on doit matcher backward
  10166. (dolist (pair controls)
  10167. (cond
  10168. ((not (string= (cdr pair) control))
  10169. )
  10170. ((eq (car pair) 'inside)
  10171. )
  10172. ((eq (car pair) type)
  10173. (setq counter (1+ counter)))
  10174. (t
  10175. (setq counter (1- counter)))
  10176. )
  10177. ) ;dolist
  10178. (when (= counter 0)
  10179. (setq continue nil))
  10180. ) ;t
  10181. ) ;cond
  10182. ) ;while
  10183. (if (= counter 0) (point) nil)
  10184. ) ;controls
  10185. (t
  10186. (goto-char pos-ori)
  10187. nil
  10188. ) ;controls = nul
  10189. ) ;conf
  10190. ))
  10191. (defun web-mode-tag-match (&optional pos)
  10192. "Move point to the matching opening/closing tag."
  10193. (interactive)
  10194. (unless pos (setq pos (point)))
  10195. (let (regexp name)
  10196. (cond
  10197. ((eq (get-text-property pos 'tag-type) 'void)
  10198. (web-mode-tag-beginning))
  10199. ((and (eq (get-text-property pos 'tag-type) 'comment)
  10200. (web-mode-looking-at-p "<!--#\\(elif\\|else\\|endif\\|if\\)" pos))
  10201. (setq regexp "<!--#\\(end\\)?if")
  10202. (if (web-mode-looking-at-p "<!--#if" pos)
  10203. (web-mode-tag-fetch-closing regexp pos)
  10204. (web-mode-tag-fetch-opening regexp pos))
  10205. )
  10206. (t
  10207. (setq name (get-text-property pos 'tag-name))
  10208. (when (string= name "_fragment_") (setq name ">"))
  10209. (setq regexp (concat "</?" name))
  10210. (when (member (get-text-property pos 'tag-type) '(start end))
  10211. (web-mode-tag-beginning)
  10212. (setq pos (point)))
  10213. (if (eq (get-text-property pos 'tag-type) 'end)
  10214. (web-mode-tag-fetch-opening regexp pos)
  10215. (web-mode-tag-fetch-closing regexp pos))
  10216. ) ;t
  10217. ) ;cond
  10218. t))
  10219. (defun web-mode-tag-fetch-opening (regexp pos)
  10220. (let ((counter 1) (n 0) (is-comment nil) (types '(start end)))
  10221. (when (eq (aref regexp 1) ?\!)
  10222. (setq types '(comment)
  10223. is-comment t))
  10224. (goto-char pos)
  10225. (while (and (> counter 0) (re-search-backward regexp nil t))
  10226. (when (and (get-text-property (point) 'tag-beg)
  10227. (member (get-text-property (point) 'tag-type) types))
  10228. (setq n (1+ n))
  10229. (cond
  10230. ((and is-comment
  10231. (eq (aref (match-string-no-properties 0) 5) ?e))
  10232. (setq counter (1+ counter)))
  10233. (is-comment
  10234. (setq counter (1- counter)))
  10235. ((eq (get-text-property (point) 'tag-type) 'end)
  10236. (setq counter (1+ counter)))
  10237. (t
  10238. (setq counter (1- counter))
  10239. )
  10240. )
  10241. )
  10242. )
  10243. (if (= n 0) (goto-char pos))
  10244. ))
  10245. (defun web-mode-tag-fetch-closing (regexp pos)
  10246. (let ((counter 1) (is-comment nil) (n 0))
  10247. (when (eq (aref regexp 1) ?\!)
  10248. (setq is-comment t))
  10249. (goto-char pos)
  10250. (web-mode-tag-end)
  10251. (while (and (> counter 0) (re-search-forward regexp nil t))
  10252. (when (get-text-property (match-beginning 0) 'tag-beg)
  10253. (setq n (1+ n))
  10254. (cond
  10255. ((and is-comment
  10256. (eq (aref (match-string-no-properties 0) 5) ?e))
  10257. (setq counter (1- counter)))
  10258. (is-comment
  10259. (setq counter (1+ counter)))
  10260. ((eq (get-text-property (point) 'tag-type) 'end)
  10261. (setq counter (1- counter)))
  10262. (t
  10263. (setq counter (1+ counter)))
  10264. )
  10265. ) ;when
  10266. ) ;while
  10267. (if (> n 0)
  10268. (web-mode-tag-beginning)
  10269. (goto-char pos))
  10270. ))
  10271. (defun web-mode-element-tag-name (&optional pos)
  10272. (unless pos (setq pos (point)))
  10273. (save-excursion
  10274. (goto-char pos)
  10275. (if (and (web-mode-tag-beginning)
  10276. (looking-at web-mode-tag-regexp))
  10277. (match-string-no-properties 1)
  10278. nil)))
  10279. (defun web-mode-element-close ()
  10280. "Close html element."
  10281. (interactive)
  10282. (let (jmp epp ins tag)
  10283. (if (and (eq (char-before) ?\>)
  10284. (web-mode-element-is-void (get-text-property (1- (point)) 'tag-name)))
  10285. (unless (eq (char-before (1- (point))) ?\/)
  10286. (backward-char)
  10287. (insert "/")
  10288. (forward-char))
  10289. (setq epp (web-mode-element-parent-position)))
  10290. ;;(message "epp=%S" epp)
  10291. (when epp
  10292. (setq tag (get-text-property epp 'tag-name))
  10293. (setq tag (web-mode-element-tag-name epp))
  10294. ;;(message "tag=%S %c" tag (char-before))
  10295. (cond
  10296. ((or (null tag) (web-mode-element-is-void tag))
  10297. (setq epp nil))
  10298. ((looking-back "</" (point-min))
  10299. (setq ins tag))
  10300. ((looking-back "<" (point-min))
  10301. (setq ins (concat "/" tag)))
  10302. (t
  10303. ;;auto-close-style = 2
  10304. ;;(message "%S %c" (point) (char-after))
  10305. (when (and (looking-at-p "[[:alpha:]]") (> (length tag) 4))
  10306. (dolist (elt '("div" "span" "strong" "pre" "li"))
  10307. (when (and (string-match-p (concat "^" elt) tag) (not (string= tag elt)))
  10308. (setq tag elt)
  10309. (put-text-property epp (point) 'tag-name tag))
  10310. )
  10311. ) ;when
  10312. (if (web-mode-element-is-void (get-text-property (point) 'tag-name))
  10313. (setq ins nil
  10314. epp nil)
  10315. (setq ins (concat "</" tag)))
  10316. )
  10317. ) ;cond
  10318. (when ins
  10319. (unless (looking-at-p "[ ]*>")
  10320. (setq ins (concat ins ">")))
  10321. (insert ins)
  10322. (setq tag (downcase tag))
  10323. (save-excursion
  10324. (search-backward "<")
  10325. (setq jmp (and (eq (char-before) ?\>)
  10326. (string= (get-text-property (1- (point)) 'tag-name) tag)))
  10327. (if jmp (setq jmp (point)))
  10328. ) ;save-excursion
  10329. (if jmp (goto-char jmp))
  10330. ) ;when not ins
  10331. ) ;when epp
  10332. epp))
  10333. (defun web-mode-detect-content-type ()
  10334. (cond
  10335. ((and (string= web-mode-engine "none")
  10336. (< (point) 16)
  10337. (eq (char-after 1) ?\#)
  10338. (string-match-p "php" (buffer-substring-no-properties
  10339. (line-beginning-position)
  10340. (line-end-position))))
  10341. (web-mode-set-engine "php"))
  10342. ((and (string= web-mode-content-type "javascript")
  10343. (< (point) web-mode-chunk-length)
  10344. (eq (char-after (point-min)) ?\/)
  10345. (string-match-p "@jsx" (buffer-substring-no-properties
  10346. (line-beginning-position)
  10347. (line-end-position))))
  10348. (web-mode-set-content-type "jsx"))
  10349. ))
  10350. (defun web-mode-auto-complete ()
  10351. "Autocomple at point."
  10352. (interactive)
  10353. (let ((pos (point))
  10354. (char (char-before))
  10355. (chunk (buffer-substring-no-properties (- (point) 2) (point)))
  10356. (expanders nil) (tag nil)
  10357. (auto-closed nil)
  10358. (auto-expanded nil)
  10359. (auto-paired nil)
  10360. (auto-quoted nil))
  10361. ;;-- auto-closing
  10362. (when web-mode-enable-auto-closing
  10363. (cond
  10364. ((and (= web-mode-auto-close-style 3)
  10365. (eq char ?\<))
  10366. (insert "/>")
  10367. (backward-char 2)
  10368. (setq auto-closed t))
  10369. ((and (= web-mode-auto-close-style 3)
  10370. (eq char ?\>)
  10371. (looking-at-p "/>"))
  10372. (save-excursion
  10373. (re-search-backward web-mode-start-tag-regexp)
  10374. (setq tag (match-string-no-properties 1)))
  10375. (insert "<")
  10376. (forward-char)
  10377. (insert tag)
  10378. (setq auto-closed t))
  10379. ((and (>= pos 4)
  10380. (or (string= "</" chunk)
  10381. ;;(progn (message "%c" char) nil)
  10382. (and (= web-mode-auto-close-style 2)
  10383. (or (string= web-mode-content-type "jsx")
  10384. (not (get-text-property pos 'part-side)))
  10385. (string-match-p "[[:alnum:]'\"]>" chunk)))
  10386. (not (get-text-property (- pos 2) 'block-side))
  10387. (web-mode-element-close))
  10388. (setq auto-closed t))
  10389. ) ;cond
  10390. ) ;when
  10391. ;;-- auto-pairing
  10392. (when (and web-mode-enable-auto-pairing
  10393. (>= pos 4)
  10394. (not auto-closed))
  10395. (let ((i 0) expr after pos-end (l (length web-mode-auto-pairs)))
  10396. (setq pos-end (if (> (+ pos 32) (line-end-position))
  10397. (line-end-position)
  10398. (+ pos 10)))
  10399. (setq chunk (buffer-substring-no-properties (- pos 3) pos)
  10400. after (buffer-substring-no-properties pos pos-end))
  10401. (while (and (< i l) (not auto-paired))
  10402. (setq expr (elt web-mode-auto-pairs i)
  10403. i (1+ i))
  10404. ;;(message "chunk=%S expr=%S after=%S" chunk expr after)
  10405. (when (and (string= (car expr) chunk)
  10406. (not (string-match-p (regexp-quote (cdr expr)) after)))
  10407. (setq auto-paired t)
  10408. (insert (cdr expr))
  10409. (if (string-match-p "|" (cdr expr))
  10410. (progn
  10411. (search-backward "|")
  10412. (delete-char 1))
  10413. (goto-char pos))
  10414. ) ;when
  10415. ) ;while
  10416. ) ;let
  10417. )
  10418. ;;-- auto-expanding
  10419. (when (and web-mode-enable-auto-expanding
  10420. (not auto-closed)
  10421. (not auto-paired)
  10422. (eq char ?\/)
  10423. (looking-back "\\(^\\|[[:punct:][:space:]>]\\)./" (point-min))
  10424. (or (web-mode-jsx-is-html (1- pos))
  10425. (and (not (get-text-property (1- pos) 'tag-type))
  10426. (not (get-text-property (1- pos) 'part-side))))
  10427. (not (get-text-property (1- pos) 'block-side))
  10428. )
  10429. (setq expanders (append web-mode-expanders web-mode-extra-expanders))
  10430. (let ((i 0) pair (l (length expanders)))
  10431. (setq chunk (buffer-substring-no-properties (- pos 2) pos))
  10432. ;;(message "%S" chunk)
  10433. (while (and (< i l) (not auto-expanded))
  10434. (setq pair (elt expanders i)
  10435. i (1+ i))
  10436. (when (string= (car pair) chunk)
  10437. (setq auto-expanded t)
  10438. (delete-char -2)
  10439. (insert (cdr pair))
  10440. (when (string-match-p "|" (cdr pair))
  10441. (search-backward "|")
  10442. (delete-char 1))
  10443. ) ;when
  10444. ) ;while
  10445. ) ;let
  10446. )
  10447. ;;-- auto-quoting
  10448. (when (and web-mode-enable-auto-quoting
  10449. (>= pos 4)
  10450. (not (get-text-property pos 'block-side))
  10451. (not auto-closed)
  10452. (not auto-paired)
  10453. (not auto-expanded)
  10454. (get-text-property (- pos 2) 'tag-attr))
  10455. (cond
  10456. ((and (eq char ?\=)
  10457. (not (looking-at-p "[ ]*[\"']")))
  10458. (cond ((= web-mode-auto-quote-style 2)
  10459. (insert "''"))
  10460. ((= web-mode-auto-quote-style 3)
  10461. (insert "{}"))
  10462. (t
  10463. (insert "\"\"")))
  10464. (if (looking-at-p "[ \n>]")
  10465. (backward-char)
  10466. (insert " ")
  10467. (backward-char 2)
  10468. )
  10469. (setq auto-quoted t))
  10470. ((and (eq char ?\")
  10471. (looking-back "=[ ]*\"" (point-min))
  10472. (not (looking-at-p "[ ]*[\"]")))
  10473. (insert-and-inherit "\"")
  10474. (backward-char)
  10475. (setq auto-quoted t))
  10476. ((and (eq char ?\')
  10477. (looking-back "=[ ]*'" (point-min))
  10478. (not (looking-at-p "[ ]*[']")))
  10479. (insert-and-inherit "'")
  10480. (backward-char)
  10481. (setq auto-quoted t))
  10482. ((and (eq char ?\{)
  10483. (eq (get-text-property pos 'part-side) 'jsx)
  10484. (looking-back "=[ ]*{" (point-min))
  10485. (not (looking-at-p "[ ]*[}]")))
  10486. (insert-and-inherit "}")
  10487. (backward-char)
  10488. (setq auto-quoted t))
  10489. ((and (eq char ?\")
  10490. (eq (char-after) ?\"))
  10491. (delete-char 1)
  10492. (cond
  10493. ((looking-back "=\"\"" (point-min))
  10494. (backward-char))
  10495. ((eq (char-after) ?\s)
  10496. (forward-char))
  10497. (t
  10498. (insert " "))
  10499. ) ;cond
  10500. )
  10501. ) ;cond
  10502. ) ;when
  10503. ;;--
  10504. (cond
  10505. ((or auto-closed auto-paired auto-expanded auto-quoted)
  10506. (when (and web-mode-change-end (>= (line-end-position) web-mode-change-end))
  10507. (setq web-mode-change-end (line-end-position)))
  10508. (list :auto-closed auto-closed
  10509. :auto-paired auto-paired
  10510. :auto-expanded auto-expanded
  10511. :auto-quoted auto-quoted))
  10512. (t
  10513. nil)
  10514. )
  10515. ))
  10516. (defun web-mode--command-is-self-insert-p ()
  10517. "Return non-nil if `this-command' is `self-insert-command'.
  10518. Also return non-nil if it is the command `self-insert-command' is remapped to."
  10519. (memq this-command (list 'self-insert-command
  10520. (key-binding [remap self-insert-command]))))
  10521. ;; NOTE: after-change triggered before post-command
  10522. (defun web-mode-on-after-change (beg end len)
  10523. ;;(message "after-change: pos=%d, beg=%d, end=%d, len=%d, ocmd=%S, cmd=%S" (point) beg end len this-original-command this-command)
  10524. ;;(backtrace)
  10525. (when (eq this-original-command 'yank)
  10526. (setq web-mode-fontification-off t))
  10527. (when (or (null web-mode-change-beg) (< beg web-mode-change-beg))
  10528. (setq web-mode-change-beg beg))
  10529. (when (or (null web-mode-change-end) (> end web-mode-change-end))
  10530. (setq web-mode-change-end end))
  10531. ;;(message "on-after-change: fontification-off(%S) change-beg(%S) change-end(%S)" web-mode-fontification-off web-mode-change-beg web-mode-change-end)
  10532. )
  10533. (defun web-mode-on-post-command ()
  10534. ;;(message "post-command: cmd=%S, state=%S, beg=%S, end=%S" this-command web-mode-expand-previous-state web-mode-change-beg web-mode-change-end)
  10535. (let (ctx n char)
  10536. (when (and web-mode-expand-previous-state
  10537. (not (member this-command web-mode-commands-like-expand-region)))
  10538. (when (eq this-command 'keyboard-quit)
  10539. (goto-char web-mode-expand-initial-pos))
  10540. (deactivate-mark)
  10541. (when web-mode-expand-initial-scroll
  10542. (set-window-start (selected-window) web-mode-expand-initial-scroll)
  10543. )
  10544. (setq web-mode-expand-previous-state nil
  10545. web-mode-expand-initial-pos nil
  10546. web-mode-expand-initial-scroll nil))
  10547. (when (member this-command '(yank))
  10548. (setq web-mode-fontification-off nil)
  10549. (when (and web-mode-scan-beg web-mode-scan-end global-font-lock-mode)
  10550. (save-excursion
  10551. (font-lock-fontify-region web-mode-scan-beg web-mode-scan-end))
  10552. (when web-mode-enable-auto-indentation
  10553. (indent-region web-mode-scan-beg web-mode-scan-end))
  10554. ) ;and
  10555. )
  10556. (when (and (< (point) 16) web-mode-change-beg web-mode-change-end)
  10557. (web-mode-detect-content-type))
  10558. (when (and web-mode-change-beg web-mode-change-end
  10559. web-mode-enable-engine-detection
  10560. (or (null web-mode-engine) (string= web-mode-engine "none"))
  10561. (< (point) web-mode-chunk-length)
  10562. (web-mode-detect-engine))
  10563. (web-mode-on-engine-setted)
  10564. (web-mode-buffer-fontify))
  10565. (when (> (point) 1)
  10566. (setq char (char-before)))
  10567. (cond
  10568. ((null char)
  10569. )
  10570. ((and (>= (point) 3)
  10571. (web-mode--command-is-self-insert-p)
  10572. (not (member (get-text-property (point) 'part-token) '(comment string)))
  10573. (not (eq (get-text-property (point) 'tag-type) 'comment))
  10574. )
  10575. (setq ctx (web-mode-auto-complete)))
  10576. ((and web-mode-enable-auto-opening
  10577. (member this-command '(newline electric-newline-and-maybe-indent newline-and-indent))
  10578. (or (and (not (eobp))
  10579. (eq (char-after) ?\<)
  10580. (eq (get-text-property (point) 'tag-type) 'end)
  10581. (looking-back ">\n[ \t]*" (point-min))
  10582. (setq n (length (match-string-no-properties 0)))
  10583. (eq (get-text-property (- (point) n) 'tag-type) 'start)
  10584. (string= (get-text-property (- (point) n) 'tag-name)
  10585. (get-text-property (point) 'tag-name))
  10586. )
  10587. (and (get-text-property (1- (point)) 'block-side)
  10588. (string= web-mode-engine "php")
  10589. (looking-back "<\\?php[ ]*\n" (point-min))
  10590. (looking-at-p "[ ]*\\?>"))))
  10591. (newline-and-indent)
  10592. (forward-line -1)
  10593. (indent-according-to-mode)
  10594. )
  10595. ) ;cond
  10596. (cond
  10597. ((not web-mode-enable-auto-opening)
  10598. )
  10599. ((and (member this-command '(newline electric-newline-and-maybe-indent newline-and-indent))
  10600. (get-text-property (point) 'part-side)
  10601. (eq (get-text-property (point) 'part-token) 'string))
  10602. (indent-according-to-mode)
  10603. (when (and web-mode-change-end (> web-mode-change-end (point-max)))
  10604. (message "post-command: enlarge web-mode-change-end")
  10605. (setq web-mode-change-end (point-max))
  10606. )
  10607. )
  10608. ((and (web-mode--command-is-self-insert-p)
  10609. (or (and ctx
  10610. (or (plist-get ctx :auto-closed)
  10611. (plist-get ctx :auto-expanded)))
  10612. (and (> (point) (point-min))
  10613. (get-text-property (1- (point)) 'tag-end)
  10614. (get-text-property (line-beginning-position) 'tag-beg))))
  10615. (indent-according-to-mode)
  10616. (when (and web-mode-change-end (> web-mode-change-end (point-max)))
  10617. (message "post-command: enlarge web-mode-change-end")
  10618. (setq web-mode-change-end (point-max))
  10619. )
  10620. )
  10621. ((and (web-mode--command-is-self-insert-p)
  10622. (member (get-text-property (point) 'part-side) '(javascript jsx css))
  10623. (looking-back "^[ \t]+[]})]" (point-min)))
  10624. (indent-according-to-mode)
  10625. (when (and web-mode-change-end (> web-mode-change-end (point-max)))
  10626. (message "post-command: enlarge web-mode-change-end")
  10627. (setq web-mode-change-end (point-max))
  10628. )
  10629. )
  10630. ) ; cond web-mode-enable-auto-opening
  10631. (when web-mode-enable-current-element-highlight
  10632. (web-mode-highlight-current-element))
  10633. (when (and web-mode-enable-current-column-highlight
  10634. (not (web-mode-buffer-narrowed-p)))
  10635. (web-mode-column-show))
  10636. ;;(message "post-command (%S) (%S)" web-mode-change-end web-mode-change-end)
  10637. ))
  10638. (defun web-mode-dom-xpath (&optional pos)
  10639. "Display html path."
  10640. (interactive)
  10641. (unless pos (setq pos (point)))
  10642. (save-excursion
  10643. (goto-char pos)
  10644. (let (path tag)
  10645. (while (web-mode-element-parent)
  10646. (looking-at web-mode-tag-regexp)
  10647. (setq tag (match-string-no-properties 1))
  10648. (setq path (cons tag path))
  10649. )
  10650. (message "/%s" (mapconcat 'identity path "/"))
  10651. )))
  10652. (defun web-mode-block-ends-with (regexp &optional pos)
  10653. (unless pos (setq pos (point)))
  10654. (save-excursion
  10655. (goto-char pos)
  10656. (save-match-data
  10657. (if (stringp regexp)
  10658. (and (web-mode-block-end)
  10659. (progn (backward-char) t)
  10660. (web-mode-block-skip-blank-backward)
  10661. (progn (forward-char) t)
  10662. (looking-back regexp (point-min)))
  10663. (let ((pair regexp)
  10664. (block-beg (web-mode-block-beginning-position pos))
  10665. (block-end (web-mode-block-end-position pos)))
  10666. (and (web-mode-block-end)
  10667. (web-mode-block-sb (car pair) block-beg)
  10668. (not (web-mode-sf (cdr pair) block-end)))
  10669. ) ;let
  10670. ) ;if
  10671. )))
  10672. (defun web-mode-block-token-starts-with (regexp &optional pos)
  10673. (unless pos (setq pos (point)))
  10674. (save-excursion
  10675. (and (goto-char pos)
  10676. (web-mode-block-token-beginning)
  10677. (skip-chars-forward "[\"']")
  10678. (looking-at regexp))
  10679. ))
  10680. (defun web-mode-block-starts-with (regexp &optional pos)
  10681. (unless pos (setq pos (point)))
  10682. (save-excursion
  10683. (and (web-mode-block-beginning)
  10684. (web-mode-block-skip-blank-forward)
  10685. (looking-at regexp))
  10686. ))
  10687. (defun web-mode-block-skip-blank-backward (&optional pos)
  10688. (unless pos (setq pos (point)))
  10689. (let ((continue t))
  10690. (goto-char pos)
  10691. (while continue
  10692. (if (and (get-text-property (point) 'block-side)
  10693. (not (bobp))
  10694. (or (member (char-after) '(?\s ?\n))
  10695. (member (get-text-property (point) 'block-token)
  10696. '(delimiter-beg delimiter-end comment))))
  10697. (backward-char)
  10698. (setq continue nil))
  10699. ) ;while
  10700. (point)))
  10701. (defun web-mode-block-skip-blank-forward (&optional pos props)
  10702. (unless pos (setq pos (point)))
  10703. (unless props (setq props '(delimiter-beg delimiter-end comment)))
  10704. (let ((continue t))
  10705. (goto-char pos)
  10706. (while continue
  10707. (if (and (get-text-property (point) 'block-side)
  10708. (or (member (char-after) '(?\s ?\n ?\t))
  10709. (member (get-text-property (point) 'block-token) props)))
  10710. (forward-char)
  10711. (setq continue nil))
  10712. ) ;while
  10713. (point)))
  10714. (defun web-mode-tag-attributes-sort (&optional pos)
  10715. "Sort the attributes inside the current html tag."
  10716. (interactive)
  10717. (unless pos (setq pos (point)))
  10718. (save-excursion
  10719. (let (attrs (continue t) min max tag-beg tag-end attr attr-name attr-beg attr-end indent indentation sorter ins)
  10720. (if (not (member (get-text-property pos 'tag-type) '(start void)))
  10721. nil
  10722. (setq tag-beg (web-mode-tag-beginning-position pos)
  10723. tag-end (web-mode-tag-end-position))
  10724. ;; (message "%S %S" tag-beg tag-end)
  10725. (goto-char tag-beg)
  10726. (while continue
  10727. (if (or (not (web-mode-attribute-next))
  10728. (>= (point) tag-end))
  10729. (setq continue nil)
  10730. ;;(message "attr=%S" (point))
  10731. (setq attr-beg (web-mode-attribute-beginning-position)
  10732. attr-end (1+ (web-mode-attribute-end-position)))
  10733. (when (null min)
  10734. (setq min attr-beg))
  10735. (setq max attr-end)
  10736. (goto-char attr-beg)
  10737. (setq attr (buffer-substring-no-properties attr-beg attr-end))
  10738. (if (string-match "^\\([[:alnum:]-]+\\)=" attr)
  10739. (setq attr-name (match-string-no-properties 1 attr))
  10740. (setq attr-name attr))
  10741. (setq indent (looking-back "^[ \t]*" (point-min)))
  10742. (setq attrs (append attrs (list (list attr-beg attr-end attr-name attr indent))))
  10743. ) ;if
  10744. ) ;while
  10745. ) ;if in tag
  10746. (when attrs
  10747. (setq sorter (function
  10748. (lambda (elt1 elt2)
  10749. (string< (nth 2 elt1) (nth 2 elt2))
  10750. )))
  10751. (setq attrs (sort attrs sorter))
  10752. (delete-region (1- min) max)
  10753. (setq ins "")
  10754. (dolist (elt attrs)
  10755. (if (and (nth 4 elt) (> (length ins) 1))
  10756. (setq ins (concat ins "\n"))
  10757. (setq ins (concat ins " ")))
  10758. (setq ins (concat ins (nth 3 elt)))
  10759. )
  10760. (goto-char (1- min))
  10761. (insert ins)
  10762. (web-mode-tag-beginning)
  10763. (setq min (line-beginning-position))
  10764. (web-mode-tag-end)
  10765. (setq max (line-end-position))
  10766. (indent-region min max)
  10767. )
  10768. ;;(message "attrs=%S" attrs)
  10769. )))
  10770. (defun web-mode-attribute-insert ()
  10771. "Insert an attribute inside current tag."
  10772. (interactive)
  10773. (let (attr attr-name attr-value)
  10774. (cond
  10775. ((not (member (get-text-property (point) 'tag-type) '(start void)))
  10776. (message "attribute-insert ** invalid context **"))
  10777. ((not (and (setq attr-name (read-from-minibuffer "Attribute name? "))
  10778. (> (length attr-name) 0)))
  10779. (message "attribute-insert ** failure **"))
  10780. (t
  10781. (setq attr (concat " " attr-name))
  10782. (when (setq attr-value (read-from-minibuffer "Attribute value? "))
  10783. (setq attr (concat attr "=\"" attr-value "\"")))
  10784. (web-mode-tag-end)
  10785. (if (looking-back "/>" (point-min))
  10786. (backward-char 2)
  10787. (backward-char))
  10788. (insert attr)
  10789. ) ;t
  10790. ) ;cond
  10791. ))
  10792. (defun web-mode-attribute-transpose (&optional pos)
  10793. "Transpose the current html attribute."
  10794. (interactive)
  10795. (unless pos (setq pos (point)))
  10796. (let (ret attr-beg attr-end next-beg next-end tag-end)
  10797. (when (and (get-text-property pos 'tag-attr)
  10798. (setq next-beg (web-mode-attribute-next-position pos))
  10799. (setq next-end (web-mode-attribute-end-position next-beg))
  10800. (setq tag-end (web-mode-tag-end-position pos))
  10801. (> tag-end next-end))
  10802. (setq attr-beg (web-mode-attribute-beginning-position pos)
  10803. attr-end (web-mode-attribute-end-position pos))
  10804. ;; (message "%S %S - %S %S" attr-beg attr-end next-beg next-end)
  10805. (transpose-regions attr-beg (1+ attr-end) next-beg (1+ next-end))
  10806. )))
  10807. (defun web-mode-attribute-select (&optional pos)
  10808. "Select the current html attribute."
  10809. (interactive)
  10810. (unless pos (setq pos (point)))
  10811. (if (null (get-text-property pos 'tag-attr))
  10812. nil
  10813. (goto-char pos)
  10814. (web-mode-attribute-beginning)
  10815. (set-mark (point))
  10816. (web-mode-attribute-end)
  10817. (exchange-point-and-mark)
  10818. (point)
  10819. ))
  10820. (defun web-mode-attribute-kill (&optional arg)
  10821. "Kill the current html attribute."
  10822. (interactive "p")
  10823. (unless arg (setq arg 1))
  10824. (while (>= arg 1)
  10825. (setq arg (1- arg))
  10826. (web-mode-attribute-select)
  10827. (when mark-active
  10828. (let ((beg (region-beginning)) (end (region-end)))
  10829. (save-excursion
  10830. (goto-char end)
  10831. (when (looking-at "[ \n\t]*")
  10832. (setq end (+ end (length (match-string-no-properties 0)))))
  10833. ) ;save-excursion
  10834. (kill-region beg end)
  10835. ) ;let
  10836. ) ;when
  10837. ) ;while
  10838. ;; Delete a potential space before the closing ">".
  10839. (when (and (looking-at ">")
  10840. (looking-back " " (point-min)))
  10841. (delete-char -1))
  10842. )
  10843. (defun web-mode-block-close (&optional pos)
  10844. "Close the first unclosed control block."
  10845. (interactive)
  10846. (unless pos (setq pos (point)))
  10847. (let ((continue t)
  10848. (h (make-hash-table :test 'equal)) ctx ctrl n closing-block)
  10849. (save-excursion
  10850. (while (and continue (web-mode-block-previous))
  10851. (when (setq ctx (web-mode-block-is-control (point)))
  10852. (setq ctrl (car ctx))
  10853. (setq n (gethash ctrl h 0))
  10854. (if (cdr ctx)
  10855. (puthash ctrl (1+ n) h)
  10856. (puthash ctrl (1- n) h))
  10857. (when (> (gethash ctrl h) 0)
  10858. (setq continue nil))
  10859. )
  10860. ) ;while
  10861. ) ;save-excursion
  10862. (when (and (null continue)
  10863. (setq closing-block (web-mode-closing-block ctrl)))
  10864. (insert closing-block)
  10865. (indent-according-to-mode))
  10866. ))
  10867. (defun web-mode-closing-block (type)
  10868. (cond
  10869. ((string= web-mode-engine "php") (concat "<?php end" type "; ?>"))
  10870. ((string= web-mode-engine "django") (concat "{% end" type " %}"))
  10871. ((string= web-mode-engine "ctemplate") (concat "{{/" type "}}"))
  10872. ((string= web-mode-engine "blade")
  10873. (if (string= type "section") (concat "@show") (concat "@end" type)))
  10874. ((string= web-mode-engine "dust") (concat "{/" type "}"))
  10875. ((string= web-mode-engine "mako") (concat "% end" type))
  10876. ((string= web-mode-engine "closure") (concat "{/" type "}"))
  10877. ((string= web-mode-engine "smarty") (concat "{/" type "}"))
  10878. ((string= web-mode-engine "expressionengine") (concat "{/" type "}"))
  10879. ((string= web-mode-engine "xoops") (concat "<{/" type "}>"))
  10880. ((string= web-mode-engine "svelte") (concat "{/" type "}"))
  10881. ((string= web-mode-engine "underscore") "<% } %>")
  10882. ((string= web-mode-engine "lsp") "<% ) %>")
  10883. ((string= web-mode-engine "erb") "<% } %>")
  10884. ((string= web-mode-engine "erb") "<% end %>")
  10885. ((string= web-mode-engine "artanis") "<% ) %>")
  10886. ((string= web-mode-engine "hero") "<% } %>")
  10887. ((string= web-mode-engine "go") "{{end}}")
  10888. ((string= web-mode-engine "velocity") "#end")
  10889. ((string= web-mode-engine "velocity") "#{end}")
  10890. ((string= web-mode-engine "template-toolkit") "[% end %]")
  10891. ((member web-mode-engine '("asp" "jsp"))
  10892. (if (string-match-p "[:.]" type) (concat "</" type ">") "<% } %>"))
  10893. (t nil)
  10894. ) ;cond
  10895. )
  10896. ;;---- POSITION ----------------------------------------------------------------
  10897. (defun web-mode-comment-beginning-position (&optional pos)
  10898. (unless pos (setq pos (point)))
  10899. (car (web-mode-comment-boundaries pos)))
  10900. (defun web-mode-comment-end-position (&optional pos)
  10901. (unless pos (setq pos (point)))
  10902. (cdr (web-mode-comment-boundaries pos)))
  10903. (defun web-mode-part-opening-paren-position (pos &optional limit)
  10904. (save-restriction
  10905. (unless limit (setq limit nil))
  10906. (goto-char pos)
  10907. (let* ((n -1)
  10908. (paren (char-after))
  10909. (pairs '((?\) . "[)(]")
  10910. (?\] . "[\]\[]")
  10911. (?\} . "[}{]")
  10912. (?\> . "[><]")))
  10913. (regexp (cdr (assoc paren pairs)))
  10914. (continue (not (null regexp)))
  10915. (counter 0))
  10916. (while (and continue (re-search-backward regexp limit t))
  10917. (cond
  10918. ((> (setq counter (1+ counter)) 500)
  10919. (message "part-opening-paren-position ** warning **")
  10920. (setq continue nil))
  10921. ((or (web-mode-is-comment-or-string)
  10922. (get-text-property (point) 'block-side))
  10923. )
  10924. ((eq (char-after) paren)
  10925. (setq n (1- n)))
  10926. (t
  10927. (setq n (1+ n))
  10928. (setq continue (not (= n 0))))
  10929. )
  10930. ) ;while
  10931. (if (= n 0) (point) nil)
  10932. )))
  10933. (defun web-mode-token-opening-paren-position (pos limit context)
  10934. (save-restriction
  10935. (unless limit (setq limit nil))
  10936. (goto-char pos)
  10937. (let* ((n -1)
  10938. (paren (char-after))
  10939. (pairs '((?\) . "[)(]")
  10940. (?\] . "[\]\[]")
  10941. (?\} . "[}{]")
  10942. (?\> . "[><]")))
  10943. (regexp (cdr (assoc paren pairs)))
  10944. (continue (not (null regexp)))
  10945. (counter 0))
  10946. (while (and continue (re-search-backward regexp limit t))
  10947. (cond
  10948. ((> (setq counter (1+ counter)) 200)
  10949. (message "token-opening-paren-position ** warning **")
  10950. (setq continue nil))
  10951. ((get-text-property (point) 'block-side)
  10952. )
  10953. ((eq (char-after) paren)
  10954. (setq n (1- n)))
  10955. (t
  10956. (setq n (1+ n))
  10957. (setq continue (not (= n 0))))
  10958. )
  10959. ) ;while
  10960. (if (= n 0) (point) nil)
  10961. )))
  10962. (defun web-mode-closing-paren-position (&optional pos limit)
  10963. (save-excursion
  10964. (unless pos (setq pos (point)))
  10965. (unless limit (setq limit nil))
  10966. (goto-char pos)
  10967. (let* ((n 0)
  10968. (block-side (and (get-text-property pos 'block-side)
  10969. (not (string= web-mode-engine "razor"))))
  10970. (paren (char-after))
  10971. (pairs '((?\( . "[)(]")
  10972. (?\[ . "[\]\[]")
  10973. (?\{ . "[}{]")
  10974. (?\< . "[><]")))
  10975. (regexp (cdr (assoc paren pairs)))
  10976. (continue (not (null regexp))))
  10977. (while (and continue (re-search-forward regexp limit t))
  10978. (cond
  10979. ((or (web-mode-is-comment-or-string (1- (point)))
  10980. (and block-side (not (get-text-property (point) 'block-side))))
  10981. ;;(message "pt=%S" (point))
  10982. )
  10983. ((eq (char-before) paren)
  10984. (setq n (1+ n)))
  10985. (t
  10986. (setq n (1- n))
  10987. (setq continue (not (= n 0)))
  10988. )
  10989. ) ;cond
  10990. ) ;while
  10991. (if (= n 0) (1- (point)) nil)
  10992. )))
  10993. (defun web-mode-closing-delimiter-position (delimiter &optional pos limit)
  10994. (unless pos (setq pos (point)))
  10995. (unless limit (setq limit nil))
  10996. (save-excursion
  10997. (goto-char pos)
  10998. (setq pos nil)
  10999. (let ((continue t))
  11000. (while (and continue (re-search-forward delimiter limit t))
  11001. (setq continue nil
  11002. pos (1- (point)))
  11003. ) ;while
  11004. pos)))
  11005. (defun web-mode-tag-match-position (&optional pos)
  11006. (unless pos (setq pos (point)))
  11007. (save-excursion
  11008. (web-mode-tag-match pos)
  11009. (if (= pos (point)) nil (point))))
  11010. (defun web-mode-tag-beginning-position (&optional pos)
  11011. (unless pos (setq pos (point)))
  11012. (let (beg end depth)
  11013. (setq depth (get-text-property pos 'jsx-depth))
  11014. (when (and depth (get-text-property pos 'tag-attr-beg))
  11015. (setq depth (get-text-property (1- pos) 'jsx-depth)))
  11016. (cond
  11017. ((null pos)
  11018. (setq end nil))
  11019. ((get-text-property pos 'tag-beg)
  11020. (setq beg pos))
  11021. ((and (> pos 1) (get-text-property (1- pos) 'tag-beg))
  11022. (setq beg (1- pos)))
  11023. ((get-text-property pos 'tag-type)
  11024. (setq beg (previous-single-property-change pos 'tag-beg))
  11025. (when beg (setq beg (1- beg)))
  11026. (cond
  11027. ((not (get-text-property beg 'tag-beg))
  11028. (setq beg nil))
  11029. ((and depth (not (eq depth (get-text-property beg 'jsx-depth))))
  11030. (let ((continue (> beg (point-min))))
  11031. (while continue
  11032. (setq beg (previous-single-property-change beg 'tag-beg))
  11033. (when beg (setq beg (1- beg)))
  11034. (cond
  11035. ((null beg)
  11036. (setq continue nil))
  11037. ((not (get-text-property beg 'tag-beg))
  11038. (setq continue nil
  11039. beg nil))
  11040. ((eq depth (get-text-property beg 'jsx-depth))
  11041. (setq continue nil))
  11042. ) ;cond
  11043. ) ;while
  11044. ) ;let
  11045. )
  11046. ) ;cond
  11047. )
  11048. (t
  11049. (setq beg nil))
  11050. ) ;cond
  11051. beg))
  11052. (defun web-mode-tag-end-position (&optional pos)
  11053. (unless pos (setq pos (point)))
  11054. (let (end depth)
  11055. (setq depth (get-text-property pos 'jsx-depth))
  11056. (when (and depth (get-text-property pos 'tag-attr-beg))
  11057. (setq depth (get-text-property (1- pos) 'jsx-depth)))
  11058. (cond
  11059. ((null pos)
  11060. (setq end nil))
  11061. ((get-text-property pos 'tag-end)
  11062. (setq end pos))
  11063. ((get-text-property pos 'tag-type)
  11064. (setq end (next-single-property-change pos 'tag-end))
  11065. (cond
  11066. ((not (get-text-property end 'tag-end))
  11067. (setq end nil))
  11068. ((and depth (not (eq depth (get-text-property end 'jsx-depth))))
  11069. (let ((continue (< end (point-max))))
  11070. (while continue
  11071. (setq end (1+ end))
  11072. (setq end (next-single-property-change end 'tag-end))
  11073. (cond
  11074. ((null end)
  11075. (setq continue nil))
  11076. ((not (get-text-property end 'tag-end))
  11077. (setq continue nil
  11078. end nil))
  11079. ((eq depth (get-text-property end 'jsx-depth))
  11080. (setq continue nil))
  11081. ) ;cond
  11082. ) ;while
  11083. ) ;let
  11084. )
  11085. ) ;cond
  11086. )
  11087. (t
  11088. (setq end nil))
  11089. ) ;cond
  11090. end))
  11091. ;; TODO: prendre en compte jsx-depth
  11092. (defun web-mode-tag-next-position (&optional pos limit)
  11093. (unless pos (setq pos (point)))
  11094. (unless limit (setq limit (point-max)))
  11095. (cond
  11096. ((or (>= pos (point-max)) (>= pos limit)) nil)
  11097. (t
  11098. (when (get-text-property pos 'tag-beg) (setq pos (1+ pos)))
  11099. (setq pos (next-single-property-change pos 'tag-beg))
  11100. (if (and pos (<= pos limit)) pos nil))
  11101. ))
  11102. ;; TODO: prendre en compte jsx-depth
  11103. (defun web-mode-tag-previous-position (&optional pos limit)
  11104. (unless pos (setq pos (point)))
  11105. (unless limit (setq limit (point-min)))
  11106. (cond
  11107. ((or (<= pos (point-min)) (<= pos limit)) nil)
  11108. (t
  11109. (when (get-text-property pos 'tag-beg) (setq pos (1- pos)))
  11110. (web-mode-go (previous-single-property-change pos 'tag-beg) -1))
  11111. ))
  11112. ;; TODO: prendre en compte jsx-depth
  11113. (defun web-mode-attribute-beginning-position (&optional pos)
  11114. (unless pos (setq pos (point)))
  11115. (cond
  11116. ((null (get-text-property pos 'tag-attr))
  11117. nil)
  11118. ((get-text-property pos 'tag-attr-beg)
  11119. pos)
  11120. ((and (> pos (point-min)) (get-text-property (1- pos) 'tag-attr-beg))
  11121. (1- pos))
  11122. (t
  11123. (setq pos (previous-single-property-change pos 'tag-attr-beg))
  11124. (setq pos (1- pos)))
  11125. ))
  11126. ;; TODO: retoucher en incluant un param limit et en s'inspirant de
  11127. ;; web-mode-attribute-next-position
  11128. (defun web-mode-attribute-end-position (&optional pos)
  11129. (unless pos (setq pos (point)))
  11130. (let (beg end depth flags)
  11131. ;;(message "pos=%S" pos)
  11132. (setq depth (get-text-property pos 'jsx-depth))
  11133. (cond
  11134. ((null pos)
  11135. (setq end nil))
  11136. ((get-text-property pos 'tag-attr-end)
  11137. (setq end pos))
  11138. ((get-text-property pos 'tag-attr)
  11139. (setq end (next-single-property-change pos 'tag-attr-end))
  11140. (when (and depth
  11141. end
  11142. (setq beg (web-mode-attribute-beginning-position end))
  11143. (setq flags (get-text-property pos 'tag-attr-beg))
  11144. (eq (logand flags 4) 4))
  11145. (setq depth (1- (get-text-property beg 'jsx-depth)))
  11146. ;;(message "%S %S" beg end)
  11147. )
  11148. (cond
  11149. ((not (get-text-property end 'tag-attr-end))
  11150. (setq end nil))
  11151. ((and depth
  11152. (eq depth (get-text-property end 'jsx-depth))
  11153. (not (eq depth (get-text-property end 'jsx-end))))
  11154. )
  11155. ((and depth (eq (1+ depth) (get-text-property end 'jsx-depth)))
  11156. )
  11157. ((and depth (not (eq (1+ depth) (get-text-property end 'jsx-depth))))
  11158. (let ((continue (< end (point-max))))
  11159. (while continue
  11160. (setq end (1+ end))
  11161. (setq end (next-single-property-change end 'tag-attr-end))
  11162. (cond
  11163. ((null end)
  11164. (setq continue nil))
  11165. ((not (get-text-property end 'tag-attr-end))
  11166. (setq continue nil
  11167. end nil))
  11168. ((eq (1+ depth) (get-text-property end 'jsx-depth))
  11169. (setq continue nil))
  11170. ) ;cond
  11171. ) ;while
  11172. ) ;let
  11173. )
  11174. ) ;cond
  11175. )
  11176. (t
  11177. (setq end nil))
  11178. ) ;cond
  11179. end))
  11180. ;; attention si pos est au debut d'un spread attributes, cela
  11181. ;; risque de poser pb
  11182. (defun web-mode-attribute-next-position (&optional pos limit)
  11183. (unless pos (setq pos (point)))
  11184. (unless limit (setq limit (point-max)))
  11185. (let (continue depth)
  11186. (when (get-text-property pos 'tag-attr-beg)
  11187. (setq pos (1+ pos)))
  11188. (if (< pos limit)
  11189. (setq continue t
  11190. depth (get-text-property pos 'jsx-depth))
  11191. (setq continue nil
  11192. pos nil))
  11193. (while continue
  11194. (setq pos (next-single-property-change pos 'tag-attr-beg))
  11195. (cond
  11196. ((null pos)
  11197. (setq continue nil))
  11198. ((>= pos limit)
  11199. (setq continue nil
  11200. pos nil))
  11201. ((null depth)
  11202. (setq continue nil))
  11203. ((and (eq (get-text-property pos 'tag-attr-beg) 4)
  11204. (eq (1+ depth) (get-text-property pos 'jsx-depth)))
  11205. (setq continue nil))
  11206. ((eq depth (get-text-property pos 'jsx-depth))
  11207. (setq continue nil))
  11208. (t
  11209. (setq pos (1+ pos)
  11210. continue (< pos limit)))
  11211. )
  11212. ) ;while
  11213. pos))
  11214. (defun web-mode-attribute-previous-position (&optional pos limit)
  11215. (unless pos (setq pos (point)))
  11216. (unless limit (setq limit (point-min)))
  11217. (let (continue depth)
  11218. (cond
  11219. ((and (> pos (point-min)) (get-text-property (1- pos) 'tag-attr-beg))
  11220. (setq pos (1- pos)
  11221. continue nil))
  11222. (t
  11223. (when (get-text-property pos 'tag-attr-beg)
  11224. (setq pos (1- pos)))
  11225. (if (> pos limit)
  11226. (setq continue t
  11227. depth (get-text-property pos 'jsx-depth))
  11228. (setq continue nil
  11229. pos nil))
  11230. ) ;t
  11231. ) ;cond
  11232. (while continue
  11233. (setq pos (previous-single-property-change pos 'tag-attr-beg))
  11234. (cond
  11235. ((null pos)
  11236. (setq continue nil))
  11237. ((< pos limit)
  11238. (setq continue nil
  11239. pos nil))
  11240. ;;((null depth)
  11241. ;; (setq continue nil))
  11242. ((and depth (eq depth (get-text-property pos 'jsx-depth)))
  11243. (setq pos (1- pos)
  11244. continue nil))
  11245. (depth
  11246. (setq pos nil
  11247. continue (> pos limit)))
  11248. (t
  11249. (setq pos (1- pos)
  11250. continue nil))
  11251. ) ;cond
  11252. ) ;while
  11253. pos))
  11254. ;; TODO: prendre en compte jsx-depth
  11255. (defun web-mode-element-beginning-position (&optional pos)
  11256. (unless pos (setq pos (point)))
  11257. (cond
  11258. ((null (get-text-property pos 'tag-type))
  11259. (setq pos (web-mode-element-parent-position)))
  11260. ((eq (get-text-property pos 'tag-type) 'end)
  11261. (setq pos (web-mode-tag-match-position pos))
  11262. (setq pos (if (get-text-property pos 'tag-beg) pos nil)))
  11263. ((member (get-text-property pos 'tag-type) '(start void))
  11264. (setq pos (web-mode-tag-beginning-position pos)))
  11265. (t
  11266. (setq pos nil))
  11267. ) ;cond
  11268. pos)
  11269. ;; TODO: prendre en compte jsx-depth
  11270. (defun web-mode-element-end-position (&optional pos)
  11271. (unless pos (setq pos (point)))
  11272. (cond
  11273. ((null (get-text-property pos 'tag-type))
  11274. (setq pos (web-mode-element-parent-position pos))
  11275. (when pos
  11276. (setq pos (web-mode-tag-match-position pos))
  11277. (when pos (setq pos (web-mode-tag-end-position pos)))
  11278. )
  11279. )
  11280. ((member (get-text-property pos 'tag-type) '(end void comment))
  11281. (setq pos (web-mode-tag-end-position pos))
  11282. )
  11283. ((member (get-text-property pos 'tag-type) '(start))
  11284. (setq pos (web-mode-tag-match-position pos))
  11285. (when pos (setq pos (web-mode-tag-end-position pos))))
  11286. (t
  11287. (setq pos nil))
  11288. ) ;cond
  11289. pos)
  11290. (defun web-mode-element-child-position (&optional pos)
  11291. (save-excursion
  11292. (let (child close)
  11293. (unless pos (setq pos (point)))
  11294. (goto-char pos)
  11295. (cond
  11296. ((eq (get-text-property pos 'tag-type) 'start)
  11297. (web-mode-tag-match)
  11298. (setq close (point))
  11299. (goto-char pos)
  11300. )
  11301. ((eq (get-text-property pos 'tag-type) 'void)
  11302. )
  11303. ((eq (get-text-property pos 'tag-type) 'end)
  11304. (web-mode-tag-beginning)
  11305. (setq close (point))
  11306. (web-mode-tag-match)
  11307. )
  11308. ((web-mode-element-parent-position pos)
  11309. (setq pos (point))
  11310. (web-mode-tag-match)
  11311. (setq close (point))
  11312. (goto-char pos)
  11313. )
  11314. ) ;cond
  11315. (when (and close
  11316. (web-mode-element-next)
  11317. (< (point) close))
  11318. (setq child (point))
  11319. )
  11320. child)))
  11321. (defun web-mode-element-parent-position (&optional pos)
  11322. (let (n tag-type tag-name (continue t) (tags (make-hash-table :test 'equal)))
  11323. (save-excursion
  11324. (if pos (goto-char pos))
  11325. (while (and continue (web-mode-tag-previous))
  11326. (setq pos (point)
  11327. tag-type (get-text-property pos 'tag-type)
  11328. tag-name (get-text-property pos 'tag-name)
  11329. n (gethash tag-name tags 0))
  11330. (when (member tag-type '(end start))
  11331. (if (eq tag-type 'end)
  11332. (puthash tag-name (1- n) tags)
  11333. (puthash tag-name (1+ n) tags)
  11334. (when (= n 0) (setq continue nil))
  11335. ) ;if
  11336. ) ;when
  11337. ) ;while
  11338. ) ;save-excursion
  11339. (if (null continue) pos nil)))
  11340. (defun web-mode-element-previous-position (&optional pos limit)
  11341. (unless pos (setq pos (point)))
  11342. (unless limit (setq limit (point-min)))
  11343. (save-excursion
  11344. (goto-char pos)
  11345. (let ((continue (not (bobp)))
  11346. (props '(start void comment)))
  11347. (while continue
  11348. (setq pos (web-mode-tag-previous))
  11349. (cond
  11350. ((or (null pos) (< (point) limit))
  11351. (setq continue nil
  11352. pos nil))
  11353. ((member (get-text-property (point) 'tag-type) props)
  11354. (setq continue nil))
  11355. )
  11356. ) ;while
  11357. pos)))
  11358. (defun web-mode-element-next-position (&optional pos limit)
  11359. (unless pos (setq pos (point)))
  11360. (unless limit (setq limit (point-max)))
  11361. (save-excursion
  11362. (goto-char pos)
  11363. (let ((continue (not (eobp)))
  11364. (props '(start void comment)))
  11365. (while continue
  11366. (setq pos (web-mode-tag-next))
  11367. (cond
  11368. ((or (null pos) (> (point) limit))
  11369. (setq continue nil
  11370. pos nil))
  11371. ((member (get-text-property (point) 'tag-type) props)
  11372. (setq continue nil))
  11373. )
  11374. ) ;while
  11375. ;; (message "pos=%S" pos)
  11376. pos)))
  11377. (defun web-mode-part-end-position (&optional pos)
  11378. (unless pos (setq pos (point)))
  11379. (cond
  11380. ((member web-mode-content-type web-mode-part-content-types)
  11381. (setq pos (point-max)))
  11382. ((not (get-text-property pos 'part-side))
  11383. (setq pos nil))
  11384. ((= pos (point-max))
  11385. (setq pos nil))
  11386. ((not (get-text-property (1+ pos) 'part-side))
  11387. pos)
  11388. (t
  11389. (setq pos (next-single-property-change pos 'part-side)))
  11390. ) ;cond
  11391. pos)
  11392. (defun web-mode-part-beginning-position (&optional pos)
  11393. (unless pos (setq pos (point)))
  11394. (cond
  11395. (web-mode-part-beg
  11396. (setq pos web-mode-part-beg))
  11397. ((member web-mode-content-type web-mode-part-content-types)
  11398. (setq pos (point-min)
  11399. web-mode-part-beg (point-min)))
  11400. ((not (get-text-property pos 'part-side))
  11401. (setq pos nil))
  11402. ((= pos (point-min))
  11403. (setq pos nil))
  11404. ((not (get-text-property (1- pos) 'part-side))
  11405. pos)
  11406. (t
  11407. (setq pos (previous-single-property-change pos 'part-side)))
  11408. ) ;cond
  11409. pos)
  11410. (defun web-mode-part-next-position (&optional pos)
  11411. (unless pos (setq pos (point)))
  11412. (cond
  11413. ((and (= pos (point-min)) (get-text-property pos 'part-side))
  11414. )
  11415. ((not (get-text-property pos 'part-side))
  11416. (setq pos (next-single-property-change pos 'part-side)))
  11417. ((and (setq pos (web-mode-part-end-position pos)) (>= pos (point-max)))
  11418. (setq pos nil))
  11419. ((and (setq pos (1+ pos)) (not (get-text-property pos 'part-side)))
  11420. (setq pos (next-single-property-change pos 'part-side)))
  11421. ) ;cond
  11422. pos)
  11423. (defun web-mode-block-match-position (&optional pos)
  11424. (unless pos (setq pos (point)))
  11425. (save-excursion
  11426. (web-mode-block-match pos)
  11427. (if (= pos (point)) nil (point))))
  11428. ;; type may be nil
  11429. (defun web-mode-block-control-previous-position (type &optional pos)
  11430. (unless pos (setq pos (point)))
  11431. (let ((continue t) controls)
  11432. (while continue
  11433. (setq pos (web-mode-block-previous-position pos))
  11434. (cond
  11435. ((null pos)
  11436. (setq continue nil
  11437. pos nil))
  11438. ((null type)
  11439. (setq continue nil))
  11440. ((and (setq controls (web-mode-block-controls-get pos))
  11441. (eq (car (car controls)) type))
  11442. (setq continue nil))
  11443. ) ;cond
  11444. ) ;while
  11445. pos))
  11446. (defun web-mode-inside-block-control (&optional pos)
  11447. (unless pos (setq pos (point)))
  11448. (setq pos (web-mode-block-control-previous-position nil pos))
  11449. (if (and pos (member (car (car (web-mode-block-controls-get pos))) '(open inside)))
  11450. pos
  11451. nil))
  11452. (defun web-mode-block-opening-paren-position (pos limit)
  11453. (save-excursion
  11454. (when (> limit pos)
  11455. (message "block-opening-paren-position: limit(%S) > pos(%S)" limit pos))
  11456. (goto-char pos)
  11457. (let (c
  11458. n
  11459. pt
  11460. (continue (> pos limit))
  11461. (pairs '((?\) . ?\()
  11462. (?\] . ?\[)
  11463. (?\} . ?\{)))
  11464. (h (make-hash-table :test 'equal))
  11465. (regexp "[\]\[)(}{]"))
  11466. (while (and continue (re-search-backward regexp limit t))
  11467. (cond
  11468. ((web-mode-is-comment-or-string)
  11469. )
  11470. (t
  11471. (setq c (char-after))
  11472. (cond
  11473. ((member c '(?\( ?\{ ?\[))
  11474. (setq n (gethash c h 0))
  11475. (if (= n 0)
  11476. (setq continue nil
  11477. pt (point))
  11478. (puthash c (1+ n) h)
  11479. ))
  11480. (t
  11481. (setq c (cdr (assoc c pairs)))
  11482. (setq n (gethash c h 0))
  11483. (puthash c (1- n) h))
  11484. ) ;cond
  11485. ) ;t
  11486. ) ;cond
  11487. ) ;while
  11488. pt)))
  11489. (defun web-mode-block-code-beginning-position (&optional pos)
  11490. (unless pos (setq pos (point)))
  11491. (when (and (setq pos (web-mode-block-beginning-position pos))
  11492. (eq (get-text-property pos 'block-token) 'delimiter-beg))
  11493. (setq pos (next-single-property-change pos 'block-token)))
  11494. pos)
  11495. (defun web-mode-block-beginning-position (&optional pos)
  11496. (unless pos (setq pos (point)))
  11497. (cond
  11498. ((or (and (get-text-property pos 'block-side) (= pos (point-min)))
  11499. (get-text-property pos 'block-beg))
  11500. )
  11501. ((and (> pos (point-min)) (get-text-property (1- pos) 'block-beg))
  11502. (setq pos (1- pos)))
  11503. ((get-text-property pos 'block-side)
  11504. (setq pos (previous-single-property-change pos 'block-beg))
  11505. (setq pos (if (and pos (> pos (point-min))) (1- pos) (point-min))))
  11506. (t
  11507. (setq pos nil))
  11508. ) ;cond
  11509. pos)
  11510. (defun web-mode-block-string-beginning-position (pos &optional block-beg)
  11511. (unless pos (setq pos (point)))
  11512. (unless block-beg (setq block-beg (web-mode-block-beginning-position pos)))
  11513. (let (char (ori pos) (continue (not (null pos))))
  11514. (while continue
  11515. (setq char (char-after pos))
  11516. (cond
  11517. ((< pos block-beg)
  11518. (setq continue nil
  11519. pos block-beg))
  11520. ((and (member (get-text-property pos 'block-token) '(string comment))
  11521. (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token)))
  11522. (setq pos (web-mode-block-token-beginning-position pos))
  11523. )
  11524. ((member char '(?\) ?\]))
  11525. (setq pos (web-mode-block-opening-paren-position pos block-beg))
  11526. (setq pos (1- pos))
  11527. )
  11528. ((and (> ori pos) (member char '(?\( ?\= ?\[ ?\? ?\: ?\; ?\, ?\`)))
  11529. (if (and (eq char ?\:) ; #1024
  11530. (web-mode-looking-at ":" pos))
  11531. (setq pos (1- pos))
  11532. (web-mode-looking-at ".[ \t\n]*" pos)
  11533. (setq pos (+ pos (length (match-string-no-properties 0)))
  11534. continue nil)
  11535. )
  11536. )
  11537. ((web-mode-looking-at "\\(return\\|echo\\|include\\|print\\)[ \n]" pos)
  11538. (setq pos (+ pos (length (match-string-no-properties 0)))
  11539. continue nil))
  11540. (t
  11541. (setq pos (web-mode-rsb-position pos "[\]\[}{)(=?;,`:]\\|\\(return\\|echo\\|include\\|print\\)" block-beg))
  11542. (when (not pos)
  11543. (message "block-string-beginning-position ** search failure **")
  11544. (setq continue nil
  11545. pos block-beg)))
  11546. ) ;cond
  11547. ) ;while
  11548. ;;(message "pos=%S" pos)
  11549. pos))
  11550. (defun web-mode-block-statement-beginning-position (pos block-beg is-ternary)
  11551. (unless pos (setq pos (point)))
  11552. (setq pos (1- pos))
  11553. (unless block-beg (setq block-beg (web-mode-block-beginning-position pos)))
  11554. (let (char (continue (not (null pos))))
  11555. (while continue
  11556. (setq char (char-after pos))
  11557. (cond
  11558. ((< pos block-beg)
  11559. (setq continue nil
  11560. pos block-beg))
  11561. ((and (member (get-text-property pos 'block-token) '(string comment))
  11562. (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token)))
  11563. (setq pos (web-mode-block-token-beginning-position pos)))
  11564. ((member char '(?\) ?\] ?\}))
  11565. (setq pos (web-mode-block-opening-paren-position pos block-beg))
  11566. (setq pos (1- pos)))
  11567. ((and (eq char ?\=)
  11568. (web-mode-looking-back "[<>!=]+" pos block-beg t))
  11569. (setq pos (- pos 1 (length (match-string-no-properties 0))))
  11570. ;;(setq pos (1- pos))
  11571. ;;(message "%S pos=%S" (match-string-no-properties 0) pos)
  11572. )
  11573. ((member char '(?\( ?\[ ?\{ ?\=))
  11574. (setq continue nil)
  11575. (web-mode-looking-at ".[ \t\n]*" pos)
  11576. (setq pos (+ pos (length (match-string-no-properties 0)))))
  11577. ((web-mode-looking-at "\\(return\\|echo\\|include\\|print\\)[ \n]" pos)
  11578. (setq pos (+ pos (length (match-string-no-properties 0)))
  11579. continue nil))
  11580. (t
  11581. (setq pos (web-mode-rsb-position pos "[\]\[}{)(=]\\|\\(return\\|echo\\|include\\|print\\)" block-beg))
  11582. (when (not pos)
  11583. (message "block-statement-beginning-position ** search failure **")
  11584. (setq continue nil
  11585. pos block-beg)))
  11586. ) ;cond
  11587. ) ;while
  11588. pos))
  11589. (defun web-mode-block-args-beginning-position (pos &optional block-beg)
  11590. (unless pos (setq pos (point)))
  11591. (setq pos (1- pos)) ;#512
  11592. (unless block-beg (setq block-beg (web-mode-block-beginning-position pos)))
  11593. (let (char (continue (not (null pos))))
  11594. (while continue
  11595. (setq char (char-after pos))
  11596. (cond
  11597. ((< pos block-beg)
  11598. (message "block-args-beginning-position ** failure **")
  11599. (setq continue nil
  11600. pos block-beg))
  11601. ((and (member (get-text-property pos 'block-token) '(string comment))
  11602. (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token)))
  11603. (setq pos (web-mode-block-token-beginning-position pos)))
  11604. ((member char '(?\) ?\] ?\}))
  11605. (setq pos (web-mode-block-opening-paren-position pos block-beg))
  11606. (setq pos (1- pos)))
  11607. ((member char '(?\( ?\[ ?\{))
  11608. (setq continue nil)
  11609. (web-mode-looking-at ".[ \t\n]*" pos)
  11610. (setq pos (+ pos (length (match-string-no-properties 0)))))
  11611. ((and (string= web-mode-engine "php")
  11612. (web-mode-looking-at "\\(extends\\|implements\\)[ \n]" pos))
  11613. (setq pos (+ pos (length (match-string-no-properties 0)))
  11614. continue nil))
  11615. (t
  11616. (setq pos (web-mode-rsb-position pos "[\]\[}{)(]\\|\\(extends\\|implements\\)" block-beg))
  11617. (when (not pos)
  11618. (message "block-args-beginning-position ** search failure **")
  11619. (setq pos block-beg
  11620. continue nil))
  11621. ) ;t
  11622. ) ;cond
  11623. ) ;while
  11624. pos))
  11625. (defun web-mode-block-calls-beginning-position (pos &optional block-beg)
  11626. (unless pos (setq pos (point)))
  11627. (unless block-beg (setq block-beg (web-mode-block-beginning-position pos)))
  11628. (let (char (continue (not (null pos))))
  11629. (while continue
  11630. (setq char (char-after pos))
  11631. (cond
  11632. ((< pos block-beg)
  11633. (message "block-calls-beginning-position ** failure **")
  11634. (setq continue nil
  11635. pos block-beg))
  11636. ((and (member (get-text-property pos 'block-token) '(string comment))
  11637. (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token)))
  11638. (setq pos (web-mode-block-token-beginning-position pos)))
  11639. ((member char '(?\) ?\]))
  11640. (setq pos (web-mode-block-opening-paren-position pos block-beg))
  11641. (setq pos (1- pos)))
  11642. ((member char '(?\( ?\[ ?\{ ?\} ?\= ?\? ?\: ?\; ?\,))
  11643. (web-mode-looking-at ".[ \t\n]*" pos)
  11644. (setq pos (+ pos (length (match-string-no-properties 0)))
  11645. continue nil))
  11646. ((web-mode-looking-at "\\(return\\|else\\)[ \n]" pos)
  11647. (setq pos (+ pos (length (match-string-no-properties 0)))
  11648. continue nil))
  11649. (t
  11650. (setq pos (web-mode-rsb-position pos "[\]\[}{)(=?:;,]\\|\\(return\\|else\\)" block-beg))
  11651. (when (not pos)
  11652. (message "block-calls-beginning-position ** search failure **")
  11653. (setq pos block-beg
  11654. continue nil))
  11655. ) ;t
  11656. ) ;cond
  11657. ) ;while
  11658. pos))
  11659. (defun web-mode-javascript-string-beginning-position (pos &optional reg-beg)
  11660. (unless pos (setq pos (point)))
  11661. (let ((char nil)
  11662. (blockside (get-text-property pos 'block-side))
  11663. (i 0)
  11664. (continue (not (null pos))))
  11665. (unless reg-beg
  11666. (if blockside
  11667. (setq reg-beg (web-mode-block-beginning-position pos))
  11668. (setq reg-beg (web-mode-part-beginning-position pos)))
  11669. )
  11670. (while continue
  11671. (setq char (char-after pos))
  11672. (cond
  11673. ((> (setq i (1+ i)) 20000)
  11674. (message "javascript-string-beginning-position ** warning (%S) **" pos)
  11675. (setq continue nil
  11676. pos nil))
  11677. ((null pos)
  11678. (message "javascript-string-beginning-position ** invalid pos **")
  11679. (setq continue nil))
  11680. ((< pos reg-beg)
  11681. (message "javascript-string-beginning-position ** failure **")
  11682. (setq continue nil
  11683. pos reg-beg))
  11684. ((and blockside
  11685. (member (get-text-property pos 'block-token) '(string comment))
  11686. (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token)))
  11687. (setq pos (web-mode-block-token-beginning-position pos)))
  11688. ((and (not blockside)
  11689. (member (get-text-property pos 'part-token) '(string comment))
  11690. (eq (get-text-property pos 'part-token) (get-text-property (1- pos) 'part-token)))
  11691. (setq pos (web-mode-part-token-beginning-position pos)))
  11692. ((and (not blockside)
  11693. (get-text-property pos 'block-side))
  11694. (when (setq pos (web-mode-block-beginning-position pos))
  11695. (setq pos (1- pos))))
  11696. ((member char '(?\) ?\] ?\}))
  11697. (setq pos (web-mode-part-opening-paren-position pos reg-beg))
  11698. (setq pos (1- pos)))
  11699. ((member char '(?\( ?\{ ?\[ ?\= ?\? ?\: ?\; ?\, ?\& ?\|))
  11700. (setq continue nil)
  11701. (web-mode-looking-at ".[ \t\n]*" pos)
  11702. (setq pos (+ pos (length (match-string-no-properties 0)))))
  11703. ((web-mode-looking-at "\\(return\\)[ \n]" pos)
  11704. (setq pos (+ pos (length (match-string-no-properties 0)))
  11705. continue nil))
  11706. (t
  11707. (setq pos (web-mode-rsb-position pos "[\]\[}{)(=?:;,&|]\\|\\(return\\)" reg-beg))
  11708. (when (not pos)
  11709. (message "javascript-string-beginning-position ** search failure **")
  11710. (setq continue nil
  11711. pos reg-beg)))
  11712. ) ;cond
  11713. ) ;while
  11714. ;;(message "js-statement-beg:%S" pos)
  11715. pos))
  11716. ;; TODO: reg-beg : jsx-beg
  11717. ;; TODO: skipper les expr dont la depth est superieure
  11718. ;; NOTE: blockside is useful for ejs
  11719. (defun web-mode-javascript-statement-beginning-position (pos reg-beg is-ternary)
  11720. (unless pos (setq pos (point)))
  11721. (setq pos (1- pos))
  11722. (let ((char nil)
  11723. (blockside (get-text-property pos 'block-side))
  11724. (i 0)
  11725. (is-jsx (string= web-mode-content-type "jsx"))
  11726. (depth-o nil) (depth-l nil)
  11727. (continue (not (null pos)))
  11728. (regexp "[\]\[}{)(=:]\\|\\(return\\)"))
  11729. (when is-ternary
  11730. (setq regexp (concat regexp "\\|[><]")))
  11731. (setq depth-o (get-text-property pos 'jsx-depth))
  11732. (unless reg-beg
  11733. (cond
  11734. (blockside
  11735. (setq reg-beg (web-mode-block-beginning-position pos)))
  11736. (is-jsx
  11737. (setq reg-beg (web-mode-jsx-depth-beginning-position pos)))
  11738. (t
  11739. (setq reg-beg (web-mode-part-beginning-position pos)))
  11740. ) ;cond
  11741. ) ;unless
  11742. (while continue
  11743. (setq char (char-after pos))
  11744. (cond
  11745. ((> (setq i (1+ i)) 20000)
  11746. (message "javascript-statement-beginning-position ** warning (%S) **" pos)
  11747. (setq continue nil
  11748. pos nil))
  11749. ((null pos)
  11750. (message "javascript-statement-beginning-position ** invalid pos **")
  11751. (setq continue nil))
  11752. ((< pos reg-beg)
  11753. (when (not is-jsx)
  11754. (message "javascript-statement-beginning-position ** failure **"))
  11755. (setq continue nil
  11756. pos reg-beg))
  11757. ((and is-jsx
  11758. (progn (setq depth-l (get-text-property pos 'jsx-depth)) t)
  11759. (not (eq depth-l depth-o)))
  11760. ;;(message "%S > depth-o(%S) depth-l(%S)" pos depth-o depth-l)
  11761. (setq pos (previous-single-property-change pos 'jsx-depth))
  11762. (setq pos (1- pos))
  11763. ;;(message "--> %S %S" pos (get-text-property pos 'jsx-depth))
  11764. )
  11765. ((and blockside
  11766. (member (get-text-property pos 'block-token) '(string comment))
  11767. (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token)))
  11768. (setq pos (web-mode-block-token-beginning-position pos)))
  11769. ((and (not blockside)
  11770. (member (get-text-property pos 'part-token) '(string comment))
  11771. (eq (get-text-property pos 'part-token) (get-text-property (1- pos) 'part-token)))
  11772. (setq pos (web-mode-part-token-beginning-position pos)))
  11773. ((and (not blockside)
  11774. (get-text-property pos 'block-side))
  11775. (when (setq pos (web-mode-block-beginning-position pos))
  11776. (setq pos (1- pos))))
  11777. ((member char '(?\) ?\] ?\}))
  11778. (setq pos (web-mode-part-opening-paren-position pos reg-beg))
  11779. (setq pos (1- pos)))
  11780. ((and (eq char ?\=)
  11781. (web-mode-looking-back "[<>!=]+" pos reg-beg t))
  11782. (setq pos (- pos 1 (length (match-string-no-properties 0)))))
  11783. ((member char '(?\( ?\{ ?\[ ?\= ?\< ?\>))
  11784. (web-mode-looking-at ".[ \t\n]*" pos)
  11785. (setq continue nil
  11786. pos (+ pos (length (match-string-no-properties 0)))))
  11787. ((web-mode-looking-at "\\(return\\)[ \n]" pos)
  11788. (setq continue nil
  11789. pos (+ pos (length (match-string-no-properties 0)))))
  11790. ((and (eq char ?\:)
  11791. (web-mode-looking-back "[{,][ \t\n]*[[:alnum:]_]+[ ]*" pos))
  11792. (web-mode-looking-at ".[ \t\n]*" pos)
  11793. (setq continue nil
  11794. pos (+ pos (length (match-string-no-properties 0)))))
  11795. (t
  11796. (setq pos (web-mode-rsb-position pos regexp reg-beg))
  11797. (when (not pos)
  11798. (cond
  11799. (is-jsx
  11800. (when (web-mode-looking-at "[ \n]*" reg-beg)
  11801. (setq pos (+ reg-beg (length (match-string-no-properties 0)))))
  11802. (setq continue nil))
  11803. (t
  11804. (message "javascript-statement-beginning-position ** search failure **")
  11805. (setq continue nil
  11806. pos reg-beg))
  11807. ) ;cond
  11808. )
  11809. ) ;t
  11810. ) ;cond
  11811. ) ;while
  11812. ;;(message "%S -------" pos)
  11813. pos))
  11814. (defun web-mode-javascript-args-beginning-position (pos &optional reg-beg)
  11815. (unless pos (setq pos (point)))
  11816. (setq pos (1- pos))
  11817. (let ((char nil)
  11818. (blockside (get-text-property pos 'block-side))
  11819. (i 0)
  11820. (continue (not (null pos))))
  11821. (unless reg-beg
  11822. (if blockside
  11823. (setq reg-beg (web-mode-block-beginning-position pos))
  11824. (setq reg-beg (web-mode-part-beginning-position pos)))
  11825. )
  11826. (while continue
  11827. (setq char (char-after pos))
  11828. ;;(message "pos(%S) char(%c)" pos char)
  11829. (cond
  11830. ((> (setq i (1+ i)) 20000)
  11831. (message "javascript-args-beginning-position ** warning (%S) **" pos)
  11832. (setq continue nil
  11833. pos nil))
  11834. ((null pos)
  11835. (message "javascript-args-beginning-position ** invalid pos **")
  11836. (setq continue nil))
  11837. ((< pos reg-beg)
  11838. (message "javascript-args-beginning-position ** failure(position) **")
  11839. (setq continue nil
  11840. pos reg-beg))
  11841. ((and blockside
  11842. (member (get-text-property pos 'block-token) '(string comment))
  11843. (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token)))
  11844. (setq pos (web-mode-block-token-beginning-position pos)))
  11845. ((and (not blockside)
  11846. (member (get-text-property pos 'part-token) '(string comment))
  11847. (eq (get-text-property pos 'part-token) (get-text-property (1- pos) 'part-token)))
  11848. (setq pos (web-mode-part-token-beginning-position pos)))
  11849. ((and (not blockside)
  11850. (get-text-property pos 'block-side))
  11851. (when (setq pos (web-mode-block-beginning-position pos))
  11852. (setq pos (1- pos)))
  11853. )
  11854. ((member char '(?\) ?\] ?\}))
  11855. (when (setq pos (web-mode-part-opening-paren-position pos reg-beg))
  11856. (setq pos (1- pos))))
  11857. ((member char '(?\( ?\[ ?\{))
  11858. (web-mode-looking-at ".[ ]*" pos)
  11859. (setq pos (+ pos (length (match-string-no-properties 0)))
  11860. continue nil)
  11861. )
  11862. ((web-mode-looking-at "\\(var\\|let\\|return\\|const\\)[ \n]" pos)
  11863. (setq pos (+ pos (length (match-string-no-properties 0)))
  11864. continue nil))
  11865. (t
  11866. (setq pos (web-mode-rsb-position pos "[\]\[}{)(]\\|\\(var\\|let\\|return\\|const\\)" reg-beg))
  11867. (when (not pos)
  11868. (message "javascript-args-beginning-position ** search failure **")
  11869. (setq continue nil
  11870. pos reg-beg)))
  11871. ) ;cond
  11872. ) ;while
  11873. ;;(message "=%S" pos)
  11874. pos))
  11875. (defun web-mode-javascript-calls-beginning-position (pos &optional reg-beg)
  11876. (unless pos (setq pos (point)))
  11877. ;;(message "pos=%S" pos)
  11878. (let ((char nil)
  11879. (dot-pos nil)
  11880. (blockside (get-text-property pos 'block-side))
  11881. (i 0)
  11882. (continue (not (null pos))))
  11883. (unless reg-beg
  11884. (setq reg-beg (if blockside
  11885. (web-mode-block-beginning-position pos)
  11886. (web-mode-part-beginning-position pos))))
  11887. (while continue
  11888. (setq char (char-after pos))
  11889. ;;(message "%S| %S=%c" reg-beg pos char)
  11890. (cond
  11891. ((> (setq i (1+ i)) 20000)
  11892. (message "javascript-calls-beginning-position ** warning (%S) **" pos)
  11893. (setq continue nil
  11894. pos nil))
  11895. ((null pos)
  11896. (message "javascript-calls-beginning-position ** invalid pos **")
  11897. (setq continue nil))
  11898. ((< pos reg-beg)
  11899. (setq continue nil
  11900. pos reg-beg))
  11901. ((and blockside
  11902. (member (get-text-property pos 'block-token) '(string comment))
  11903. (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token)))
  11904. (setq pos (web-mode-block-token-beginning-position pos)))
  11905. ((and (not blockside)
  11906. (member (get-text-property pos 'part-token) '(string comment))
  11907. (eq (get-text-property pos 'part-token) (get-text-property (1- pos) 'part-token)))
  11908. (setq pos (web-mode-part-token-beginning-position pos)))
  11909. ((and (not blockside)
  11910. (get-text-property pos 'block-side))
  11911. (when (setq pos (web-mode-block-beginning-position pos))
  11912. (setq pos (1- pos))))
  11913. ((and (member char '(?\.)) (> i 1))
  11914. (setq dot-pos pos
  11915. pos (1- pos)))
  11916. ((member char '(?\) ?\]))
  11917. (when (setq pos (web-mode-part-opening-paren-position pos reg-beg))
  11918. (setq pos (1- pos)))
  11919. )
  11920. ((member char '(?\( ?\{ ?\} ?\[ ?\= ?\? ?\: ?\; ?\, ?\& ?\| ?\>))
  11921. (web-mode-looking-at ".[ \t\n]*" pos)
  11922. (setq pos (+ pos (length (match-string-no-properties 0)))
  11923. continue nil))
  11924. ((web-mode-looking-at "\\(return\\|else\\|const\\)[ \n]" pos)
  11925. (setq pos (+ pos (length (match-string-no-properties 0)))
  11926. continue nil))
  11927. (t
  11928. (setq pos (web-mode-rsb-position pos "[\]\[}{)(=?:;,&|>.]\\|\\(return\\|else\\|const\\)" reg-beg))
  11929. (when (not pos)
  11930. (message "javascript-calls-beginning-position ** search failure **")
  11931. (setq pos reg-beg
  11932. continue nil))
  11933. ) ;t
  11934. ) ;cond
  11935. ) ;while
  11936. ;;(message "pos=%S dot-pos=%S" pos dot-pos)
  11937. (if (null pos) pos (cons pos dot-pos))
  11938. ))
  11939. (defun web-mode-part-token-beginning-position (&optional pos)
  11940. (unless pos (setq pos (point)))
  11941. (cond
  11942. ((not (get-text-property pos 'part-token))
  11943. nil)
  11944. ((or (= pos (point-min))
  11945. (and (> pos (point-min))
  11946. (not (get-text-property (1- pos) 'part-token))))
  11947. pos)
  11948. (t
  11949. (setq pos (previous-single-property-change pos 'part-token))
  11950. (if (and pos (> pos (point-min))) pos (point-min)))
  11951. ))
  11952. (defun web-mode-part-token-end-position (&optional pos)
  11953. (unless pos (setq pos (point)))
  11954. (cond
  11955. ((not (get-text-property pos 'part-token))
  11956. nil)
  11957. ((or (= pos (point-max))
  11958. (not (get-text-property (1+ pos) 'part-token)))
  11959. pos)
  11960. (t
  11961. (1- (next-single-property-change pos 'part-token)))
  11962. ))
  11963. (defun web-mode-block-token-beginning-position (&optional pos)
  11964. (unless pos (setq pos (point)))
  11965. (cond
  11966. ((not (get-text-property pos 'block-token))
  11967. nil)
  11968. ((or (= pos (point-min))
  11969. (and (> pos (point-min))
  11970. (not (get-text-property (1- pos) 'block-token))))
  11971. pos)
  11972. (t
  11973. (setq pos (previous-single-property-change pos 'block-token))
  11974. (if (and pos (> pos (point-min))) pos (point-min)))
  11975. ))
  11976. (defun web-mode-block-token-end-position (&optional pos)
  11977. (unless pos (setq pos (point)))
  11978. (cond
  11979. ((not (get-text-property pos 'block-token))
  11980. nil)
  11981. ((or (= pos (point-max))
  11982. (not (get-text-property (1+ pos) 'block-token)))
  11983. pos)
  11984. (t
  11985. (1- (next-single-property-change pos 'block-token)))
  11986. ))
  11987. (defun web-mode-block-code-end-position (&optional pos)
  11988. (unless pos (setq pos (point)))
  11989. (setq pos (web-mode-block-end-position pos))
  11990. (cond
  11991. ((not pos)
  11992. nil)
  11993. ((and (eq (get-text-property pos 'block-token) 'delimiter-end)
  11994. (eq (get-text-property (1- pos) 'block-token) 'delimiter-end))
  11995. (previous-single-property-change pos 'block-token))
  11996. ((= pos (1- (point-max))) ;; TODO: comparer plutot avec line-end-position
  11997. (point-max))
  11998. (t
  11999. pos)
  12000. ))
  12001. (defun web-mode-block-end-position (&optional pos)
  12002. (unless pos (setq pos (point)))
  12003. (cond
  12004. ((get-text-property pos 'block-end)
  12005. pos)
  12006. ((get-text-property pos 'block-side)
  12007. (or (next-single-property-change pos 'block-end)
  12008. (point-max)))
  12009. (t
  12010. nil)
  12011. ))
  12012. (defun web-mode-block-previous-position (&optional pos)
  12013. (unless pos (setq pos (point)))
  12014. (cond
  12015. ((= pos (point-min))
  12016. (setq pos nil))
  12017. ((get-text-property pos 'block-side)
  12018. (setq pos (web-mode-block-beginning-position pos))
  12019. (cond
  12020. ((or (null pos) (= pos (point-min)))
  12021. (setq pos nil)
  12022. )
  12023. ((and (setq pos (previous-single-property-change pos 'block-beg))
  12024. (> pos (point-min)))
  12025. (setq pos (1- pos))
  12026. )
  12027. )
  12028. ) ;block-side
  12029. ((get-text-property (1- pos) 'block-side)
  12030. (setq pos (web-mode-block-beginning-position (1- pos)))
  12031. )
  12032. (t
  12033. (setq pos (previous-single-property-change pos 'block-side))
  12034. (cond
  12035. ((and (null pos) (get-text-property (point-min) 'block-beg))
  12036. (setq pos (point-min)))
  12037. ((and pos (> pos (point-min)))
  12038. (setq pos (web-mode-block-beginning-position (1- pos))))
  12039. )
  12040. )
  12041. ) ;conf
  12042. pos)
  12043. (defun web-mode-block-next-position (&optional pos limit)
  12044. (unless pos (setq pos (point)))
  12045. (unless limit (setq limit (point-max)))
  12046. (cond
  12047. ((and (get-text-property pos 'block-side)
  12048. (setq pos (web-mode-block-end-position pos))
  12049. (< pos (point-max))
  12050. (setq pos (1+ pos)))
  12051. (unless (get-text-property pos 'block-beg)
  12052. (setq pos (next-single-property-change pos 'block-side)))
  12053. )
  12054. (t
  12055. (setq pos (next-single-property-change pos 'block-side)))
  12056. ) ;cond
  12057. (if (and pos (<= pos limit)) pos nil))
  12058. (defun web-mode-is-css-string (pos)
  12059. (let (beg)
  12060. (cond
  12061. ((and (setq beg (web-mode-part-token-beginning-position pos))
  12062. (web-mode-looking-at-p "`" beg)
  12063. (web-mode-looking-back "\\(styled[[:alnum:].]+\\|css\\)" beg))
  12064. beg)
  12065. (t
  12066. nil)
  12067. ) ;cond
  12068. ))
  12069. ;; Relay.QL , gql, graphql
  12070. (defun web-mode-is-ql-string (pos prefix-regexp)
  12071. (let (beg)
  12072. (cond
  12073. ((and (setq beg (web-mode-part-token-beginning-position pos))
  12074. (web-mode-looking-back prefix-regexp beg))
  12075. beg)
  12076. (t
  12077. nil)
  12078. ) ;cond
  12079. ))
  12080. (defun web-mode-is-html-string (pos)
  12081. (let (beg)
  12082. (cond
  12083. ((and (setq beg (web-mode-part-token-beginning-position pos))
  12084. (web-mode-looking-at-p "`[ \t\n]*<[a-zA-Z]" beg)
  12085. (web-mode-looking-back "\\(template\\|html\\)\\([ ]*[=:][ ]*\\)?" beg))
  12086. beg)
  12087. (t
  12088. nil)
  12089. ) ;cond
  12090. ))
  12091. ;;---- EXCURSION ---------------------------------------------------------------
  12092. (defun web-mode-backward-sexp (n)
  12093. (interactive "p")
  12094. (if (< n 0) (web-mode-forward-sexp (- n))
  12095. (let (pos)
  12096. (dotimes (_ n)
  12097. (skip-chars-backward "[:space:]")
  12098. (setq pos (point))
  12099. (cond
  12100. ((bobp) nil)
  12101. ((get-text-property (1- pos) 'block-end)
  12102. (backward-char 1)
  12103. (web-mode-block-beginning))
  12104. ((get-text-property (1- pos) 'block-token)
  12105. (backward-char 1)
  12106. (web-mode-block-token-beginning))
  12107. ((get-text-property (1- pos) 'part-token)
  12108. (backward-char 1)
  12109. (web-mode-part-token-beginning))
  12110. ((get-text-property (1- pos) 'tag-end)
  12111. (backward-char 1)
  12112. (web-mode-element-beginning))
  12113. ((get-text-property (1- pos) 'tag-attr)
  12114. (backward-char 1)
  12115. (web-mode-attribute-beginning))
  12116. ((get-text-property (1- pos) 'tag-type)
  12117. (backward-char 1)
  12118. (web-mode-tag-beginning))
  12119. ((get-text-property (1- pos) 'jsx-end)
  12120. (backward-char 1)
  12121. (web-mode-jsx-beginning))
  12122. (t
  12123. (let ((forward-sexp-function nil))
  12124. (backward-sexp))
  12125. ) ;case t
  12126. ) ;cond
  12127. ) ;dotimes
  12128. ))) ;let if defun
  12129. (defun web-mode-forward-sexp (n)
  12130. (interactive "p")
  12131. (if (< n 0) (web-mode-backward-sexp (- n))
  12132. (let (pos)
  12133. (dotimes (_ n)
  12134. (skip-chars-forward "[:space:]")
  12135. (setq pos (point))
  12136. (cond
  12137. ((eobp) nil)
  12138. ((get-text-property pos 'block-beg)
  12139. (web-mode-block-end))
  12140. ((get-text-property pos 'block-token)
  12141. (web-mode-block-token-end))
  12142. ((get-text-property pos 'part-token)
  12143. (web-mode-part-token-end))
  12144. ((get-text-property pos 'tag-beg)
  12145. (web-mode-element-end))
  12146. ((get-text-property pos 'tag-attr)
  12147. (web-mode-attribute-end))
  12148. ((get-text-property pos 'tag-type)
  12149. (web-mode-tag-end))
  12150. ((get-text-property pos 'jsx-beg)
  12151. (web-mode-jsx-end))
  12152. (t
  12153. (let ((forward-sexp-function nil))
  12154. (forward-sexp))
  12155. ) ;case t
  12156. ) ;cond
  12157. ) ;dotimes
  12158. ))) ;let if defun
  12159. (defun web-mode-comment-beginning ()
  12160. "Fetch current comment beg."
  12161. (interactive)
  12162. (web-mode-go (web-mode-comment-beginning-position (point))))
  12163. (defun web-mode-comment-end ()
  12164. "Fetch current comment end."
  12165. (interactive)
  12166. (web-mode-go (web-mode-comment-end-position (point)) 1))
  12167. (defun web-mode-tag-beginning ()
  12168. "Fetch current html tag beg."
  12169. (interactive)
  12170. (web-mode-go (web-mode-tag-beginning-position (point))))
  12171. (defun web-mode-tag-end ()
  12172. "Fetch current html tag end."
  12173. (interactive)
  12174. (web-mode-go (web-mode-tag-end-position (point)) 1))
  12175. (defun web-mode-tag-previous ()
  12176. "Fetch previous tag."
  12177. (interactive)
  12178. (web-mode-go (web-mode-tag-previous-position (point))))
  12179. (defun web-mode-tag-next ()
  12180. "Fetch next tag. Might be html comment or server tag (e.g. jsp)."
  12181. (interactive)
  12182. (web-mode-go (web-mode-tag-next-position (point))))
  12183. (defun web-mode-attribute-beginning ()
  12184. "Fetch html attribute beginning."
  12185. (interactive)
  12186. (web-mode-go (web-mode-attribute-beginning-position (point))))
  12187. (defun web-mode-attribute-end ()
  12188. "Fetch html attribute end."
  12189. (interactive)
  12190. (web-mode-go (web-mode-attribute-end-position (point)) 1))
  12191. (defun web-mode-attribute-next (&optional arg)
  12192. "Fetch next attribute."
  12193. (interactive "p")
  12194. (unless arg (setq arg 1))
  12195. (cond
  12196. ((= arg 1) (web-mode-go (web-mode-attribute-next-position (point))))
  12197. ((< arg 1) (web-mode-element-previous (* arg -1)))
  12198. (t
  12199. (while (>= arg 1)
  12200. (setq arg (1- arg))
  12201. (web-mode-go (web-mode-attribute-next-position (point)))
  12202. )
  12203. )
  12204. )
  12205. )
  12206. (defun web-mode-attribute-previous (&optional arg)
  12207. "Fetch previous attribute."
  12208. (interactive "p")
  12209. (unless arg (setq arg 1))
  12210. (unless arg (setq arg 1))
  12211. (cond
  12212. ((= arg 1) (web-mode-go (web-mode-attribute-previous-position (point))))
  12213. ((< arg 1) (web-mode-element-next (* arg -1)))
  12214. (t
  12215. (while (>= arg 1)
  12216. (setq arg (1- arg))
  12217. (web-mode-go (web-mode-attribute-previous-position (point)))
  12218. )
  12219. )
  12220. )
  12221. )
  12222. (defun web-mode-element-previous (&optional arg)
  12223. "Fetch previous element."
  12224. (interactive "p")
  12225. (unless arg (setq arg 1))
  12226. (cond
  12227. ((= arg 1) (web-mode-go (web-mode-element-previous-position (point))))
  12228. ((< arg 1) (web-mode-element-next (* arg -1)))
  12229. (t
  12230. (while (>= arg 1)
  12231. (setq arg (1- arg))
  12232. (web-mode-go (web-mode-element-previous-position (point)))
  12233. ) ;while
  12234. ) ;t
  12235. ) ;cond
  12236. )
  12237. (defun web-mode-element-next (&optional arg)
  12238. "Fetch next element."
  12239. (interactive "p")
  12240. (unless arg (setq arg 1))
  12241. (cond
  12242. ((= arg 1) (web-mode-go (web-mode-element-next-position (point))))
  12243. ((< arg 1) (web-mode-element-previous (* arg -1)))
  12244. (t
  12245. (while (>= arg 1)
  12246. (setq arg (1- arg))
  12247. (web-mode-go (web-mode-element-next-position (point)))
  12248. ) ;while
  12249. ) ;t
  12250. ) ;cond
  12251. )
  12252. (defun web-mode-element-sibling-next ()
  12253. "Fetch next sibling element."
  12254. (interactive)
  12255. (let ((pos (point)))
  12256. (save-excursion
  12257. (cond
  12258. ((not (get-text-property pos 'tag-type))
  12259. (if (and (web-mode-element-parent)
  12260. (web-mode-tag-match)
  12261. (web-mode-tag-next)
  12262. (member (get-text-property (point) 'tag-type) '(start void comment)))
  12263. (setq pos (point))
  12264. (setq pos nil))
  12265. )
  12266. ((member (get-text-property pos 'tag-type) '(start void))
  12267. (if (and (web-mode-tag-match)
  12268. (web-mode-tag-next)
  12269. (member (get-text-property (point) 'tag-type) '(start void comment)))
  12270. (setq pos (point))
  12271. (setq pos nil))
  12272. )
  12273. ((and (web-mode-tag-next)
  12274. (member (get-text-property (point) 'tag-type) '(start void comment)))
  12275. (setq pos (point)))
  12276. (t
  12277. (setq pos nil))
  12278. ) ;cond
  12279. ) ;save-excursion
  12280. (web-mode-go pos)))
  12281. (defun web-mode-element-sibling-previous ()
  12282. "Fetch previous sibling element."
  12283. (interactive)
  12284. (let ((pos (point)))
  12285. (save-excursion
  12286. (cond
  12287. ((not (get-text-property pos 'tag-type))
  12288. (if (and (web-mode-element-parent)
  12289. (web-mode-tag-previous)
  12290. (web-mode-element-beginning))
  12291. (setq pos (point))
  12292. (setq pos nil))
  12293. )
  12294. ((eq (get-text-property pos 'tag-type) 'start)
  12295. (if (and (web-mode-tag-beginning)
  12296. (web-mode-tag-previous)
  12297. (web-mode-element-beginning))
  12298. (setq pos (point))
  12299. (setq pos nil))
  12300. )
  12301. ((and (web-mode-element-beginning)
  12302. (web-mode-tag-previous)
  12303. (web-mode-element-beginning))
  12304. (setq pos (point)))
  12305. (t
  12306. (setq pos nil))
  12307. ) ;cond
  12308. ) ;save-excursion
  12309. (web-mode-go pos)))
  12310. (defun web-mode-element-beginning ()
  12311. "Move to beginning of element."
  12312. (interactive)
  12313. (web-mode-go (web-mode-element-beginning-position (point))))
  12314. (defun web-mode-element-end ()
  12315. "Move to end of element."
  12316. (interactive)
  12317. (web-mode-go (web-mode-element-end-position (point)) 1))
  12318. (defun web-mode-element-parent ()
  12319. "Fetch parent element."
  12320. (interactive)
  12321. (web-mode-go (web-mode-element-parent-position (point))))
  12322. (defun web-mode-element-child ()
  12323. "Fetch child element."
  12324. (interactive)
  12325. (web-mode-go (web-mode-element-child-position (point))))
  12326. (defun web-mode-dom-traverse ()
  12327. "Traverse html dom tree."
  12328. (interactive)
  12329. (cond
  12330. ((web-mode-element-child)
  12331. )
  12332. ((web-mode-element-sibling-next)
  12333. )
  12334. ((and (web-mode-element-parent)
  12335. (not (web-mode-element-sibling-next)))
  12336. (goto-char (point-min)))
  12337. (t
  12338. (goto-char (point-min)))
  12339. ) ;cond
  12340. )
  12341. (defun web-mode-closing-paren (limit)
  12342. (let ((pos (web-mode-closing-paren-position (point) limit)))
  12343. (if (or (null pos) (> pos limit))
  12344. nil
  12345. (goto-char pos)
  12346. pos)
  12347. ))
  12348. (defun web-mode-part-next ()
  12349. "Move point to the beginning of the next part."
  12350. (interactive)
  12351. (web-mode-go (web-mode-part-next-position (point))))
  12352. (defun web-mode-part-beginning ()
  12353. "Move point to the beginning of the current part."
  12354. (interactive)
  12355. (web-mode-go (web-mode-part-beginning-position (point))))
  12356. (defun web-mode-part-end ()
  12357. "Move point to the end of the current part."
  12358. (interactive)
  12359. (web-mode-go (web-mode-part-end-position (point)) 1))
  12360. (defun web-mode-block-previous ()
  12361. "Move point to the beginning of the previous block."
  12362. (interactive)
  12363. (web-mode-go (web-mode-block-previous-position (point))))
  12364. (defun web-mode-block-next ()
  12365. "Move point to the beginning of the next block."
  12366. (interactive)
  12367. (web-mode-go (web-mode-block-next-position (point))))
  12368. (defun web-mode-block-beginning ()
  12369. "Move point to the beginning of the current block."
  12370. (interactive)
  12371. (web-mode-go (web-mode-block-beginning-position (point))))
  12372. (defun web-mode-block-end ()
  12373. "Move point to the end of the current block."
  12374. (interactive)
  12375. (web-mode-go (web-mode-block-end-position (point)) 1))
  12376. (defun web-mode-block-token-beginning ()
  12377. (web-mode-go (web-mode-block-token-beginning-position (point))))
  12378. (defun web-mode-block-token-end ()
  12379. (web-mode-go (web-mode-block-token-end-position (point)) 1))
  12380. (defun web-mode-part-token-beginning ()
  12381. (web-mode-go (web-mode-part-token-beginning-position (point))))
  12382. (defun web-mode-part-token-end ()
  12383. (web-mode-go (web-mode-part-token-end-position (point)) 1))
  12384. (defun web-mode-block-opening-paren (limit)
  12385. (web-mode-go (web-mode-block-opening-paren-position (point) limit)))
  12386. (defun web-mode-block-string-beginning (&optional pos block-beg)
  12387. (unless pos (setq pos (point)))
  12388. (unless block-beg (setq block-beg (web-mode-block-beginning-position pos)))
  12389. (web-mode-go (web-mode-block-string-beginning-position pos block-beg)))
  12390. (defun web-mode-block-statement-beginning (pos block-beg is-ternary)
  12391. (unless pos (setq pos (point)))
  12392. (unless block-beg (setq block-beg (web-mode-block-beginning-position pos)))
  12393. (web-mode-go (web-mode-block-statement-beginning-position pos block-beg is-ternary)))
  12394. (defun web-mode-block-args-beginning (&optional pos block-beg)
  12395. (unless pos (setq pos (point)))
  12396. (unless block-beg (setq block-beg (web-mode-block-beginning-position pos)))
  12397. (web-mode-go (web-mode-block-args-beginning-position pos block-beg)))
  12398. (defun web-mode-block-calls-beginning (&optional pos block-beg)
  12399. (unless pos (setq pos (point)))
  12400. (unless block-beg (setq block-beg (web-mode-block-beginning-position pos)))
  12401. (web-mode-go (web-mode-block-calls-beginning-position pos block-beg)))
  12402. (defun web-mode-javascript-string-beginning (&optional pos reg-beg)
  12403. (unless pos (setq pos (point)))
  12404. (unless reg-beg
  12405. (if (get-text-property pos 'block-side)
  12406. (setq reg-beg (web-mode-block-beginning-position pos))
  12407. (setq reg-beg (web-mode-part-beginning-position pos))))
  12408. (web-mode-go (web-mode-javascript-string-beginning-position pos reg-beg)))
  12409. (defun web-mode-javascript-statement-beginning (pos reg-beg is-ternary)
  12410. (unless pos (setq pos (point)))
  12411. (unless reg-beg
  12412. (if (get-text-property pos 'block-side)
  12413. (setq reg-beg (web-mode-block-beginning-position pos))
  12414. (setq reg-beg (web-mode-part-beginning-position pos))))
  12415. (web-mode-go (web-mode-javascript-statement-beginning-position pos reg-beg is-ternary)))
  12416. (defun web-mode-javascript-args-beginning (&optional pos reg-beg)
  12417. (unless pos (setq pos (point)))
  12418. (unless reg-beg
  12419. (setq reg-beg (if (get-text-property pos 'block-side)
  12420. (web-mode-block-beginning-position pos)
  12421. (web-mode-part-beginning-position pos))))
  12422. ;;(message "reg-beg%S" reg-beg)
  12423. (web-mode-go (web-mode-javascript-args-beginning-position pos reg-beg)))
  12424. (defun web-mode-javascript-calls-beginning (&optional pos reg-beg)
  12425. (unless pos (setq pos (point)))
  12426. (unless reg-beg
  12427. (if (get-text-property pos 'block-side)
  12428. (setq reg-beg (web-mode-block-beginning-position pos))
  12429. (setq reg-beg (web-mode-part-beginning-position pos))))
  12430. (let (pair)
  12431. (setq pair (web-mode-javascript-calls-beginning-position pos reg-beg))
  12432. (when pair (web-mode-go (car pair)))
  12433. ))
  12434. (defun web-mode-go (pos &optional offset)
  12435. (unless offset (setq offset 0))
  12436. (when pos
  12437. (cond
  12438. ((and (> offset 0) (<= (+ pos offset) (point-max)))
  12439. (setq pos (+ pos offset)))
  12440. ((and (< offset 0) (>= (+ pos offset) (point-min)))
  12441. (setq pos (+ pos offset)))
  12442. ) ;cond
  12443. (goto-char pos))
  12444. pos)
  12445. ;;---- SEARCH ------------------------------------------------------------------
  12446. (defun web-mode-rsf-balanced (regexp-open regexp-close &optional limit noerror)
  12447. (unless noerror (setq noerror t))
  12448. (let ((continue t)
  12449. (level 1)
  12450. (pos (point))
  12451. ret
  12452. (regexp (concat regexp-open "\\|" regexp-close)))
  12453. (while continue
  12454. (setq ret (re-search-forward regexp limit noerror))
  12455. (cond
  12456. ((null ret)
  12457. (setq continue nil)
  12458. )
  12459. (t
  12460. (if (string-match-p regexp-open (match-string-no-properties 0))
  12461. (setq level (1+ level))
  12462. (setq level (1- level)))
  12463. (when (< level 1)
  12464. (setq continue nil)
  12465. )
  12466. ) ;t
  12467. ) ;cond
  12468. ) ;while
  12469. (when (not (= level 0)) (goto-char pos))
  12470. ret))
  12471. (defun web-mode-block-sb (expr &optional limit noerror)
  12472. (unless limit (setq limit (web-mode-block-beginning-position (point))))
  12473. (unless noerror (setq noerror t))
  12474. (let ((continue t) ret)
  12475. (while continue
  12476. (setq ret (search-backward expr limit noerror))
  12477. (when (or (null ret)
  12478. (not (get-text-property (point) 'block-token)))
  12479. (setq continue nil)
  12480. ) ;when
  12481. ) ;while
  12482. ret))
  12483. (defun web-mode-block-sf (expr &optional limit noerror)
  12484. (unless limit (setq limit (web-mode-block-end-position (point))))
  12485. (unless noerror (setq noerror t))
  12486. (let ((continue t) ret)
  12487. (while continue
  12488. (setq ret (search-forward expr limit noerror))
  12489. (when (or (null ret)
  12490. (not (get-text-property (point) 'block-token)))
  12491. (setq continue nil)
  12492. ) ;when
  12493. ) ;while
  12494. ret))
  12495. (defun web-mode-block-rsb (regexp &optional limit noerror)
  12496. (unless limit (setq limit (web-mode-block-beginning-position (point))))
  12497. (unless noerror (setq noerror t))
  12498. (let ((continue t) ret)
  12499. (while continue
  12500. (setq ret (re-search-backward regexp limit noerror))
  12501. (when (or (null ret)
  12502. (not (get-text-property (point) 'block-token)))
  12503. (setq continue nil)
  12504. ) ;when
  12505. ) ;while
  12506. ret))
  12507. (defun web-mode-block-rsf (regexp &optional limit noerror)
  12508. (unless limit (setq limit (web-mode-block-end-position (point))))
  12509. (unless noerror (setq noerror t))
  12510. (let ((continue t) ret)
  12511. (while continue
  12512. (setq ret (re-search-forward regexp limit noerror))
  12513. (when (or (null ret)
  12514. (not (get-text-property (point) 'block-token)))
  12515. (setq continue nil)
  12516. ) ;when
  12517. ) ;while
  12518. ret))
  12519. (defun web-mode-part-sb (expr &optional limit noerror)
  12520. (unless limit (setq limit (web-mode-part-beginning-position (point))))
  12521. (unless noerror (setq noerror t))
  12522. (let ((continue t) ret)
  12523. (while continue
  12524. (setq ret (search-backward expr limit noerror))
  12525. (when (or (null ret)
  12526. (and (not (get-text-property (point) 'part-token))
  12527. (not (get-text-property (point) 'block-side)))
  12528. )
  12529. (setq continue nil)
  12530. ) ;when
  12531. ) ;while
  12532. ret))
  12533. (defun web-mode-part-sf (expr &optional limit noerror)
  12534. (unless limit (setq limit (web-mode-part-end-position (point))))
  12535. (unless noerror (setq noerror t))
  12536. (let ((continue t) ret)
  12537. (while continue
  12538. (setq ret (search-forward expr limit noerror))
  12539. (when (or (null ret)
  12540. (and (not (get-text-property (point) 'part-token))
  12541. (not (get-text-property (point) 'block-side)))
  12542. )
  12543. (setq continue nil)
  12544. ) ;when
  12545. ) ;while
  12546. ret))
  12547. (defun web-mode-part-rsb (regexp &optional limit noerror)
  12548. (unless limit (setq limit (web-mode-part-beginning-position (point))))
  12549. (unless noerror (setq noerror t))
  12550. (let ((continue t) ret)
  12551. (while continue
  12552. (setq ret (re-search-backward regexp limit noerror))
  12553. (when (or (null ret)
  12554. (and (not (get-text-property (point) 'part-token))
  12555. (not (get-text-property (point) 'block-side)))
  12556. )
  12557. (setq continue nil)
  12558. ) ;when
  12559. ) ;while
  12560. ret))
  12561. (defun web-mode-part-rsf (regexp &optional limit noerror)
  12562. (unless limit (setq limit (web-mode-part-end-position (point))))
  12563. (unless noerror (setq noerror t))
  12564. (let ((continue t) ret)
  12565. (while continue
  12566. (setq ret (re-search-forward regexp limit t))
  12567. (when (or (null ret)
  12568. (and (not (get-text-property (point) 'part-token))
  12569. (not (get-text-property (point) 'block-side)))
  12570. )
  12571. (setq continue nil)
  12572. ) ;when
  12573. ) ;while
  12574. ret))
  12575. (defun web-mode-javascript-rsb (regexp &optional limit noerror)
  12576. (unless limit (setq limit (web-mode-part-beginning-position (point))))
  12577. (unless noerror (setq noerror t))
  12578. (let ((continue t) ret)
  12579. (while continue
  12580. (setq ret (re-search-backward regexp limit noerror))
  12581. (when (or (null ret)
  12582. (and (not (get-text-property (point) 'part-token))
  12583. (not (get-text-property (point) 'block-side))
  12584. (not (get-text-property (point) 'jsx-depth)))
  12585. )
  12586. (setq continue nil)
  12587. ) ;when
  12588. ) ;while
  12589. ret))
  12590. (defun web-mode-javascript-rsf (regexp &optional limit noerror)
  12591. (unless limit (setq limit (web-mode-part-end-position (point))))
  12592. (unless noerror (setq noerror t))
  12593. (let ((continue t) ret)
  12594. (while continue
  12595. (setq ret (re-search-forward regexp limit t))
  12596. (when (or (null ret)
  12597. (and (not (get-text-property (point) 'part-token))
  12598. (not (get-text-property (point) 'block-side))
  12599. (not (get-text-property (point) 'jsx-depth)))
  12600. )
  12601. (setq continue nil)
  12602. ) ;when
  12603. ) ;while
  12604. ret))
  12605. (defun web-mode-dom-sf (expr &optional limit noerror)
  12606. (unless noerror (setq noerror t))
  12607. (let ((continue t) ret)
  12608. (while continue
  12609. (setq ret (search-forward expr limit noerror))
  12610. (if (or (null ret)
  12611. (not (get-text-property (- (point) (length expr)) 'block-side)))
  12612. (setq continue nil))
  12613. )
  12614. ret))
  12615. (defun web-mode-dom-rsf (regexp &optional limit noerror)
  12616. (unless noerror (setq noerror t))
  12617. (let ((continue t) (ret nil))
  12618. (while continue
  12619. (setq ret (re-search-forward regexp limit noerror))
  12620. ;; (message "ret=%S point=%S limit=%S i=%S" ret (point) limit 0)
  12621. (cond
  12622. ((null ret)
  12623. (setq continue nil))
  12624. ((or (get-text-property (match-beginning 0) 'block-side)
  12625. (get-text-property (match-beginning 0) 'part-token))
  12626. )
  12627. (t
  12628. (setq continue nil))
  12629. ) ;cond
  12630. ) ;while
  12631. ret))
  12632. (defun web-mode-rsb-position (pos regexp &optional limit noerror)
  12633. (unless noerror (setq noerror t))
  12634. (save-excursion
  12635. (goto-char pos)
  12636. (if (re-search-backward regexp limit noerror) (point) nil)
  12637. ))
  12638. (defun web-mode-rsb (regexp &optional limit noerror)
  12639. (unless noerror (setq noerror t))
  12640. (let ((continue t) ret)
  12641. (while continue
  12642. (setq ret (re-search-backward regexp limit noerror))
  12643. (if (or (null ret)
  12644. (not (web-mode-is-comment-or-string)))
  12645. (setq continue nil)))
  12646. ret))
  12647. (defun web-mode-rsf (regexp &optional limit noerror)
  12648. (unless noerror (setq noerror t))
  12649. (let ((continue t) ret)
  12650. (while continue
  12651. (setq ret (re-search-forward regexp limit noerror))
  12652. (if (or (null ret)
  12653. (not (web-mode-is-comment-or-string)))
  12654. (setq continue nil))
  12655. )
  12656. ret))
  12657. (defun web-mode-sb (expr &optional limit noerror)
  12658. (unless noerror (setq noerror t))
  12659. (let ((continue t) ret)
  12660. (while continue
  12661. (setq ret (search-backward expr limit noerror))
  12662. (if (or (null ret)
  12663. (not (web-mode-is-comment-or-string)))
  12664. (setq continue nil)))
  12665. ret))
  12666. (defun web-mode-sf (expr &optional limit noerror)
  12667. (unless noerror (setq noerror t))
  12668. (let ((continue t) ret)
  12669. (while continue
  12670. (setq ret (search-forward expr limit noerror))
  12671. (if (or (null ret)
  12672. (not (web-mode-is-comment-or-string)))
  12673. (setq continue nil)))
  12674. ret))
  12675. (defun web-mode-content-rsf (regexp &optional limit noerror)
  12676. (unless noerror (setq noerror t))
  12677. (let ((continue t) ret beg end)
  12678. (while continue
  12679. (setq ret (re-search-forward regexp limit noerror)
  12680. beg (if (null ret) (point) (match-beginning 0))
  12681. end (if (null ret) (point) (1- (match-end 0))))
  12682. (if (or (null ret)
  12683. (and (web-mode-is-content beg)
  12684. (web-mode-is-content end)))
  12685. (setq continue nil)))
  12686. ret))
  12687. ;;---- ADVICES -----------------------------------------------------------------
  12688. (defadvice ac-start (before web-mode-set-up-ac-sources activate)
  12689. "Set `ac-sources' based on current language before running auto-complete."
  12690. (when (equal major-mode 'web-mode)
  12691. ;; set ignore each time to nil. User has to implement a hook to change it
  12692. ;; for each completion
  12693. (setq web-mode-ignore-ac-start-advice nil)
  12694. (run-hooks 'web-mode-before-auto-complete-hooks)
  12695. (unless web-mode-ignore-ac-start-advice
  12696. (when web-mode-ac-sources-alist
  12697. (let ((new-web-mode-ac-sources
  12698. (assoc (web-mode-language-at-pos)
  12699. web-mode-ac-sources-alist)))
  12700. (setq ac-sources (cdr new-web-mode-ac-sources)))))))
  12701. ;;---- MINOR MODE ADDONS -------------------------------------------------------
  12702. (defun web-mode-yasnippet-exit-hook ()
  12703. "Yasnippet exit hook"
  12704. (when (and (boundp 'yas-snippet-beg) (boundp 'yas-snippet-end))
  12705. (indent-region yas-snippet-beg yas-snippet-end)))
  12706. (defun web-mode-imenu-index ()
  12707. (interactive)
  12708. "Returns imenu items."
  12709. (let (toc-index
  12710. line)
  12711. (save-excursion
  12712. (goto-char (point-min))
  12713. (while (not (eobp))
  12714. (setq line (buffer-substring-no-properties
  12715. (line-beginning-position)
  12716. (line-end-position)))
  12717. (let (found
  12718. (i 0)
  12719. item
  12720. regexp
  12721. type
  12722. type-idx
  12723. content
  12724. content-idx
  12725. content-regexp
  12726. close-tag-regexp
  12727. concat-str
  12728. jumpto
  12729. str)
  12730. (while (and (not found ) (< i (length web-mode-imenu-regexp-list)))
  12731. (setq item (nth i web-mode-imenu-regexp-list))
  12732. (setq regexp (nth 0 item))
  12733. (setq type-idx (nth 1 item))
  12734. (setq content-idx (nth 2 item))
  12735. (setq concat-str (nth 3 item))
  12736. (when (not (numberp content-idx))
  12737. (setq content-regexp (nth 2 item)
  12738. close-tag-regexp (nth 4 item)
  12739. content-idx nil))
  12740. (when (string-match regexp line)
  12741. (cond
  12742. (content-idx
  12743. (setq type (match-string type-idx line))
  12744. (setq content (match-string content-idx line))
  12745. (setq str (concat type concat-str content))
  12746. (setq jumpto (line-beginning-position)))
  12747. (t
  12748. (let (limit)
  12749. (setq type (match-string type-idx line))
  12750. (goto-char (line-beginning-position))
  12751. (save-excursion
  12752. (setq limit (re-search-forward close-tag-regexp (point-max) t)))
  12753. (when limit
  12754. (when (re-search-forward content-regexp limit t)
  12755. (setq content (match-string 1))
  12756. (setq str (concat type concat-str content))
  12757. (setq jumpto (line-beginning-position))
  12758. )
  12759. )))
  12760. )
  12761. (when str (setq toc-index
  12762. (cons (cons str jumpto)
  12763. toc-index)
  12764. )
  12765. (setq found t))
  12766. )
  12767. (setq i (1+ i))))
  12768. (forward-line)
  12769. (goto-char (line-end-position)) ;; make sure we are at eobp
  12770. ))
  12771. (nreverse toc-index)))
  12772. ;;---- UNIT TESTING ------------------------------------------------------------
  12773. (defun web-mode-test ()
  12774. "Executes web-mode unit tests. See `web-mode-tests-directory'."
  12775. (interactive)
  12776. (let (files ret regexp)
  12777. (setq regexp "^[[:alnum:]][[:alnum:]._]+\\'")
  12778. (setq files (directory-files web-mode-tests-directory t regexp))
  12779. (dolist (file files)
  12780. (cond
  12781. ((eq (string-to-char (file-name-nondirectory file)) ?\_)
  12782. (delete-file file))
  12783. (t
  12784. (setq ret (web-mode-test-process file)))
  12785. ) ;cond
  12786. ) ;dolist
  12787. ))
  12788. (defun web-mode-test-process (file)
  12789. (with-temp-buffer
  12790. (let (out sig1 sig2 success err)
  12791. (setq-default indent-tabs-mode nil)
  12792. (if (string-match-p "sql" file)
  12793. (setq web-mode-enable-sql-detection t)
  12794. (setq web-mode-enable-sql-detection nil))
  12795. (insert-file-contents file)
  12796. (set-visited-file-name file)
  12797. (web-mode)
  12798. (setq sig1 (md5 (current-buffer)))
  12799. (delete-horizontal-space)
  12800. (while (not (eobp))
  12801. (forward-line)
  12802. (delete-horizontal-space)
  12803. (end-of-line))
  12804. (web-mode-buffer-indent)
  12805. (setq sig2 (md5 (current-buffer)))
  12806. (setq success (string= sig1 sig2))
  12807. (setq out (concat (if success "ok" "ko") " : " (file-name-nondirectory file) "\n"))
  12808. (princ out)
  12809. (setq err (concat (file-name-directory file) "_err." (file-name-nondirectory file)))
  12810. (if success
  12811. (when (file-readable-p err)
  12812. (delete-file err))
  12813. (write-file err)
  12814. (message "[%s]" (buffer-string))
  12815. ) ;if
  12816. out)))
  12817. ;;---- MISC --------------------------------------------------------------------
  12818. (defun web-mode-set-engine (engine)
  12819. "Set the engine for the current buffer."
  12820. (interactive
  12821. (list (completing-read
  12822. "Engine: "
  12823. (let (engines)
  12824. (dolist (elt web-mode-engines)
  12825. (setq engines (append engines (list (car elt)))))
  12826. engines))))
  12827. (setq web-mode-content-type "html"
  12828. web-mode-engine (web-mode-engine-canonical-name engine)
  12829. web-mode-minor-engine engine)
  12830. (web-mode-on-engine-setted)
  12831. (web-mode-buffer-fontify))
  12832. (defun web-mode-set-content-type (content-type)
  12833. "Set the content-type for the current buffer"
  12834. (interactive (list (completing-read "Content-type: " web-mode-part-content-types)))
  12835. (setq web-mode-content-type content-type)
  12836. (when (called-interactively-p 'any)
  12837. )
  12838. (web-mode-buffer-fontify))
  12839. (defun web-mode-on-engine-setted ()
  12840. (let (elt elts engines)
  12841. (when (string= web-mode-engine "razor") (setq web-mode-enable-block-face t))
  12842. ;;(setq web-mode-engine-attr-regexp (cdr (assoc web-mode-engine web-mode-engine-attr-regexps)))
  12843. (setq web-mode-engine-token-regexp (cdr (assoc web-mode-engine web-mode-engine-token-regexps)))
  12844. ;;(message "%S %S %S" web-mode-engine web-mode-engine-attr-regexp web-mode-engine-token-regexp)
  12845. (when (null web-mode-minor-engine)
  12846. (setq web-mode-minor-engine "none"))
  12847. (setq elt (assoc web-mode-engine web-mode-engine-open-delimiter-regexps))
  12848. (cond
  12849. (elt
  12850. (setq web-mode-block-regexp (cdr elt)))
  12851. ((string= web-mode-engine "archibus")
  12852. (setq web-mode-block-regexp nil))
  12853. (t
  12854. (setq web-mode-engine "none"))
  12855. )
  12856. (unless (boundp 'web-mode-extra-auto-pairs)
  12857. (setq web-mode-extra-auto-pairs nil))
  12858. (setq web-mode-auto-pairs
  12859. (append
  12860. (cdr (assoc web-mode-engine web-mode-engines-auto-pairs))
  12861. (cdr (assoc nil web-mode-engines-auto-pairs))
  12862. (cdr (assoc web-mode-engine web-mode-extra-auto-pairs))
  12863. (cdr (assoc nil web-mode-extra-auto-pairs))))
  12864. (unless (boundp 'web-mode-extra-snippets)
  12865. (setq web-mode-extra-snippets nil))
  12866. (setq elts
  12867. (append
  12868. (cdr (assoc web-mode-engine web-mode-extra-snippets))
  12869. (cdr (assoc nil web-mode-extra-snippets))
  12870. (cdr (assoc web-mode-engine web-mode-engines-snippets))
  12871. (cdr (assoc nil web-mode-engines-snippets))))
  12872. ;;(message "%S" elts)
  12873. (dolist (elt elts)
  12874. (unless (assoc (car elt) web-mode-snippets)
  12875. (setq web-mode-snippets (append (list elt) web-mode-snippets)))
  12876. )
  12877. (setq web-mode-engine-font-lock-keywords
  12878. (symbol-value (cdr (assoc web-mode-engine web-mode-engines-font-lock-keywords))))
  12879. (when (and (string= web-mode-minor-engine "jinja")
  12880. (not (member "endtrans" web-mode-django-control-blocks)))
  12881. (add-to-list 'web-mode-django-control-blocks "endtrans")
  12882. (setq web-mode-django-control-blocks-regexp
  12883. (regexp-opt web-mode-django-control-blocks t))
  12884. )
  12885. (when (string= web-mode-engine "spip")
  12886. (modify-syntax-entry ?# "w" (syntax-table)))
  12887. ;; (message "%S" (symbol-value (cdr (assoc web-mode-engine web-mode-engines-font-lock-keywords))))
  12888. ))
  12889. (defun web-mode-detect-engine ()
  12890. (save-excursion
  12891. (goto-char (point-min))
  12892. (when (re-search-forward "-\\*- engine:[ ]*\\([[:alnum:]-]+\\)[ ]*-\\*-" web-mode-chunk-length t)
  12893. (setq web-mode-minor-engine (match-string-no-properties 1))
  12894. (setq web-mode-engine (web-mode-engine-canonical-name web-mode-minor-engine)))
  12895. web-mode-minor-engine))
  12896. (defun web-mode-guess-engine-and-content-type ()
  12897. (let (buff-name elt found)
  12898. (setq buff-name (buffer-file-name))
  12899. (unless buff-name (setq buff-name (buffer-name)))
  12900. (setq web-mode-is-scratch (string= buff-name "*scratch*"))
  12901. (setq web-mode-content-type nil)
  12902. (when (boundp 'web-mode-content-types-alist)
  12903. (setq found nil)
  12904. (dolist (elt web-mode-content-types-alist)
  12905. (when (and (not found) (string-match-p (cdr elt) buff-name))
  12906. (setq web-mode-content-type (car elt)
  12907. found t))
  12908. ) ;dolist
  12909. ) ;when
  12910. (unless web-mode-content-type
  12911. (setq found nil)
  12912. (dolist (elt web-mode-content-types)
  12913. (when (and (not found) (string-match-p (cdr elt) buff-name))
  12914. (setq web-mode-content-type (car elt)
  12915. found t)
  12916. ;;(message "%S" web-mode-content-type)
  12917. ) ;when
  12918. ) ;dolist
  12919. ) ;unless
  12920. (when (boundp 'web-mode-engines-alist)
  12921. (setq found nil)
  12922. (dolist (elt web-mode-engines-alist)
  12923. (cond
  12924. ((stringp (cdr elt))
  12925. (when (string-match-p (cdr elt) buff-name)
  12926. (setq web-mode-engine (car elt))))
  12927. ((functionp (cdr elt))
  12928. (when (funcall (cdr elt))
  12929. (setq web-mode-engine (car elt))))
  12930. ) ;cond
  12931. ) ;dolist
  12932. ) ;when
  12933. (unless web-mode-engine
  12934. (setq found nil)
  12935. (dolist (elt web-mode-engine-file-regexps)
  12936. ;;(message "%S %S" (cdr elt) buff-name)
  12937. (when (and (not found) (string-match-p (cdr elt) buff-name))
  12938. (setq web-mode-engine (car elt)
  12939. found t))
  12940. )
  12941. )
  12942. (when (and (or (null web-mode-engine) (string= web-mode-engine "none"))
  12943. (string-match-p "php" (buffer-substring-no-properties
  12944. (line-beginning-position)
  12945. (line-end-position))))
  12946. (setq web-mode-engine "php"))
  12947. (when (and (string= web-mode-content-type "javascript")
  12948. (string-match-p "@jsx"
  12949. (buffer-substring-no-properties
  12950. (point-min)
  12951. (if (< (point-max) web-mode-chunk-length)
  12952. (point-max)
  12953. web-mode-chunk-length)
  12954. )))
  12955. (setq web-mode-content-type "jsx"))
  12956. (when web-mode-engine
  12957. (setq web-mode-minor-engine web-mode-engine
  12958. web-mode-engine (web-mode-engine-canonical-name web-mode-engine))
  12959. )
  12960. (when (and (or (null web-mode-engine)
  12961. (string= web-mode-engine "none"))
  12962. web-mode-enable-engine-detection)
  12963. (web-mode-detect-engine))
  12964. (web-mode-on-engine-setted)
  12965. ))
  12966. (defun web-mode-engine-canonical-name (name)
  12967. (let (engine)
  12968. (cond
  12969. ((null name)
  12970. nil)
  12971. ((assoc name web-mode-engines)
  12972. name)
  12973. (t
  12974. (dolist (elt web-mode-engines)
  12975. (when (and (null engine) (member name (cdr elt)))
  12976. (setq engine (car elt)))
  12977. ) ;dolist
  12978. engine)
  12979. )))
  12980. (defun web-mode-on-after-save ()
  12981. (when web-mode-is-scratch
  12982. (web-mode-guess-engine-and-content-type)
  12983. (web-mode-buffer-fontify))
  12984. nil)
  12985. (defun web-mode-on-exit ()
  12986. (web-mode-with-silent-modifications
  12987. (put-text-property (point-min) (point-max) 'invisible nil)
  12988. (remove-overlays)
  12989. (remove-hook 'change-major-mode-hook 'web-mode-on-exit t)
  12990. ))
  12991. (defun web-mode-file-link (file)
  12992. "Insert a link to a file in html document. This function can be
  12993. extended to support more filetypes by customizing
  12994. `web-mode-links'."
  12995. (interactive
  12996. (list (file-relative-name (read-file-name "Link file: "))))
  12997. (let ((matched nil)
  12998. (point-line (line-number-at-pos))
  12999. (point-column (current-column)))
  13000. (dolist (type web-mode-links)
  13001. (when (string-match (car type) file)
  13002. (setq matched t)
  13003. (when (nth 2 type)
  13004. (goto-char (point-min))
  13005. (search-forward "</head>")
  13006. (backward-char 7)
  13007. (open-line 1))
  13008. (insert (format (cadr type) file))
  13009. (indent-for-tab-command)
  13010. (when (nth 2 type)
  13011. ;; return point where it was and fix indentation
  13012. (forward-line)
  13013. (indent-for-tab-command)
  13014. (if (> point-line (- (line-number-at-pos) 2))
  13015. (forward-line (+ (- point-line (line-number-at-pos)) 1))
  13016. (forward-line (- point-line (line-number-at-pos))))
  13017. (move-to-column point-column))
  13018. ;; move point back if needed
  13019. (backward-char (nth 3 type))))
  13020. (when (not matched)
  13021. (user-error "Unknown file type"))))
  13022. (defun web-mode-reload ()
  13023. "Reload web-mode."
  13024. (interactive)
  13025. (web-mode-with-silent-modifications
  13026. (put-text-property (point-min) (point-max) 'invisible nil)
  13027. (remove-overlays)
  13028. (setq font-lock-unfontify-region-function 'font-lock-default-unfontify-region)
  13029. (load "web-mode.el")
  13030. (setq web-mode-change-beg nil
  13031. web-mode-change-end nil)
  13032. (web-mode)
  13033. ))
  13034. (defun web-mode-trace (msg)
  13035. (let (sub)
  13036. (when (null web-mode-time) (setq web-mode-time (current-time)))
  13037. (setq sub (time-subtract (current-time) web-mode-time))
  13038. (when nil
  13039. (save-excursion
  13040. (let ((n 0))
  13041. (goto-char (point-min))
  13042. (while (web-mode-tag-next)
  13043. (setq n (1+ n))
  13044. )
  13045. (message "%S tags found" n)
  13046. )))
  13047. (message "%18s: time elapsed = %Ss %9Sµs" msg (nth 1 sub) (nth 2 sub))
  13048. ))
  13049. (defun web-mode-reveal ()
  13050. "Display text properties at point."
  13051. (interactive)
  13052. (let (symbols out)
  13053. (setq out (format
  13054. "[point=%S engine=%S minor=%S content-type=%S language-at-pos=%S]\n"
  13055. (point)
  13056. web-mode-engine
  13057. web-mode-minor-engine
  13058. web-mode-content-type
  13059. (web-mode-language-at-pos (point))))
  13060. (setq symbols (append web-mode-scan-properties '(font-lock-face face)))
  13061. (dolist (symbol symbols)
  13062. (when symbol
  13063. (setq out (concat out (format "%s(%S) " (symbol-name symbol) (get-text-property (point) symbol)))))
  13064. )
  13065. (message "%s\n" out)
  13066. ;;(message "syntax-class=%S" (syntax-class (syntax-after (point))))
  13067. (message nil)))
  13068. (defun web-mode-debug ()
  13069. "Display informations useful for debugging."
  13070. (interactive)
  13071. (let ((modes nil)
  13072. (customs '(web-mode-enable-current-column-highlight web-mode-enable-current-element-highlight indent-tabs-mode))
  13073. (ignore '(abbrev-mode auto-composition-mode auto-compression-mode auto-encryption-mode auto-insert-mode blink-cursor-mode column-number-mode delete-selection-mode display-time-mode electric-indent-mode file-name-shadow-mode font-lock-mode global-font-lock-mode global-hl-line-mode line-number-mode menu-bar-mode mouse-wheel-mode recentf-mode show-point-mode tool-bar-mode tooltip-mode transient-mark-mode)))
  13074. (message "\n")
  13075. (message "--- WEB-MODE DEBUG BEG ---")
  13076. (message "versions: emacs(%S.%S) web-mode(%S)"
  13077. emacs-major-version emacs-minor-version web-mode-version)
  13078. (message "vars: engine(%S) minor(%S) content-type(%S) file(%S)"
  13079. web-mode-engine
  13080. web-mode-minor-engine
  13081. web-mode-content-type
  13082. (or (buffer-file-name) (buffer-name)))
  13083. (message "system: window(%S) config(%S)" window-system system-configuration)
  13084. (message "colors: fg(%S) bg(%S) "
  13085. (cdr (assoc 'foreground-color default-frame-alist))
  13086. (cdr (assoc 'background-color default-frame-alist)))
  13087. (mapc (lambda (mode)
  13088. (condition-case nil
  13089. (if (and (symbolp mode) (symbol-value mode) (not (member mode ignore)))
  13090. (add-to-list 'modes mode))
  13091. (error nil))
  13092. ) ;lambda
  13093. minor-mode-list)
  13094. (message "minor modes: %S" modes)
  13095. (message "vars:")
  13096. (dolist (custom customs)
  13097. (message (format "%s=%S " (symbol-name custom) (symbol-value custom))))
  13098. (message "--- WEB-MODE DEBUG END ---")
  13099. (switch-to-buffer "*Messages*")
  13100. (goto-char (point-max))
  13101. (recenter)
  13102. ))
  13103. (provide 'web-mode)
  13104. ;;; web-mode.el ends here
  13105. ;; Local Variables:
  13106. ;; coding: utf-8
  13107. ;; indent-tabs-mode: nil
  13108. ;; End: