From 96a9c67adacf2c51f19d1a8f72d7830e3699272d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?CAPELLE=20Mika=C3=ABl?= Date: Mon, 13 Jan 2020 15:14:54 +0100 Subject: [PATCH] Initial commit. --- .gitignore | 17 + .gitmodules | 36 + early-init.el | 68 + elisp/init-ace-window.el | 47 + elisp/init-all-the-icons.el | 168 + elisp/init-avy.el | 58 + elisp/init-cc.el | 82 + elisp/init-comment.el | 49 + elisp/init-company.el | 224 + elisp/init-const.el | 112 + elisp/init-crux.el | 56 + elisp/init-dashboard.el | 91 + elisp/init-dired.el | 102 + elisp/init-discover-my-major.el | 47 + elisp/init-dumb-jump.el | 52 + elisp/init-eaf.el | 67 + elisp/init-edit.el | 73 + elisp/init-ein.el | 48 + elisp/init-epaint.el | 58 + elisp/init-erc.el | 140 + elisp/init-ess.el | 50 + elisp/init-eww.el | 58 + elisp/init-flycheck.el | 64 + elisp/init-fonts.el | 84 + elisp/init-format.el | 47 + elisp/init-func.el | 184 + elisp/init-games.el | 68 + elisp/init-global-config.el | 176 + elisp/init-header.el | 54 + elisp/init-indent.el | 75 + elisp/init-java.el | 56 + elisp/init-latex.el | 79 + elisp/init-leetcode.el | 57 + elisp/init-lsp.el | 114 + elisp/init-magit.el | 51 + elisp/init-mu4e.el | 130 + elisp/init-org.el | 114 + elisp/init-package.el | 100 + elisp/init-parens.el | 116 + elisp/init-pdf.el | 60 + elisp/init-popup-kill-ring.el | 47 + elisp/init-projectile.el | 60 + elisp/init-pyim.el | 69 + elisp/init-python.el | 91 + elisp/init-quickrun.el | 49 + elisp/init-scroll.el | 58 + elisp/init-search.el | 114 + elisp/init-shell.el | 79 + elisp/init-theme.el | 79 + elisp/init-tramp.el | 62 + elisp/init-treemacs.el | 105 + elisp/init-ui-config.el | 103 + elisp/init-undo-tree.el | 49 + elisp/init-webdev.el | 81 + elisp/init-which-key.el | 52 + elisp/init-winner.el | 61 + elisp/init-yasnippet.el | 66 + elisp/init-zone.el | 59 + images/KEC_Dark_BK.png | Bin 0 -> 88588 bytes images/KEC_Dark_BK_Small.png | Bin 0 -> 94689 bytes images/KEC_Light_BK.png | Bin 0 -> 94162 bytes images/KEC_Light_BK_Small.png | Bin 0 -> 96313 bytes init.el | 232 + one-file-mode/bind-key.el | 413 + one-file-mode/c++1x-minor-mode.el | 56 + one-file-mode/doc-mode.el | 928 ++ one-file-mode/dockerfile-mode.el | 168 + one-file-mode/go-template-mode.el | 267 + one-file-mode/use-package.el | 1169 ++ one-file-mode/web-mode.el | 11830 ++++++++++++++++ site-elisp/aweshell | 1 + site-elisp/awesome-pair | 1 + site-elisp/color-rg | 1 + site-elisp/delete-block | 1 + site-elisp/emacs-application-framework | 1 + site-elisp/epaint | 1 + site-elisp/grep-dired | 1 + site-elisp/header2 | 1 + site-elisp/instant-rename-tag | 1 + site-elisp/leetcode | 1 + site-elisp/multi-term | 1 + site-elisp/snails | 1 + snippets/c++-mode/acc | 5 + snippets/c++-mode/accl | 8 + snippets/c++-mode/cls | 10 + snippets/c++-mode/dcast | 5 + snippets/c++-mode/dpcast | 5 + snippets/c++-mode/forc | 7 + snippets/c++-mode/scast | 5 + snippets/c++-mode/sct | 9 + snippets/c++-mode/spcast | 5 + snippets/c++-mode/sptr | 5 + snippets/c++-mode/todo | 5 + snippets/c++-mode/uptr | 5 + snippets/c++-mode/wptr | 5 + .../.yas-ignore-filenames-as-triggers | 0 snippets/latex-mode/.yas-make-groups | 0 snippets/latex-mode/.yas-parents | 1 + snippets/latex-mode/abstract.yasnippet | 9 + snippets/latex-mode/align.yasnippet | 9 + snippets/latex-mode/alignstar.yasnippet | 9 + snippets/latex-mode/array.yasnippet | 9 + snippets/latex-mode/article.yasnippet | 28 + snippets/latex-mode/beamer.yasnippet | 37 + snippets/latex-mode/begin.yasnippet | 10 + snippets/latex-mode/bib.yasnippet | 8 + snippets/latex-mode/big.yasnippet | 7 + snippets/latex-mode/bigop.yasnippet | 7 + snippets/latex-mode/binom.yasnippet | 7 + snippets/latex-mode/block.yasnippet | 9 + snippets/latex-mode/bold.yasnippet | 7 + snippets/latex-mode/case.yasnippet | 9 + snippets/latex-mode/cha.yasnippet | 9 + snippets/latex-mode/chastar.yasnippet | 8 + snippets/latex-mode/cite.yasnippet | 7 + snippets/latex-mode/coprod.yasnippet | 7 + snippets/latex-mode/desc.yasnippet | 9 + snippets/latex-mode/doc.yasnippet | 10 + snippets/latex-mode/em.yasnippet | 7 + snippets/latex-mode/enum.yasnippet | 9 + snippets/latex-mode/eq.yasnippet | 10 + snippets/latex-mode/eqs.yasnippet | 10 + snippets/latex-mode/fig.yasnippet | 12 + snippets/latex-mode/frac.yasnippet | 7 + snippets/latex-mode/frame.yasnippet | 9 + snippets/latex-mode/gls.yasnippet | 8 + snippets/latex-mode/graphics.yasnippet | 6 + snippets/latex-mode/href.yasnippet | 6 + snippets/latex-mode/int.yasnippet | 7 + snippets/latex-mode/it.yasnippet | 7 + snippets/latex-mode/itd.yasnippet | 7 + snippets/latex-mode/item.yasnippet | 9 + snippets/latex-mode/label.yasnippet | 7 + snippets/latex-mode/letter.yasnippet | 27 + snippets/latex-mode/lim.yasnippet | 7 + snippets/latex-mode/math.yasnippet | 9 + snippets/latex-mode/matrix.yasnippet | 11 + snippets/latex-mode/minipage.yasnippet | 9 + snippets/latex-mode/par.yasnippet | 9 + snippets/latex-mode/prod.yasnippet | 7 + snippets/latex-mode/ref.yasnippet | 7 + snippets/latex-mode/sc.yasnippet | 7 + snippets/latex-mode/sec.yasnippet | 9 + snippets/latex-mode/secstar.yasnippet | 8 + snippets/latex-mode/ssub.yasnippet | 9 + snippets/latex-mode/ssubstar.yasnippet | 8 + snippets/latex-mode/sub.yasnippet | 9 + snippets/latex-mode/subfig.yasnippet | 10 + snippets/latex-mode/substar.yasnippet | 8 + snippets/latex-mode/sum.yasnippet | 7 + snippets/latex-mode/table.yasnippet | 14 + snippets/latex-mode/tt.yasnippet | 7 + snippets/latex-mode/url.yasnippet | 7 + snippets/latex-mode/use.yasnippet | 7 + snippets/latex-mode/verb.yasnippet | 11 + 155 files changed, 20314 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 early-init.el create mode 100644 elisp/init-ace-window.el create mode 100644 elisp/init-all-the-icons.el create mode 100644 elisp/init-avy.el create mode 100644 elisp/init-cc.el create mode 100644 elisp/init-comment.el create mode 100644 elisp/init-company.el create mode 100644 elisp/init-const.el create mode 100644 elisp/init-crux.el create mode 100644 elisp/init-dashboard.el create mode 100644 elisp/init-dired.el create mode 100644 elisp/init-discover-my-major.el create mode 100644 elisp/init-dumb-jump.el create mode 100644 elisp/init-eaf.el create mode 100644 elisp/init-edit.el create mode 100644 elisp/init-ein.el create mode 100644 elisp/init-epaint.el create mode 100644 elisp/init-erc.el create mode 100644 elisp/init-ess.el create mode 100644 elisp/init-eww.el create mode 100644 elisp/init-flycheck.el create mode 100644 elisp/init-fonts.el create mode 100644 elisp/init-format.el create mode 100644 elisp/init-func.el create mode 100644 elisp/init-games.el create mode 100644 elisp/init-global-config.el create mode 100644 elisp/init-header.el create mode 100644 elisp/init-indent.el create mode 100644 elisp/init-java.el create mode 100644 elisp/init-latex.el create mode 100644 elisp/init-leetcode.el create mode 100644 elisp/init-lsp.el create mode 100644 elisp/init-magit.el create mode 100644 elisp/init-mu4e.el create mode 100644 elisp/init-org.el create mode 100644 elisp/init-package.el create mode 100644 elisp/init-parens.el create mode 100644 elisp/init-pdf.el create mode 100644 elisp/init-popup-kill-ring.el create mode 100644 elisp/init-projectile.el create mode 100644 elisp/init-pyim.el create mode 100644 elisp/init-python.el create mode 100644 elisp/init-quickrun.el create mode 100644 elisp/init-scroll.el create mode 100644 elisp/init-search.el create mode 100644 elisp/init-shell.el create mode 100644 elisp/init-theme.el create mode 100644 elisp/init-tramp.el create mode 100644 elisp/init-treemacs.el create mode 100644 elisp/init-ui-config.el create mode 100644 elisp/init-undo-tree.el create mode 100644 elisp/init-webdev.el create mode 100644 elisp/init-which-key.el create mode 100644 elisp/init-winner.el create mode 100644 elisp/init-yasnippet.el create mode 100644 elisp/init-zone.el create mode 100644 images/KEC_Dark_BK.png create mode 100644 images/KEC_Dark_BK_Small.png create mode 100644 images/KEC_Light_BK.png create mode 100644 images/KEC_Light_BK_Small.png create mode 100644 init.el create mode 100644 one-file-mode/bind-key.el create mode 100644 one-file-mode/c++1x-minor-mode.el create mode 100644 one-file-mode/doc-mode.el create mode 100644 one-file-mode/dockerfile-mode.el create mode 100644 one-file-mode/go-template-mode.el create mode 100644 one-file-mode/use-package.el create mode 100644 one-file-mode/web-mode.el create mode 160000 site-elisp/aweshell create mode 160000 site-elisp/awesome-pair create mode 160000 site-elisp/color-rg create mode 160000 site-elisp/delete-block create mode 160000 site-elisp/emacs-application-framework create mode 160000 site-elisp/epaint create mode 160000 site-elisp/grep-dired create mode 160000 site-elisp/header2 create mode 160000 site-elisp/instant-rename-tag create mode 160000 site-elisp/leetcode create mode 160000 site-elisp/multi-term create mode 160000 site-elisp/snails create mode 100644 snippets/c++-mode/acc create mode 100644 snippets/c++-mode/accl create mode 100644 snippets/c++-mode/cls create mode 100644 snippets/c++-mode/dcast create mode 100644 snippets/c++-mode/dpcast create mode 100644 snippets/c++-mode/forc create mode 100644 snippets/c++-mode/scast create mode 100644 snippets/c++-mode/sct create mode 100644 snippets/c++-mode/spcast create mode 100644 snippets/c++-mode/sptr create mode 100644 snippets/c++-mode/todo create mode 100644 snippets/c++-mode/uptr create mode 100644 snippets/c++-mode/wptr create mode 100644 snippets/latex-mode/.yas-ignore-filenames-as-triggers create mode 100644 snippets/latex-mode/.yas-make-groups create mode 100644 snippets/latex-mode/.yas-parents create mode 100644 snippets/latex-mode/abstract.yasnippet create mode 100644 snippets/latex-mode/align.yasnippet create mode 100644 snippets/latex-mode/alignstar.yasnippet create mode 100644 snippets/latex-mode/array.yasnippet create mode 100644 snippets/latex-mode/article.yasnippet create mode 100644 snippets/latex-mode/beamer.yasnippet create mode 100644 snippets/latex-mode/begin.yasnippet create mode 100644 snippets/latex-mode/bib.yasnippet create mode 100644 snippets/latex-mode/big.yasnippet create mode 100644 snippets/latex-mode/bigop.yasnippet create mode 100644 snippets/latex-mode/binom.yasnippet create mode 100644 snippets/latex-mode/block.yasnippet create mode 100644 snippets/latex-mode/bold.yasnippet create mode 100644 snippets/latex-mode/case.yasnippet create mode 100644 snippets/latex-mode/cha.yasnippet create mode 100644 snippets/latex-mode/chastar.yasnippet create mode 100644 snippets/latex-mode/cite.yasnippet create mode 100644 snippets/latex-mode/coprod.yasnippet create mode 100644 snippets/latex-mode/desc.yasnippet create mode 100644 snippets/latex-mode/doc.yasnippet create mode 100644 snippets/latex-mode/em.yasnippet create mode 100644 snippets/latex-mode/enum.yasnippet create mode 100644 snippets/latex-mode/eq.yasnippet create mode 100644 snippets/latex-mode/eqs.yasnippet create mode 100644 snippets/latex-mode/fig.yasnippet create mode 100644 snippets/latex-mode/frac.yasnippet create mode 100644 snippets/latex-mode/frame.yasnippet create mode 100644 snippets/latex-mode/gls.yasnippet create mode 100644 snippets/latex-mode/graphics.yasnippet create mode 100644 snippets/latex-mode/href.yasnippet create mode 100644 snippets/latex-mode/int.yasnippet create mode 100644 snippets/latex-mode/it.yasnippet create mode 100644 snippets/latex-mode/itd.yasnippet create mode 100644 snippets/latex-mode/item.yasnippet create mode 100644 snippets/latex-mode/label.yasnippet create mode 100644 snippets/latex-mode/letter.yasnippet create mode 100644 snippets/latex-mode/lim.yasnippet create mode 100644 snippets/latex-mode/math.yasnippet create mode 100644 snippets/latex-mode/matrix.yasnippet create mode 100644 snippets/latex-mode/minipage.yasnippet create mode 100644 snippets/latex-mode/par.yasnippet create mode 100644 snippets/latex-mode/prod.yasnippet create mode 100644 snippets/latex-mode/ref.yasnippet create mode 100644 snippets/latex-mode/sc.yasnippet create mode 100644 snippets/latex-mode/sec.yasnippet create mode 100644 snippets/latex-mode/secstar.yasnippet create mode 100644 snippets/latex-mode/ssub.yasnippet create mode 100644 snippets/latex-mode/ssubstar.yasnippet create mode 100644 snippets/latex-mode/sub.yasnippet create mode 100644 snippets/latex-mode/subfig.yasnippet create mode 100644 snippets/latex-mode/substar.yasnippet create mode 100644 snippets/latex-mode/sum.yasnippet create mode 100644 snippets/latex-mode/table.yasnippet create mode 100644 snippets/latex-mode/tt.yasnippet create mode 100644 snippets/latex-mode/url.yasnippet create mode 100644 snippets/latex-mode/use.yasnippet create mode 100644 snippets/latex-mode/verb.yasnippet diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..60f8cd3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +# Emacs file +*~ +amx-items +custom-set-variables.el +.python-environments +auto-save-list +elpa +.last-package-update-day +projectile.cache +projectile-bookmarks.eld +eshell/ +early-init-do-not-edit/ +places +transient/ +elpy/ +recentf +.cache diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..1c0701a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,36 @@ +[submodule "site-elisp\\color-rg"] + path = site-elisp\\color-rg + url = https://github.com/manateelazycat/color-rg.git +[submodule "site-elisp\\awesome-pair"] + path = site-elisp\\awesome-pair + url = https://github.com/manateelazycat/awesome-pair.git +[submodule "site-elisp\\header2"] + path = site-elisp\\header2 + url = https://github.com/emacsmirror/header2.git +[submodule "site-elisp\\grep-dired"] + path = site-elisp\\grep-dired + url = https://github.com/manateelazycat/grep-dired.git +[submodule "site-elisp\\leetcode"] + path = site-elisp\\leetcode + url = https://github.com/kaiwk/leetcode.el.git +[submodule "site-elisp\\delete-block"] + path = site-elisp\\delete-block + url = https://github.com/manateelazycat/delete-block.git +[submodule "site-elisp\\instant-rename-tag"] + path = site-elisp\\instant-rename-tag + url = https://github.com/manateelazycat/instant-rename-tag.git +[submodule "site-elisp\\emacs-application-framework"] + path = site-elisp\\emacs-application-framework + url = https://github.com/manateelazycat/emacs-application-framework.git +[submodule "site-elisp\\snails"] + path = site-elisp\\snails + url = https://github.com/manateelazycat/snails.git +[submodule "site-elisp\\multi-term"] + path = site-elisp\\multi-term + url = https://github.com/manateelazycat/multi-term.git +[submodule "site-elisp\\epaint"] + path = site-elisp\\epaint + url = https://github.com/chuntaro/epaint.git +[submodule "site-elisp\\aweshell"] + path = site-elisp\\aweshell + url = https://github.com/MatthewZMD/aweshell.git diff --git a/early-init.el b/early-init.el new file mode 100644 index 0000000..65cda0a --- /dev/null +++ b/early-init.el @@ -0,0 +1,68 @@ +;;; early-init.el --- -*- lexical-binding: t -*- +;; +;; Filename: early-init.el +;; Description: Early initialization +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Sun Jun 9 17:58:05 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Tue Sep 17 01:13:45 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d init early-init +;; Compatibility: emacs-version >= 27 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; Emacs27 introduces early-init.el, which is run before init.el, +;; before package and UI initialization happens. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; DeferGC +(setq gc-cons-threshold 100000000) +;; -DeferGC + +;; UnsetPES +(setq package-enable-at-startup nil) +;; -UnsetPES + +;; UnsetFNHA +(defvar file-name-handler-alist-original file-name-handler-alist) +(setq file-name-handler-alist nil) +;; -UnsetFNHA + +;; UnsetSRF +(setq site-run-file nil) +;; -UnsetSRF + +;; DisableUnnecessaryInterface +(menu-bar-mode -1) +(unless (and (display-graphic-p) (eq system-type 'darwin)) + (push '(menu-bar-lines . 0) default-frame-alist)) +(push '(tool-bar-lines . 0) default-frame-alist) +(push '(vertical-scroll-bars) default-frame-alist) +;; -DisableUnnecessaryInterface + +(provide 'early-init) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; early-init.el ends here diff --git a/elisp/init-ace-window.el b/elisp/init-ace-window.el new file mode 100644 index 0000000..7909616 --- /dev/null +++ b/elisp/init-ace-window.el @@ -0,0 +1,47 @@ +;;; init-ace-window.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-ace-window.el +;; Description: Initialize Ace-Window +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Tue Apr 23 10:00:42 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Aug 8 16:02:47 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d ace-window +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes ace-window +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; AceWindowPac +(use-package ace-window + :bind ("C-x C-o" . ace-window)) +;; -AceWindowPac + +(provide 'init-ace-window) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-ace-window.el ends here diff --git a/elisp/init-all-the-icons.el b/elisp/init-all-the-icons.el new file mode 100644 index 0000000..1d197f3 --- /dev/null +++ b/elisp/init-all-the-icons.el @@ -0,0 +1,168 @@ +;;; init-all-the-icons.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-all-the-icons.el +;; Description: Initialize All-The-Icons +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Mar 14 17:06:08 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Tue Dec 24 11:47:45 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d all-the-icons +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes all-the-icons, all-the-icons-dired, all-the-icons-ivy +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-const)) + +(use-package all-the-icons + :if *sys/gui* + :config + (with-no-warnings + ;; FIXME: Align the directory icons + ;; @see https://github.com/domtronn/all-the-icons.el/pull/173 + (defun all-the-icons-icon-for-dir (dir &optional chevron padding) + "Format an icon for DIR with CHEVRON similar to tree based directories." + (let* ((matcher (all-the-icons-match-to-alist (file-name-base (directory-file-name dir)) all-the-icons-dir-icon-alist)) + (path (expand-file-name dir)) + (chevron (if chevron (all-the-icons-octicon (format "chevron-%s" chevron) :height 0.8 :v-adjust -0.1) "")) + (padding (or padding "\t")) + (icon (cond + ((file-symlink-p path) + (all-the-icons-octicon "file-symlink-directory" :height 1.0 :v-adjust 0.0)) + ((all-the-icons-dir-is-submodule path) + (all-the-icons-octicon "file-submodule" :height 1.0 :v-adjust 0.0)) + ((file-exists-p (format "%s/.git" path)) + (format "%s" (all-the-icons-octicon "repo" :height 1.1 :v-adjust 0.0))) + (t (apply (car matcher) (list (cadr matcher) :v-adjust 0.0)))))) + (format "%s%s%s%s%s" padding chevron padding icon padding))) + + (defun all-the-icons-reset () + "Reset (unmemoize/memoize) the icons." + (interactive) + (dolist (f '(all-the-icons-icon-for-file + all-the-icons-icon-for-mode + all-the-icons-icon-for-url + all-the-icons-icon-family-for-file + all-the-icons-icon-family-for-mode + all-the-icons-icon-family)) + (ignore-errors + (memoize-restore f) + (memoize f))) + (message "Reset all-the-icons"))) + + (add-to-list 'all-the-icons-mode-icon-alist + '(bongo-playlist-mode all-the-icons-material "playlist_play" :height 1.2 :v-adjust -0.2 :face 'all-the-icons-green)) + (add-to-list 'all-the-icons-mode-icon-alist + '(bongo-library-mode all-the-icons-material "library_music" :height 1.1 :v-adjust -0.2 :face 'all-the-icons-dgreen)) + (add-to-list 'all-the-icons-mode-icon-alist + '(gnus-group-mode all-the-icons-fileicon "gnu" :face 'all-the-icons-silver)) + (add-to-list 'all-the-icons-mode-icon-alist + '(gnus-summary-mode all-the-icons-octicon "inbox" :height 1.0 :v-adjust 0.0 :face 'all-the-icons-orange)) + (add-to-list 'all-the-icons-mode-icon-alist + '(gnus-article-mode all-the-icons-octicon "mail" :height 1.1 :v-adjust 0.0 :face 'all-the-icons-lblue)) + (add-to-list 'all-the-icons-mode-icon-alist + '(message-mode all-the-icons-octicon "mail" :height 1.1 :v-adjust 0.0 :face 'all-the-icons-lblue)) + (add-to-list 'all-the-icons-mode-icon-alist + '(diff-mode all-the-icons-octicon "git-compare" :v-adjust 0.0 :face all-the-icons-lred)) + (add-to-list 'all-the-icons-mode-icon-alist + '(flycheck-error-list-mode all-the-icons-octicon "checklist" :height 1.1 :v-adjust 0.0 :face all-the-icons-lred)) + (add-to-list 'all-the-icons-mode-icon-alist + '(elfeed-search-mode all-the-icons-faicon "rss-square" :v-adjust -0.1 :face all-the-icons-orange)) + (add-to-list 'all-the-icons-mode-icon-alist + '(elfeed-show-mode all-the-icons-octicon "rss" :height 1.1 :v-adjust 0.0 :face all-the-icons-lorange)) + (add-to-list 'all-the-icons-mode-icon-alist + '(newsticker-mode all-the-icons-faicon "rss-square" :v-adjust -0.1 :face all-the-icons-orange)) + (add-to-list 'all-the-icons-mode-icon-alist + '(newsticker-treeview-mode all-the-icons-faicon "rss-square" :v-adjust -0.1 :face all-the-icons-orange)) + (add-to-list 'all-the-icons-mode-icon-alist + '(newsticker-treeview-list-mode all-the-icons-octicon "rss" :height 1.1 :v-adjust 0.0 :face all-the-icons-orange)) + (add-to-list 'all-the-icons-mode-icon-alist + '(newsticker-treeview-item-mode all-the-icons-octicon "rss" :height 1.1 :v-adjust 0.0 :face all-the-icons-lorange)) + (add-to-list 'all-the-icons-icon-alist + '("\\.[bB][iI][nN]$" all-the-icons-octicon "file-binary" :v-adjust 0.0 :face all-the-icons-yellow)) + (add-to-list 'all-the-icons-icon-alist + '("\\.c?make$" all-the-icons-fileicon "gnu" :face all-the-icons-dorange)) + (add-to-list 'all-the-icons-icon-alist + '("\\.conf$" all-the-icons-octicon "settings" :v-adjust 0.0 :face all-the-icons-yellow)) + (add-to-list 'all-the-icons-icon-alist + '("\\.toml$" all-the-icons-octicon "settings" :v-adjust 0.0 :face all-the-icons-yellow)) + (add-to-list 'all-the-icons-mode-icon-alist + '(conf-mode all-the-icons-octicon "settings" :v-adjust 0.0 :face all-the-icons-yellow)) + (add-to-list 'all-the-icons-mode-icon-alist + '(conf-space-mode all-the-icons-octicon "settings" :v-adjust 0.0 :face all-the-icons-yellow)) + (add-to-list 'all-the-icons-mode-icon-alist + '(forge-topic-mode all-the-icons-alltheicon "git" :face all-the-icons-blue)) + (add-to-list 'all-the-icons-icon-alist + '("\\.xpm$" all-the-icons-octicon "file-media" :v-adjust 0.0 :face all-the-icons-dgreen)) + (add-to-list 'all-the-icons-mode-icon-alist + '(help-mode all-the-icons-faicon "info-circle" :height 1.1 :v-adjust -0.1 :face all-the-icons-purple)) + (add-to-list 'all-the-icons-mode-icon-alist + '(helpful-mode all-the-icons-faicon "info-circle" :height 1.1 :v-adjust -0.1 :face all-the-icons-purple)) + (add-to-list 'all-the-icons-mode-icon-alist + '(Info-mode all-the-icons-faicon "info-circle" :height 1.1 :v-adjust -0.1)) + (add-to-list 'all-the-icons-icon-alist + '("NEWS$" all-the-icons-faicon "newspaper-o" :height 0.9 :v-adjust -0.2)) + (add-to-list 'all-the-icons-icon-alist + '("Cask\\'" all-the-icons-fileicon "elisp" :height 1.0 :v-adjust -0.2 :face all-the-icons-blue)) + (add-to-list 'all-the-icons-mode-icon-alist + '(cask-mode all-the-icons-fileicon "elisp" :height 1.0 :v-adjust -0.2 :face all-the-icons-blue)) + (add-to-list 'all-the-icons-icon-alist + '(".*\\.ipynb\\'" all-the-icons-fileicon "jupyter" :height 1.2 :face all-the-icons-orange)) + (add-to-list 'all-the-icons-mode-icon-alist + '(ein:notebooklist-mode all-the-icons-faicon "book" :face all-the-icons-lorange)) + (add-to-list 'all-the-icons-mode-icon-alist + '(ein:notebook-mode all-the-icons-fileicon "jupyter" :height 1.2 :face all-the-icons-orange)) + (add-to-list 'all-the-icons-mode-icon-alist + '(ein:notebook-multilang-mode all-the-icons-fileicon "jupyter" :height 1.2 :face all-the-icons-dorange)) + (add-to-list 'all-the-icons-icon-alist + '("\\.epub\\'" all-the-icons-faicon "book" :height 1.0 :v-adjust -0.1 :face all-the-icons-green)) + (add-to-list 'all-the-icons-mode-icon-alist + '(nov-mode all-the-icons-faicon "book" :height 1.0 :v-adjust -0.1 :face all-the-icons-green)) + (add-to-list 'all-the-icons-mode-icon-alist + '(gfm-mode all-the-icons-octicon "markdown" :face all-the-icons-lblue))) + +;; ATIDiredPac +(use-package all-the-icons-dired + :after all-the-icons + :if *sys/gui* + :diminish + :custom-face + (all-the-icons-dired-dir-face ((t `(:foreground ,(face-background 'default))))) + :hook (dired-mode . all-the-icons-dired-mode) + :config + ;; Workaround for all-the-icons bug until PR merged https://github.com/domtronn/all-the-icons.el/pull/150 + (when (require 'all-the-icons nil 'noerror) + (setq all-the-icons-mode-icon-alist + (delete '(erc-mode all-the-icons-faicon "commenting-o" :height 1.0 :v-adjust 0.0 :face all-the-icons-white) all-the-icons-mode-icon-alist)) + (add-to-list 'all-the-icons-mode-icon-alist '(erc-mode all-the-icons-faicon "commenting-o" :height 1.0 :v-adjust 0.0)))) +;; -ATIDiredPac + +(provide 'init-all-the-icons) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-all-the-icons.el ends here diff --git a/elisp/init-avy.el b/elisp/init-avy.el new file mode 100644 index 0000000..43d2445 --- /dev/null +++ b/elisp/init-avy.el @@ -0,0 +1,58 @@ +;;; init-avy.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-avy.el +;; Description: Initialize Avy +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Mar 14 11:12:49 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Nov 7 05:55:40 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d avy +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes avy +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-global-config)) + +;; AvyPac +(use-package avy + :defer t + :bind + (("C-z c" . avy-goto-char-timer) + ("C-z l" . avy-goto-line)) + :custom + (avy-timeout-seconds 0.3) + (avy-style 'pre) + :custom-face + (avy-lead-face ((t (:background "#51afef" :foreground "#870000" :weight bold))))); +;; -AvyPac + +(provide 'init-avy) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-avy.el ends here diff --git a/elisp/init-cc.el b/elisp/init-cc.el new file mode 100644 index 0000000..9e0f66b --- /dev/null +++ b/elisp/init-cc.el @@ -0,0 +1,82 @@ +;;; init-cc.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-cc.el +;; Description: Initialize C family languages +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Fri Mar 15 10:58:29 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Dec 26 02:07:34 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d c c++ go ccls +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initialize ccls modern-cpp-font-lock go-mode +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-const)) + +;; CCLSPac +(use-package ccls + :defer t + :if (not *sys/win32*) + :hook ((c-mode c++-mode objc-mode) . + (lambda () (require 'ccls) (lsp))) + :custom + (ccls-executable (executable-find "ccls")) ; Add ccls to path if you haven't done so + (ccls-sem-highlight-method 'font-lock) + (ccls-enable-skipped-ranges nil) + :config + (lsp-register-client + (make-lsp-client + :new-connection (lsp-tramp-connection (cons ccls-executable ccls-args)) + :major-modes '(c-mode c++-mode cuda-mode objc-mode) + :server-id 'ccls-remote + :multi-root nil + :remote? t + :notification-handlers + (lsp-ht ("$ccls/publishSkippedRanges" #'ccls--publish-skipped-ranges) + ("$ccls/publishSemanticHighlight" #'ccls--publish-semantic-highlight)) + :initialization-options (lambda () ccls-initialization-options) + :library-folders-fn nil))) +;; -CCLSPac + +;; CPPFontLockPac +(use-package modern-cpp-font-lock + :diminish t + :init (modern-c++-font-lock-global-mode t)) +;; -CPPFontLockPac + +;; GoPac +(use-package go-mode + :mode "\\.go\\'" + :hook (before-save . gofmt-before-save)) +;; -GoPac + +(provide 'init-cc) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-cc.el ends here diff --git a/elisp/init-comment.el b/elisp/init-comment.el new file mode 100644 index 0000000..9200a5e --- /dev/null +++ b/elisp/init-comment.el @@ -0,0 +1,49 @@ +;;; init-comment.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-comment.el +;; Description: Initialize Evil-Nerd-Commenter +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Fri Apr 5 00:21:58 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Wed Oct 16 16:44:25 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d evil-nerd-commenter +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes evil-nerd-commenter +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; EvilNerdCommenPac +(use-package evil-nerd-commenter + :bind + (("C-c M-;" . c-toggle-comment-style) + ("M-;" . evilnc-comment-or-uncomment-lines))) +;; -EvilNerdCommenPac + +(provide 'init-comment) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-comment.el ends here diff --git a/elisp/init-company.el b/elisp/init-company.el new file mode 100644 index 0000000..d9db166 --- /dev/null +++ b/elisp/init-company.el @@ -0,0 +1,224 @@ +;;; init-company.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-company.el +;; Description: Initialize Company +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Fri Mar 15 10:02:00 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Fri Dec 27 22:11:06 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d company company-tabnine +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes company +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-const)) + +;; ComPac +(use-package company + :diminish company-mode + :hook ((prog-mode LaTeX-mode latex-mode ess-r-mode) . company-mode) + :bind + (:map company-active-map + ([tab] . smarter-yas-expand-next-field-complete) + ("TAB" . smarter-yas-expand-next-field-complete)) + ("M-/" . company-complete) + :custom + (company-minimum-prefix-length 1) + (company-tooltip-align-annotations t) + (company-begin-commands '(self-insert-command)) + (company-require-match 'never) + ;; Don't use company in the following modes + (company-global-modes '(not shell-mode eaf-mode)) + ;; Trigger completion immediately. + (company-idle-delay 0.1) + ;; Number the candidates (use M-1, M-2 etc to select completions). + (company-show-numbers t) + :config + (unless *clangd* (delete 'company-clang company-backends)) + (global-company-mode 1) + (defun smarter-yas-expand-next-field-complete () + "Try to `yas-expand' and `yas-next-field' at current cursor position. + +If failed try to complete the common part with `company-complete-common'" + (interactive) + (if yas-minor-mode + (let ((old-point (point)) + (old-tick (buffer-chars-modified-tick))) + (yas-expand) + (when (and (eq old-point (point)) + (eq old-tick (buffer-chars-modified-tick))) + (ignore-errors (yas-next-field)) + (when (and (eq old-point (point)) + (eq old-tick (buffer-chars-modified-tick))) + (company-complete-common)))) + (company-complete-common)))) +;; -ComPac + +;; CompanyLSPPac +;; (use-package company-lsp +;; :defer t +;; :custom (company-lsp-cache-candidates 'auto)) +;; ;; -CompanyLSPPac + +;; CompanyTabNinePac +;; (use-package company-tabnine +;; :defer 1 +;; :custom +;; (company-tabnine-max-num-results 9) +;; :bind +;; (("M-q" . company-other-backend) +;; ("C-z t" . company-tabnine)) +;; :hook +;; (lsp-after-open . (lambda () +;; (setq company-tabnine-max-num-results 3) +;; (add-to-list 'company-transformers 'company//sort-by-tabnine t) +;; (add-to-list 'company-backends '(company-lsp :with company-tabnine :separate)))) +;; (kill-emacs . company-tabnine-kill-process) +;; :config +;; ;; Enable TabNine on default +;; (add-to-list 'company-backends #'company-tabnine) + +;; ;; Integrate company-tabnine with lsp-mode +;; (defun company//sort-by-tabnine (candidates) +;; (if (or (functionp company-backend) +;; (not (and (listp company-backend) (memq 'company-tabnine company-backend)))) +;; candidates +;; (let ((candidates-table (make-hash-table :test #'equal)) +;; candidates-lsp +;; candidates-tabnine) +;; (dolist (candidate candidates) +;; (if (eq (get-text-property 0 'company-backend candidate) +;; 'company-tabnine) +;; (unless (gethash candidate candidates-table) +;; (push candidate candidates-tabnine)) +;; (push candidate candidates-lsp) +;; (puthash candidate t candidates-table))) +;; (setq candidates-lsp (nreverse candidates-lsp)) +;; (setq candidates-tabnine (nreverse candidates-tabnine)) +;; (nconc (seq-take candidates-tabnine 3) +;; (seq-take candidates-lsp 6)))))) +;; ;; -CompanyTabNinePac + +;; CompanyBoxPac +(use-package company-box + :diminish + :functions (my-company-box--make-line + my-company-box-icons--elisp) + :commands (company-box--get-color + company-box--resolve-colors + company-box--add-icon + company-box--apply-color + company-box--make-line + company-box-icons--elisp) + :hook (company-mode . company-box-mode) + :custom + (company-box-backends-colors nil) + (company-box-show-single-candidate t) + (company-box-max-candidates 50) + (company-box-doc-delay 0.3) + :config + ;; Support `company-common' + (defun my-company-box--make-line (candidate) + (-let* (((candidate annotation len-c len-a backend) candidate) + (color (company-box--get-color backend)) + ((c-color a-color i-color s-color) (company-box--resolve-colors color)) + (icon-string (and company-box--with-icons-p (company-box--add-icon candidate))) + (candidate-string (concat (propertize (or company-common "") 'face 'company-tooltip-common) + (substring (propertize candidate 'face 'company-box-candidate) (length company-common) nil))) + (align-string (when annotation + (concat " " (and company-tooltip-align-annotations + (propertize " " 'display `(space :align-to (- right-fringe ,(or len-a 0) 1))))))) + (space company-box--space) + (icon-p company-box-enable-icon) + (annotation-string (and annotation (propertize annotation 'face 'company-box-annotation))) + (line (concat (unless (or (and (= space 2) icon-p) (= space 0)) + (propertize " " 'display `(space :width ,(if (or (= space 1) (not icon-p)) 1 0.75)))) + (company-box--apply-color icon-string i-color) + (company-box--apply-color candidate-string c-color) + align-string + (company-box--apply-color annotation-string a-color))) + (len (length line))) + (add-text-properties 0 len (list 'company-box--len (+ len-c len-a) + 'company-box--color s-color) + line) + line)) + (advice-add #'company-box--make-line :override #'my-company-box--make-line) + + ;; Prettify icons + (defun my-company-box-icons--elisp (candidate) + (when (derived-mode-p 'emacs-lisp-mode) + (let ((sym (intern candidate))) + (cond ((fboundp sym) 'Function) + ((featurep sym) 'Module) + ((facep sym) 'Color) + ((boundp sym) 'Variable) + ((symbolp sym) 'Text) + (t . nil))))) + (advice-add #'company-box-icons--elisp :override #'my-company-box-icons--elisp) + + (when (and *sys/gui* + (require 'all-the-icons nil t)) + (declare-function all-the-icons-faicon 'all-the-icons) + (declare-function all-the-icons-material 'all-the-icons) + (declare-function all-the-icons-octicon 'all-the-icons) + (setq company-box-icons-all-the-icons + `((Unknown . ,(all-the-icons-material "find_in_page" :height 0.85 :v-adjust -0.2)) + (Text . ,(all-the-icons-faicon "text-width" :height 0.8 :v-adjust -0.05)) + (Method . ,(all-the-icons-faicon "cube" :height 0.8 :v-adjust -0.05 :face 'all-the-icons-purple)) + (Function . ,(all-the-icons-faicon "cube" :height 0.8 :v-adjust -0.05 :face 'all-the-icons-purple)) + (Constructor . ,(all-the-icons-faicon "cube" :height 0.8 :v-adjust -0.05 :face 'all-the-icons-purple)) + (Field . ,(all-the-icons-octicon "tag" :height 0.8 :v-adjust 0 :face 'all-the-icons-lblue)) + (Variable . ,(all-the-icons-octicon "tag" :height 0.8 :v-adjust 0 :face 'all-the-icons-lblue)) + (Class . ,(all-the-icons-material "settings_input_component" :height 0.85 :v-adjust -0.2 :face 'all-the-icons-orange)) + (Interface . ,(all-the-icons-material "share" :height 0.85 :v-adjust -0.2 :face 'all-the-icons-lblue)) + (Module . ,(all-the-icons-material "view_module" :height 0.85 :v-adjust -0.2 :face 'all-the-icons-lblue)) + (Property . ,(all-the-icons-faicon "wrench" :height 0.8 :v-adjust -0.05)) + (Unit . ,(all-the-icons-material "settings_system_daydream" :height 0.85 :v-adjust -0.2)) + (Value . ,(all-the-icons-material "format_align_right" :height 0.85 :v-adjust -0.2 :face 'all-the-icons-lblue)) + (Enum . ,(all-the-icons-material "storage" :height 0.85 :v-adjust -0.2 :face 'all-the-icons-orange)) + (Keyword . ,(all-the-icons-material "filter_center_focus" :height 0.85 :v-adjust -0.2)) + (Snippet . ,(all-the-icons-material "format_align_center" :height 0.85 :v-adjust -0.2)) + (Color . ,(all-the-icons-material "palette" :height 0.85 :v-adjust -0.2)) + (File . ,(all-the-icons-faicon "file-o" :height 0.85 :v-adjust -0.05)) + (Reference . ,(all-the-icons-material "collections_bookmark" :height 0.85 :v-adjust -0.2)) + (Folder . ,(all-the-icons-faicon "folder-open" :height 0.85 :v-adjust -0.05)) + (EnumMember . ,(all-the-icons-material "format_align_right" :height 0.85 :v-adjust -0.2 :face 'all-the-icons-lblue)) + (Constant . ,(all-the-icons-faicon "square-o" :height 0.85 :v-adjust -0.05)) + (Struct . ,(all-the-icons-material "settings_input_component" :height 0.85 :v-adjust -0.2 :face 'all-the-icons-orange)) + (Event . ,(all-the-icons-faicon "bolt" :height 0.8 :v-adjust -0.05 :face 'all-the-icons-orange)) + (Operator . ,(all-the-icons-material "control_point" :height 0.85 :v-adjust -0.2)) + (TypeParameter . ,(all-the-icons-faicon "arrows" :height 0.8 :v-adjust -0.05)) + (Template . ,(all-the-icons-material "format_align_center" :height 0.85 :v-adjust -0.2))) + company-box-icons-alist 'company-box-icons-all-the-icons))) +;; -CompanyBoxPac + +(provide 'init-company) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-company.el ends here diff --git a/elisp/init-const.el b/elisp/init-const.el new file mode 100644 index 0000000..21a7449 --- /dev/null +++ b/elisp/init-const.el @@ -0,0 +1,112 @@ +;;; init-const.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-const.el +;; Description: Initialize Constants +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Mon Mar 18 14:20:54 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Mon Dec 9 20:49:39 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d constants +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes constants +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; UserInfo +(setq user-full-name "Mikaël Capelle") +(setq user-mail-address "capelle.mikael@gmail.com") +;; -UserInfo + +;; Consts +(defconst *sys/gui* + (display-graphic-p) + "Are we running on a GUI Emacs?") + +(defconst *sys/win32* + (eq system-type 'windows-nt) + "Are we running on a WinTel system?") + +(defconst *sys/linux* + (eq system-type 'gnu/linux) + "Are we running on a GNU/Linux system?") + +(defconst *sys/mac* + (eq system-type 'darwin) + "Are we running on a Mac system?") + +(defconst *sys/root* + (string-equal "root" (getenv "USER")) + "Are you a ROOT user?") + +(defconst *rg* + (executable-find "rg") + "Do we have ripgrep?") + +(defconst *python* + (executable-find "python") + "Do we have python?") + +(defconst *python3* + (executable-find "python3") + "Do we have python3?") + +(defconst *tr* + (executable-find "tr") + "Do we have tr?") + +(defconst *mvn* + (executable-find "mvn") + "Do we have Maven?") + +(defconst *clangd* + (or (executable-find "clangd") ;; usually + (executable-find "/usr/local/opt/llvm/bin/clangd")) ;; macOS + "Do we have clangd?") + +(defconst *gcc* + (executable-find "gcc") + "Do we have gcc?") + +(defconst *git* + (executable-find "git") + "Do we have git?") + +(defconst *pdflatex* + (executable-find "pdflatex") + "Do we have pdflatex?") + +(defconst *eaf-env* + (and *sys/linux* *sys/gui* *python3* + (executable-find "pip") + (not (equal (shell-command-to-string "pip freeze | grep '^PyQt\\|PyQtWebEngine'") ""))) + "Check basic requirements for EAF to run.") +;; -Consts + +(provide 'init-const) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-const.el ends here diff --git a/elisp/init-crux.el b/elisp/init-crux.el new file mode 100644 index 0000000..c3b0757 --- /dev/null +++ b/elisp/init-crux.el @@ -0,0 +1,56 @@ +;;; init-crux.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-crux.el +;; Description: Initialize Crux +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Tue Dec 24 13:15:38 2019 (-0500) +;; Version: 2.0.0 +;; Last-Updated: Thu Dec 26 22:02:32 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d crux +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes Crux +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; CruxPac +(use-package crux + :bind + (("C-a" . crux-move-beginning-of-line) + ("C-x 4 t" . crux-transpose-windows) + ("C-x K" . crux-kill-other-buffers) + ("C-k" . crux-smart-kill-line)) + :config + (crux-with-region-or-buffer indent-region) + (crux-with-region-or-buffer untabify) + (crux-with-region-or-point-to-eol kill-ring-save) + (defalias 'rename-file-and-buffer #'crux-rename-file-and-buffer)) +;; -CruxPac + +(provide 'init-crux) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-crux.el ends here diff --git a/elisp/init-dashboard.el b/elisp/init-dashboard.el new file mode 100644 index 0000000..253c911 --- /dev/null +++ b/elisp/init-dashboard.el @@ -0,0 +1,91 @@ +;;; init-dashboard.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-dashboard.el +;; Description: Initialize Dashboard +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Mar 14 17:21:46 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Mon Dec 23 18:19:44 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d dashboard +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes dashboard +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; DashboardPac +(use-package dashboard + :demand + :diminish (dashboard-mode page-break-lines-mode) + :bind ("C-z d" . open-dashboard) + :custom + (dashboard-banner-logo-title "Close the world. Open the nExt.") + (dashboard-startup-banner + (expand-file-name "images/KEC_Dark_BK_Small.png" user-emacs-directory)) + (dashboard-items '((recents . 7) + (bookmarks . 7) + (agenda . 5))) + (dashboard-set-heading-icons t) + (dashboard-set-navigator t) + (initial-buffer-choice (lambda () (get-buffer dashboard-buffer-name))) + (dashboard-navigator-buttons + (if (featurep 'all-the-icons) + `(((,(all-the-icons-octicon "mark-github" :height 1.1 :v-adjust -0.05) + "M-EMACS" "Browse M-EMACS Homepage" + (lambda (&rest _) (browse-url "https://github.com/MatthewZMD/.emacs.d"))) + (,(all-the-icons-fileicon "elisp" :height 1.0 :v-adjust -0.1) + "Configuration" "" (lambda (&rest _) (edit-configs))))) + `((("" "M-EMACS" "Browse M-EMACS Homepage" + (lambda (&rest _) (browse-url "https://github.com/MatthewZMD/.emacs.d"))) + ("" "Configuration" "" (lambda (&rest _) (edit-configs))))))) + :custom-face + (dashboard-banner-logo-title ((t (:family "Love LetterTW" :height 123)))) + :config + (dashboard-modify-heading-icons '((recents . "file-text") + (bookmarks . "book"))) + (dashboard-setup-startup-hook) + ;; Open Dashboard function + (defun open-dashboard () + "Open the *dashboard* buffer and jump to the first widget." + (interactive) + (if (get-buffer dashboard-buffer-name) + (kill-buffer dashboard-buffer-name)) + (dashboard-insert-startupify-lists) + (switch-to-buffer dashboard-buffer-name) + (goto-char (point-min)) + (delete-other-windows))) +;; -DashboardPac + +;; PBLPac +(use-package page-break-lines + :diminish + :init (global-page-break-lines-mode)) +;; -PBLPac + +(provide 'init-dashboard) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-dashboard.el ends here diff --git a/elisp/init-dired.el b/elisp/init-dired.el new file mode 100644 index 0000000..2076af6 --- /dev/null +++ b/elisp/init-dired.el @@ -0,0 +1,102 @@ +;;; init-dired.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-dired.el +;; Description: Initialize Dired and Related Configurations +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Mar 14 11:37:00 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Wed Dec 25 02:33:09 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d dired auto-save +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes dired, super-save, disk-usage +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; DiredPackage +(use-package dired + :ensure nil + :bind + (("C-x C-j" . dired-jump) + ("C-x j" . dired-jump-other-window)) + :custom + ;; Always delete and copy recursively + (dired-recursive-deletes 'always) + (dired-recursive-copies 'always) + ;; Auto refresh Dired, but be quiet about it + (global-auto-revert-non-file-buffers t) + (auto-revert-verbose nil) + ;; Quickly copy/move file in Dired + (dired-dwim-target t) + ;; Move files to trash when deleting + (delete-by-moving-to-trash t) + ;; Load the newest version of a file + (load-prefer-newer t) + ;; Detect external file changes and auto refresh file + (auto-revert-use-notify nil) + (auto-revert-interval 3) ; Auto revert every 3 sec + :config + ;; Enable global auto-revert + (global-auto-revert-mode t) + ;; Reuse same dired buffer, to prevent numerous buffers while navigating in dired + (put 'dired-find-alternate-file 'disabled nil) + :hook + (dired-mode . (lambda () + (local-set-key (kbd "") #'dired-find-alternate-file) + (local-set-key (kbd "RET") #'dired-find-alternate-file) + (local-set-key (kbd "^") + (lambda () (interactive) (find-alternate-file "..")))))) +;; -DiredPackage + +;; DiskUsage +(use-package disk-usage + :commands (disk-usage)) +;; -DiskUsage + +;; SuperSave +(use-package super-save + :diminish + :custom + (super-save-auto-save-when-idle t) + (auto-save-default nil) + (make-backup-files nil) + :config + (super-save-mode 1)) +;; -SuperSave + +;; SaveAllBuffers +(defun save-all-buffers () + "Instead of `save-buffer', save all opened buffers by calling `save-some-buffers' with ARG t." + (interactive) + (save-some-buffers t)) +(global-set-key (kbd "C-x C-s") nil) +(global-set-key (kbd "C-x C-s") #'save-all-buffers) +;; -SaveAllBuffers + +(provide 'init-dired) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-dired.el ends here diff --git a/elisp/init-discover-my-major.el b/elisp/init-discover-my-major.el new file mode 100644 index 0000000..4e6a5ca --- /dev/null +++ b/elisp/init-discover-my-major.el @@ -0,0 +1,47 @@ +;;; init-discover-my-major.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-discover-my-major.el +;; Description: Initialize Discover-My-Major +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Mar 14 15:38:29 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Aug 8 16:05:23 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d discover-my-major +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes discover-my-major +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; DiscMyMajor +(use-package discover-my-major + :bind ("C-h C-m" . discover-my-major)) +;; -DiscMyMajor + +(provide 'init-discover-my-major) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-discover-my-major.el ends here diff --git a/elisp/init-dumb-jump.el b/elisp/init-dumb-jump.el new file mode 100644 index 0000000..90a8e97 --- /dev/null +++ b/elisp/init-dumb-jump.el @@ -0,0 +1,52 @@ +;;; init-dumb-jump.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-dumb-jump.el +;; Description: Initialize Dumb Jump +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Fri Mar 15 10:11:21 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Sat Aug 24 22:07:00 2019 (+0000) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes dumb-jump +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; DumbJump +(use-package dumb-jump + :bind + (:map prog-mode-map + (("C-c C-o" . dumb-jump-go-other-window) + ("C-c C-j" . dumb-jump-go) + ("C-c C-i" . dumb-jump-go-prompt))) + :custom (dumb-jump-selector 'ivy)) +;; -DumbJump + +(provide 'init-dumb-jump) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-dumb-jump.el ends here diff --git a/elisp/init-eaf.el b/elisp/init-eaf.el new file mode 100644 index 0000000..0f0a88d --- /dev/null +++ b/elisp/init-eaf.el @@ -0,0 +1,67 @@ +;;; init-eaf.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-eaf.el +;; Description: Initialize Emacs Application Framework +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Tue Jun 4 00:26:09 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Fri Dec 27 22:07:41 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d pdf-tools +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes Emacs Application Framework +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-const)) + +;; EAFPac +(use-package eaf + :load-path (lambda () (expand-file-name "site-elisp/emacs-application-framework" user-emacs-directory)) + :if *eaf-env* + :custom + (eaf-find-alternate-file-in-dired t) + (browse-url-browser-function 'eaf-open-browser) ;; Make EAF Browser my default browser + :config + (defalias 'browse-web #'eaf-open-browser) + ;; I already bind "RET", "", "^" to `dired-find-alternate-file' in `init-dired.el'. + ;; Comment this line out of you don't want to use EAF to open available files in dired. + ;; (global-set-key [remap dired-find-alternate-file] #'eaf-file-open-in-dired) + (eaf-bind-key scroll_up "RET" eaf-pdf-viewer-keybinding) + (eaf-bind-key scroll_down_page "DEL" eaf-pdf-viewer-keybinding) + (eaf-bind-key scroll_down_page "u" eaf-pdf-viewer-keybinding) + (eaf-bind-key scroll_up_page "d" eaf-pdf-viewer-keybinding) + (eaf-bind-key scroll_to_end "M->" eaf-pdf-viewer-keybinding) + (eaf-bind-key scroll_to_home "M-<" eaf-pdf-viewer-keybinding) + (eaf-bind-key quit-window "q" eaf-pdf-viewer-keybinding) + (eaf-bind-key take_photo "p" eaf-camera-keybinding)) +;; -EAFPac + +(provide 'init-eaf) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-eaf.el ends here diff --git a/elisp/init-edit.el b/elisp/init-edit.el new file mode 100644 index 0000000..5d15aa0 --- /dev/null +++ b/elisp/init-edit.el @@ -0,0 +1,73 @@ +;;; init-edit.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-edit.el +;; Description: Initialize Editing Configuration +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Mar 28 13:25:24 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Tue Dec 24 11:50:24 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d iedit +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes iedit, awesome-pair, delete-block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: +(eval-when-compile + (require 'init-global-config)) + +;; IEditPac +(use-package iedit + :bind ("C-z ," . iedit-mode) + :diminish) +;; -IEditPac + +;; AwesomePairPac +(use-package awesome-pair + :load-path (lambda () (expand-file-name "site-elisp/awesome-pair" user-emacs-directory)) + :bind + (:map prog-mode-map + (("M-D" . awesome-pair-kill) + ("SPC" . awesome-pair-space) + ("=" . awesome-pair-equal) + ("M-F" . awesome-pair-jump-right) + ("M-B" . awesome-pair-jump-left))) + :hook (prog-mode . awesome-pair-mode)) +;; -AwesomePairPac + +;; DeleteBlockPac +(use-package delete-block + :load-path (lambda () (expand-file-name "site-elisp/delete-block" user-emacs-directory)) + :bind + (("M-d" . delete-block-forward) + ("C-" . delete-block-backward) + ("M-" . delete-block-backward) + ("M-DEL" . delete-block-backward))) +;; -DeleteBlockPac + +(provide 'init-edit) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-edit.el ends here diff --git a/elisp/init-ein.el b/elisp/init-ein.el new file mode 100644 index 0000000..8d3c72c --- /dev/null +++ b/elisp/init-ein.el @@ -0,0 +1,48 @@ +;;; init-ein.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-ein.el +;; Description: Initialize Emacs IPython Notebook Client +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Mar 21 14:04:50 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Aug 8 16:05:40 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d ein jupyter +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes Jupyter (formerly IPython) client for Emacs +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; EINPac +(use-package ein + :disabled + :defer t) +;; -EINPac + +(provide 'init-ein) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-ein.el ends here diff --git a/elisp/init-epaint.el b/elisp/init-epaint.el new file mode 100644 index 0000000..2ba0185 --- /dev/null +++ b/elisp/init-epaint.el @@ -0,0 +1,58 @@ +;;; init-epaint.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-epaint.el +;; Description: Initialize epaint +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Mon Sep 16 15:47:34 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Mon Sep 16 16:17:43 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d epaint +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes epaint +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-const)) + +;; EPaintPac +(use-package epaint + :if *sys/gui* + :load-path (lambda () (expand-file-name "site-elisp/epaint" user-emacs-directory)) + :commands (epaint) + :init + (with-eval-after-load (quote epaint-context) + (unless (boundp (quote cl-struct-epaint-drawable)) + (defvar cl-struct-epaint-drawable (quote epaint-drawable))) + (unless (boundp (quote cl-struct-epaint-gc)) + (defvar cl-struct-epaint-gc (quote epaint-gc))))) +;; -EPaintPac + +(provide 'init-epaint) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-epaint.el ends here diff --git a/elisp/init-erc.el b/elisp/init-erc.el new file mode 100644 index 0000000..d8f532b --- /dev/null +++ b/elisp/init-erc.el @@ -0,0 +1,140 @@ +;;; init-erc.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-erc.el +;; Description: Initialize ERC +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Tue Jul 30 22:15:50 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Wed Dec 4 01:57:57 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d erc irc +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes erc +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-global-config) + (require 'init-func)) + +;; ERCPac +(use-package erc + :ensure nil + :init + (use-package erc-hl-nicks :defer t) + (use-package erc-image :defer t) + :custom-face + (erc-notice-face ((t (:foreground "#ababab")))) + :custom + (erc-autojoin-channels-alist '(("freenode.net" "#emacs"))) + (erc-track-exclude-types '("NICK" "PART" "MODE" "324" "329" "332" "333" "353" "477")) + (erc-hide-list '("JOIN" "PART" "QUIT")) + (erc-lurker-hide-list '("JOIN" "PART" "QUIT")) + (erc-server-coding-system '(utf-8 . utf-8)) + (erc-interpret-mirc-color t) + (erc-kill-buffer-on-part t) + (erc-kill-queries-on-quit t) + (erc-kill-server-buffer-on-quit t) + (erc-autojoin-timing 'ident) + (erc-fill-function 'erc-fill-static) + (erc-fill-static-center 15) + (erc-lurker-threshold-time 43200) + (erc-server-reconnect-attempts 5) + (erc-server-reconnect-timeout 3) + (erc-prompt-for-password nil) + (erc-prompt-for-nickserv-password nil) + :config + ;; Prerequisite: Configure this to your IRC nickname + (defvar erc-nick "" + "The nickname used to login into ERC") + (add-to-list 'erc-modules 'notifications) + (erc-track-mode t) + (erc-services-mode 1) + (defun erc-start-or-switch () + "Start ERC or switch to ERC buffer if it has started already." + (interactive) + (if (get-buffer "irc.freenode.net:6697") + (erc-track-switch-buffer 1) + (erc-tls :server "irc.freenode.net" :port 6697 :nick erc-nick))) + + (defun erc-count-users () + "Displays the number of users and ops connected on the current channel." + (interactive) + (if (get-buffer "irc.freenode.net:6697") + (let ((channel (erc-default-target))) + (if (and channel (erc-channel-p channel)) + (let ((hash-table (with-current-buffer (erc-server-buffer) + erc-server-users)) + (users 0) + (ops 0)) + (maphash (lambda (k v) + (when (member (current-buffer) + (erc-server-user-buffers v)) + (cl-incf users)) + (when (erc-channel-user-op-p k) + (cl-incf ops))) + hash-table) + (message "%d users (%s ops) are online on %s" users ops channel)) + (user-error "The current buffer is not a channel"))) + (user-error "You must first be connected on IRC"))) + + (defun erc-get-ops () + "Displays the names of ops users on the current channel." + (interactive) + (if (get-buffer "irc.freenode.net:6697") + (let ((channel (erc-default-target))) + (if (and channel (erc-channel-p channel)) + (let (ops) + (maphash (lambda (nick cdata) + (if (and (cdr cdata) + (erc-channel-user-op (cdr cdata))) + (setq ops (cons nick ops)))) + erc-channel-users) + (if ops + (message "The online ops users are: %s" (mapconcat 'identity ops " ")) + (message "There are no ops users online on %s" channel))) + (user-error "The current buffer is not a channel"))) + (user-error "You must first be connected on IRC"))) + + (defun erc-notify (nickname message) + "Displays a notification message for ERC." + (let* ((channel (buffer-name)) + (nick (erc-hl-nicks-trim-irc-nick nickname)) + (title (if (string-match-p (concat "^" nickname) channel) + nick + (concat nick " (" channel ")"))) + (msg (s-trim (s-collapse-whitespace message)))) + (alert (concat nick ": " msg) :title title))) + :bind + ("M-z i" . erc-start-or-switch) + :hook + (ercn-notify . erc-notify)) +;; -ERCPac + +(provide 'init-erc) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-erc.el ends here diff --git a/elisp/init-ess.el b/elisp/init-ess.el new file mode 100644 index 0000000..7569a18 --- /dev/null +++ b/elisp/init-ess.el @@ -0,0 +1,50 @@ +;;; init-ess.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-ess.el +;; Description: Initialize ESS +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Tue Sep 3 21:28:26 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Wed Sep 4 00:27:58 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d ess +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initialies ESS +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; ESSPac +(use-package ess + :defer t + :commands R + :config + (load "ess-autoloads")) +;; -ESSPac + +(provide 'init-ess) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-ess.el ends here diff --git a/elisp/init-eww.el b/elisp/init-eww.el new file mode 100644 index 0000000..1afe3b2 --- /dev/null +++ b/elisp/init-eww.el @@ -0,0 +1,58 @@ +;;; init-eww.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-eww.el +;; Description: Configure Eww +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Fri Mar 15 11:13:42 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Tue Dec 24 12:18:07 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d eww +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes eww +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-const)) + +;; EWWPac +(use-package eww + :ensure nil + :commands (eww) + :hook (eww-mode . (lambda () + "Rename EWW's buffer so sites open in new page." + (rename-buffer "eww" t))) + :config + ;; I am using EAF-Browser instead of EWW + (unless *eaf-env* + (setq browse-url-browser-function 'eww-browse-url))) ; Hit & to browse url with system browser +;; -EWWPac + +(provide 'init-eww) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-eww.el ends here diff --git a/elisp/init-flycheck.el b/elisp/init-flycheck.el new file mode 100644 index 0000000..15d7871 --- /dev/null +++ b/elisp/init-flycheck.el @@ -0,0 +1,64 @@ +;;; init-flycheck.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-flycheck.el +;; Description: Initialize Flycheck +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Fri Mar 15 10:08:22 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Aug 8 16:05:47 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d flycheck +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes flycheck +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; FlyCheckPac +(use-package flycheck + :defer t + :hook (prog-mode . flycheck-mode) + :custom + (flycheck-emacs-lisp-load-path 'inherit) + :config + (add-hook 'flycheck-after-syntax-check-hook 'flycheck-autolist-hook) + (flycheck-add-mode 'javascript-eslint 'js-mode) + (flycheck-add-mode 'typescript-tslint 'rjsx-mode)) +;; -FlyCheckPac + +(use-package flycheck-pos-tip + :after (flycheck) + :config + (add-hook 'flycheck-mode-hook 'flycheck-pos-tip-mode)) + +(use-package flycheck-color-mode-line + :after (flycheck) + :config + (add-hook 'flycheck-mode-hook 'flycheck-color-mode-line-mode)) + +(provide 'init-flycheck) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-flycheck.el ends here diff --git a/elisp/init-fonts.el b/elisp/init-fonts.el new file mode 100644 index 0000000..eac29c4 --- /dev/null +++ b/elisp/init-fonts.el @@ -0,0 +1,84 @@ +;;; init-fonts.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-fonts.el +;; Description: Initialize Fonts +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Mar 14 17:32:54 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: lun. janv. 13 10:50:18 2020 (+0100) +;; By: Mikaël Capelle +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d fonts +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes fonts +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-const)) + +;; FontsList +;; Input Mono, Monaco Style, Line Height 1.3 download +;; from http://input.fontbureau.com/ +(defvar font-list '( + ("Fira Mono for Powerline" . 11) + ("Fira Mono" . 11) + ("Input" . 11) + ("SF Mono" . 12) + ("Consolas" . 12) ("Love LetterTW" . 12.5)) + "List of fonts and sizes. The first one available will be used.") +;; -FontsList + +;; FontFun +(defun change-font () + "Documentation." + (interactive) + (let* (available-fonts font-name font-size font-setting) + (dolist (font font-list (setq available-fonts (nreverse available-fonts))) + (when (member (car font) (font-family-list)) + (push font available-fonts))) + (if (not available-fonts) + (message "No fonts from the chosen set are available") + (if (called-interactively-p 'interactive) + (let* ((chosen + (assoc-string + (completing-read "What font to use? " available-fonts nil t) + available-fonts))) + (setq font-name (car chosen) + font-size (read-number "Font size: " (cdr chosen)))) + (setq font-name (caar available-fonts) + font-size (cdar available-fonts))) + (setq font-setting (format "%s-%d" font-name font-size)) + (set-frame-font font-setting nil t) + (add-to-list 'default-frame-alist (cons 'font font-setting))))) + +(when *sys/gui* + (change-font)) +;; -FontFun + +(provide 'init-fonts) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-fonts.el ends here diff --git a/elisp/init-format.el b/elisp/init-format.el new file mode 100644 index 0000000..61fd406 --- /dev/null +++ b/elisp/init-format.el @@ -0,0 +1,47 @@ +;;; init-format.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-format.el +;; Description: Initialize Formatter +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Fri Mar 15 10:27:40 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Aug 8 16:05:52 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d format-all +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes format-all +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; FormatAllPac +(use-package format-all + :bind ("C-c C-f" . format-all-buffer)) +;; -FormatAllPac + +(provide 'init-format) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-format.el ends here diff --git a/elisp/init-func.el b/elisp/init-func.el new file mode 100644 index 0000000..a13de4e --- /dev/null +++ b/elisp/init-func.el @@ -0,0 +1,184 @@ +;;; init-func.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-func.el +;; Description: Initialize Functions +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Sun Jun 9 17:53:44 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Fri Dec 27 01:02:58 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This file initializes functions +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-global-config)) + +;; ResizeWidthHeight +;; Resizes the window width based on the input +(defun resize-window-width (w) + "Resizes the window width based on W." + (interactive (list (if (> (count-windows) 1) + (read-number "Set the current window width in [1~9]x10%: ") + (error "You need more than 1 window to execute this function!")))) + (message "%s" w) + (window-resize nil (- (truncate (* (/ w 10.0) (frame-width))) (window-total-width)) t)) + +;; Resizes the window height based on the input +(defun resize-window-height (h) + "Resizes the window height based on H." + (interactive (list (if (> (count-windows) 1) + (read-number "Set the current window height in [1~9]x10%: ") + (error "You need more than 1 window to execute this function!")))) + (message "%s" h) + (window-resize nil (- (truncate (* (/ h 10.0) (frame-height))) (window-total-height)) nil)) + +;; Setup shorcuts for window resize width and height +(global-set-key (kbd "C-z w") #'resize-window-width) +(global-set-key (kbd "C-z h") #'resize-window-height) + +(defun resize-window (width delta) + "Resize the current window's size. If WIDTH is non-nil, resize width by some DELTA." + (if (> (count-windows) 1) + (window-resize nil delta width) + (error "You need more than 1 window to execute this function!"))) + +;; Setup shorcuts for window resize width and height +(global-set-key (kbd "M-W =") (lambda () (interactive) (resize-window t 5))) +(global-set-key (kbd "M-W M-+") (lambda () (interactive) (resize-window t 5))) +(global-set-key (kbd "M-W -") (lambda () (interactive) (resize-window t -5))) +(global-set-key (kbd "M-W M-_") (lambda () (interactive) (resize-window t -5))) + +(global-set-key (kbd "M-H =") (lambda () (interactive) (resize-window nil 5))) +(global-set-key (kbd "M-H M-+") (lambda () (interactive) (resize-window nil 5))) +(global-set-key (kbd "M-H -") (lambda () (interactive) (resize-window nil -5))) +(global-set-key (kbd "M-H M-_") (lambda () (interactive) (resize-window nil -5))) +;; -ResizeWidthheight + +;; EditConfig +(defun edit-configs () + "Opens the README.org file." + (interactive) + (find-file "~/.emacs.d/init.org")) + +(global-set-key (kbd "C-z e") #'edit-configs) +;; -EditConfig + +;; OrgIncludeAuto +(defun save-and-update-includes () + "Update the line numbers of #+INCLUDE:s in current buffer. +Only looks at INCLUDEs that have either :range-begin or :range-end. +This function does nothing if not in `org-mode', so you can safely +add it to `before-save-hook'." + (interactive) + (when (derived-mode-p 'org-mode) + (save-excursion + (goto-char (point-min)) + (while (search-forward-regexp + "^\\s-*#\\+INCLUDE: *\"\\([^\"]+\\)\".*:range-\\(begin\\|end\\)" + nil 'noerror) + (let* ((file (expand-file-name (match-string-no-properties 1))) + lines begin end) + (forward-line 0) + (when (looking-at "^.*:range-begin *\"\\([^\"]+\\)\"") + (setq begin (match-string-no-properties 1))) + (when (looking-at "^.*:range-end *\"\\([^\"]+\\)\"") + (setq end (match-string-no-properties 1))) + (setq lines (decide-line-range file begin end)) + (when lines + (if (looking-at ".*:lines *\"\\([-0-9]+\\)\"") + (replace-match lines :fixedcase :literal nil 1) + (goto-char (line-end-position)) + (insert " :lines \"" lines "\"")))))))) + +(add-hook 'before-save-hook #'save-and-update-includes) + +(defun decide-line-range (file begin end) + "Visit FILE and decide which lines to include. +BEGIN and END are regexps which define the line range to use." + (let (l r) + (save-match-data + (with-temp-buffer + (insert-file-contents file) + (goto-char (point-min)) + (if (null begin) + (setq l "") + (search-forward-regexp begin) + (setq l (line-number-at-pos (match-beginning 0)))) + (if (null end) + (setq r "") + (search-forward-regexp end) + (setq r (1+ (line-number-at-pos (match-end 0))))) + (format "%s-%s" (+ l 1) (- r 1)))))) ;; Exclude wrapper +;; -OrgIncludeAuto + +;; BetterMiniBuffer +(defun abort-minibuffer-using-mouse () + "Abort the minibuffer when using the mouse." + (when (and (>= (recursion-depth) 1) (active-minibuffer-window)) + (abort-recursive-edit))) + +(add-hook 'mouse-leave-buffer-hook 'abort-minibuffer-using-mouse) + +;; keep the point out of the minibuffer +(setq-default minibuffer-prompt-properties '(read-only t point-entered minibuffer-avoid-prompt face minibuffer-prompt)) +;; -BetterMiniBuffer + +;; DisplayLineOverlay +(defun display-line-overlay+ (pos str &optional face) + "Display line at POS as STR with FACE. + +FACE defaults to inheriting from default and highlight." + (let ((ol (save-excursion + (goto-char pos) + (make-overlay (line-beginning-position) + (line-end-position))))) + (overlay-put ol 'display str) + (overlay-put ol 'face + (or face '(:background null :inherit highlight))) + ol)) +;; -DisplayLineOverlay + +;; ReadLines +(defun read-lines (filePath) + "Return a list of lines of a file at FILEPATH." + (with-temp-buffer (insert-file-contents filePath) + (split-string (buffer-string) "\n" t))) +;; -ReadLines + +;; WhereAmI +(defun where-am-i () + "An interactive function showing function `buffer-file-name' or `buffer-name'." + (interactive) + (message (kill-new (if (buffer-file-name) (buffer-file-name) (buffer-name))))) +;; -WhereAmI + +(provide 'init-func) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-func.el ends here diff --git a/elisp/init-games.el b/elisp/init-games.el new file mode 100644 index 0000000..74bb4a5 --- /dev/null +++ b/elisp/init-games.el @@ -0,0 +1,68 @@ +;;; init-games.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-games.el +;; Description: Initialize Games +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Fri Mar 15 11:16:53 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Dec 26 02:55:21 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d tetris speed-type 2048 +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes tetris, speed-type, 2048 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; TetrisConfig +(use-package tetris + :ensure nil + :commands (tetris) + :bind + (:map tetris-mode-map + ("C-p" . tetris-rotate-prev) + ("C-n" . tetris-rotate-down) + ("C-b" . tetris-move-left) + ("C-f" . tetris-move-right) + ("C-SPC" . tetris-move-bottom)) + :config + (defadvice tetris-end-game (around zap-scores activate) + (save-window-excursion ad-do-it))) +;; -TetrisConfig + +;; SpeedTypePac +(use-package speed-type + :commands (speed-type-text)) +;; -SpeedTypePac + +;; 2048Pac +(use-package 2048-game + :commands (2048-game)) +;; -2048Pac + +(provide 'init-games) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-games.el ends here diff --git a/elisp/init-global-config.el b/elisp/init-global-config.el new file mode 100644 index 0000000..0f949e6 --- /dev/null +++ b/elisp/init-global-config.el @@ -0,0 +1,176 @@ +;;; init-global-config.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-global-config.el +;; Description: Initialize Global Configurations +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Mar 14 14:01:54 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Wed Dec 25 03:02:50 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This file initializes global configurations +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-const)) + +;; SudoEditPac +(use-package sudo-edit + :commands (sudo-edit)) +;; -SudoEditPac + +;; DefBindings +;; Unbind unneeded keys +(global-set-key (kbd "C-z") nil) +(global-set-key (kbd "M-z") nil) +(global-set-key (kbd "C-x C-z") nil) +(global-set-key (kbd "M-/") nil) +;; Use iBuffer instead of Buffer List +(global-set-key (kbd "C-x C-b") #'ibuffer) +;; Truncate lines +(global-set-key (kbd "C-x C-l") #'toggle-truncate-lines) +;; Adjust font size like web browsers +(global-set-key (kbd "C-+") #'text-scale-increase) +(global-set-key (kbd "C--") #'text-scale-decrease) +;; Move up/down paragraph +(global-set-key (kbd "M-n") #'forward-paragraph) +(global-set-key (kbd "M-p") #'backward-paragraph) +;; -DefBindings + +;; UTF8Coding +(unless *sys/win32* + (set-selection-coding-system 'utf-8) + (prefer-coding-system 'utf-8) + (set-language-environment "UTF-8") + (set-default-coding-systems 'utf-8) + (set-terminal-coding-system 'utf-8) + (set-keyboard-coding-system 'utf-8) + (setq locale-coding-system 'utf-8)) +;; Treat clipboard input as UTF-8 string first; compound text next, etc. +(when *sys/gui* + (setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))) +;; -UTF8Coding + +;; EditExp +;; Remove useless whitespace before saving a file +(defun delete-trailing-whitespace-except-current-line () + "Sometimes `delete-trailing-whitespace' becomes very annoying. +It deletes trailing whitespace current line. Therefore I use this alternative." + (interactive) + (let ((begin (line-beginning-position)) + (end (line-end-position))) + (save-excursion + (when (< (point-min) begin) + (save-restriction + (narrow-to-region (point-min) (1- begin)) + (delete-trailing-whitespace) + (widen))) + (when (> (point-max) end) + (save-restriction + (narrow-to-region (+ end 2) (point-max)) + (delete-trailing-whitespace) + (widen)))))) +(add-hook 'before-save-hook #'delete-trailing-whitespace-except-current-line) + +;; Replace selection on insert +(delete-selection-mode 1) + +;; Map Alt key to Meta +(setq x-alt-keysym 'meta) +;; -EditExp + +;; History +(use-package recentf + :ensure nil + :hook (after-init . recentf-mode) + :custom + (recentf-auto-cleanup "05:00am") + (recentf-max-saved-items 200) + (recentf-exclude '((expand-file-name package-user-dir) + ".cache" + ".cask" + ".elfeed" + "bookmarks" + "cache" + "ido.*" + "persp-confs" + "recentf" + "undo-tree-hist" + "url" + "COMMIT_EDITMSG\\'"))) + +;; When buffer is closed, saves the cursor location +(save-place-mode 1) + +;; Set history-length longer +(setq-default history-length 500) +;; -History + +;; SmallConfigs +;; Turn Off Cursor Alarms +(setq ring-bell-function 'ignore) + +;; Show Keystrokes in Progress Instantly +(setq echo-keystrokes 0.1) + +;; Don't Lock Files +(setq-default create-lockfiles nil) + +;; Better Compilation +(setq-default compilation-always-kill t) ; kill compilation process before starting another + +(setq-default compilation-ask-about-save nil) ; save all buffers on `compile' + +(setq-default compilation-scroll-output t) + +;; ad-handle-definition warnings are generated when functions are redefined with `defadvice', +;; they are not helpful. +(setq ad-redefinition-action 'accept) + +;; Move Custom-Set-Variables to Different File +(setq custom-file (concat user-emacs-directory "custom-set-variables.el")) +(load custom-file 'noerror) + +;; So Long mitigates slowness due to extremely long lines. +;; Currently available in Emacs master branch *only*! +(when (fboundp 'global-so-long-mode) + (global-so-long-mode)) + +;; Add a newline automatically at the end of the file upon save. +(setq require-final-newline t) + +;; Default .args, .in, .out files to text-mode +(add-to-list 'auto-mode-alist '("\\.in\\'" . text-mode)) +(add-to-list 'auto-mode-alist '("\\.out\\'" . text-mode)) +(add-to-list 'auto-mode-alist '("\\.args\\'" . text-mode)) +;; -SmallConfigs + +(provide 'init-global-config) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-global-config.el ends here diff --git a/elisp/init-header.el b/elisp/init-header.el new file mode 100644 index 0000000..507999d --- /dev/null +++ b/elisp/init-header.el @@ -0,0 +1,54 @@ +;;; init-header.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-header.el +;; Description: Initialize Header2 +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Fri Mar 15 10:32:02 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Tue Dec 24 11:54:28 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d header2 +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes header2 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; Header2Pac +(use-package header2 + :load-path (lambda () (expand-file-name "site-elisp/header2" user-emacs-directory)) + :custom + (header-copyright-notice (concat "Copyright (C) 2019 " (user-full-name) "\n")) + :hook (emacs-lisp-mode . auto-make-header) + :config + (add-to-list 'write-file-functions 'auto-update-file-header) + (autoload 'auto-make-header "header2") + (autoload 'auto-update-file-header "header2")) +;; -Header2Pac + +(provide 'init-header) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-header.el ends here diff --git a/elisp/init-indent.el b/elisp/init-indent.el new file mode 100644 index 0000000..d46f83b --- /dev/null +++ b/elisp/init-indent.el @@ -0,0 +1,75 @@ +;;; init-indent.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-indent.el +;; Description: Initialize Indentation +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Fri Mar 15 10:29:56 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Tue Dec 3 21:41:41 2019 (-0500) +;; By: User Account1 +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d highlight-indent-guides indentation +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes highlight-indent-guides +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-const)) + +;; HighLightIndentPac +(use-package highlight-indent-guides + :if *sys/gui* + :diminish + :hook ((prog-mode web-mode nxml-mode) . highlight-indent-guides-mode) + :custom + (highlight-indent-guides-method 'character) + (highlight-indent-guides-responsive 'top) + (highlight-indent-guides-delay 0) + (highlight-indent-guides-auto-character-face-perc 7)) +;; -HighLightIndentPac + +;; IndentConfig +(setq-default indent-tabs-mode nil) +(setq-default indent-line-function 'insert-tab) +(setq-default tab-width 4) +(setq-default c-basic-offset 4) +(setq-default js-switch-indent-offset 4) +(c-set-offset 'comment-intro 0) +(c-set-offset 'innamespace 0) +(c-set-offset 'case-label '+) +(c-set-offset 'access-label 0) +(c-set-offset (quote cpp-macro) 0 nil) +(add-hook 'after-change-major-mode-hook + (lambda () (if (equal electric-indent-mode 't) + (when (derived-mode-p 'text-mode) + (electric-indent-mode -1)) + (electric-indent-mode 1)))) +;; -IndentConfig + +(provide 'init-indent) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-indent.el ends here diff --git a/elisp/init-java.el b/elisp/init-java.el new file mode 100644 index 0000000..5fe5e38 --- /dev/null +++ b/elisp/init-java.el @@ -0,0 +1,56 @@ +;;; init-java.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-java.el +;; Description: Initialize lsp-java java-one-click-run +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Jul 4 21:26:24 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Aug 8 16:06:55 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d lsp-java java-one-click-run +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes lsp-java and java-one-click-run +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-const)) + +;; LSPJavaPac +(use-package lsp-java + :after lsp-mode + :if *mvn* + :config + (use-package request :defer t) + :custom + (lsp-java-server-install-dir (expand-file-name "~/.emacs.d/eclipse.jdt.ls/server/")) + (lsp-java-workspace-dir (expand-file-name "~/.emacs.d/eclipse.jdt.ls/workspace/"))) +;; -LSPJavaPac + +(provide 'init-java) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-java.el ends here diff --git a/elisp/init-latex.el b/elisp/init-latex.el new file mode 100644 index 0000000..ce09182 --- /dev/null +++ b/elisp/init-latex.el @@ -0,0 +1,79 @@ +;;; init-latex.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-latex.el +;; Description: Initialize AUCTex +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Wed Sep 4 16:35:00 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Tue Dec 24 12:00:08 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d auctex +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes AUCTex +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-const) + (require 'init-global-config) + (require 'init-func)) + +;; AUCTeXPac +(use-package tex + :ensure auctex + :defer t + :custom + (TeX-auto-save t) + (TeX-parse-self t) + (TeX-master nil) + ;; to use pdfview with auctex + (TeX-view-program-selection '((output-pdf "pdf-tools")) + TeX-source-correlate-start-server t) + (TeX-view-program-list '(("pdf-tools" "TeX-pdf-tools-sync-view"))) + (TeX-after-compilation-finished-functions #'TeX-revert-document-buffer) + :hook + (LaTeX-mode . (lambda () + (turn-on-reftex) + (setq reftex-plug-into-AUCTeX t) + (reftex-isearch-minor-mode) + (setq TeX-PDF-mode t) + (setq TeX-source-correlate-method 'synctex) + (setq TeX-source-correlate-start-server t))) + :config + (when (version< emacs-version "26") + (add-hook LaTeX-mode-hook #'display-line-numbers-mode))) +;; -AUCTeXPac + +;; OrgLatexPac +(use-package org-edit-latex + :defer t + :after org) +;; -OrgLatexPac + +(provide 'init-latex) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-latex.el ends here diff --git a/elisp/init-leetcode.el b/elisp/init-leetcode.el new file mode 100644 index 0000000..ecba587 --- /dev/null +++ b/elisp/init-leetcode.el @@ -0,0 +1,57 @@ +;;; init-leetcode.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-leetcode.el +;; Description: Initialize LeetCode Client +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Apr 11 22:28:41 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Sat Sep 7 00:52:17 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d leetcode +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes a LeetCode client +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-const)) + +;; LeetCodePac +(use-package leetcode + :load-path (lambda () (expand-file-name "site-elisp/leetcode.el" user-emacs-directory)) + :commands (leetcode) + :init + (use-package graphql :defer t) + (use-package aio :defer t) + :custom + (url-debug t) + (leetcode-prefer-language "python3")) +;; -LeetCodePac + +(provide 'init-leetcode) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-leetcode.el ends here diff --git a/elisp/init-lsp.el b/elisp/init-lsp.el new file mode 100644 index 0000000..962dd66 --- /dev/null +++ b/elisp/init-lsp.el @@ -0,0 +1,114 @@ +;;; init-lsp.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-lsp.el +;; Description: Initialize LSP +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Fri Mar 15 10:42:09 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Dec 26 01:56:25 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d lsp +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes lsp-mode and dap-mode +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-const)) + +;; LSPPac +(use-package lsp-mode + :defer t + :commands lsp + :custom + (lsp-auto-guess-root nil) + (lsp-prefer-flymake nil) ; Use flycheck instead of flymake + (lsp-file-watch-threshold 2000) + (read-process-output-max (* 1024 1024)) + :bind (:map lsp-mode-map ("C-c C-f" . lsp-format-buffer)) + :hook ((java-mode python-mode go-mode + js-mode js2-mode typescript-mode web-mode + c-mode c++-mode objc-mode) . lsp)) +;; -LSPPac + +;; LSPUI +(use-package lsp-ui + :after lsp-mode + :diminish + :commands lsp-ui-mode + :custom-face + (lsp-ui-doc-background ((t (:background nil)))) + (lsp-ui-doc-header ((t (:inherit (font-lock-string-face italic))))) + :bind (:map lsp-ui-mode-map + ([remap xref-find-definitions] . lsp-ui-peek-find-definitions) + ([remap xref-find-references] . lsp-ui-peek-find-references) + ("C-c u" . lsp-ui-imenu)) + :custom + (lsp-ui-doc-enable t) + (lsp-ui-doc-header t) + (lsp-ui-doc-include-signature t) + (lsp-ui-doc-position 'top) + (lsp-ui-doc-border (face-foreground 'default)) + (lsp-ui-sideline-enable nil) + (lsp-ui-sideline-ignore-duplicate t) + (lsp-ui-sideline-show-code-actions nil) + :config + ;; Use lsp-ui-doc-webkit only in GUI + (if *sys/gui* + (setq lsp-ui-doc-use-webkit t)) + ;; WORKAROUND Hide mode-line of the lsp-ui-imenu buffer + ;; https://github.com/emacs-lsp/lsp-ui/issues/243 + (defadvice lsp-ui-imenu (after hide-lsp-ui-imenu-mode-line activate) + (setq mode-line-format nil))) +;; -LSPUI + +;; DAPPac +(use-package dap-mode + :diminish + :bind + (:map dap-mode-map + (("" . dap-debug) + ("" . dap-continue) + ("" . dap-next) + ("" . dap-step-in) + ("C-M-" . dap-step-out) + ("" . dap-breakpoint-toggle))) + :hook ((after-init . dap-mode) + (dap-mode . dap-ui-mode) + (python-mode . (lambda () (require 'dap-python))) + (ruby-mode . (lambda () (require 'dap-ruby))) + (go-mode . (lambda () (require 'dap-go))) + (java-mode . (lambda () (require 'dap-java))) + ((c-mode c++-mode objc-mode swift) . (lambda () (require 'dap-lldb))) + (php-mode . (lambda () (require 'dap-php))) + (elixir-mode . (lambda () (require 'dap-elixir))) + ((js-mode js2-mode typescript-mode) . (lambda () (require 'dap-chrome))))) +;; -DAPPac + +(provide 'init-lsp) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-lsp.el ends here diff --git a/elisp/init-magit.el b/elisp/init-magit.el new file mode 100644 index 0000000..9ac90af --- /dev/null +++ b/elisp/init-magit.el @@ -0,0 +1,51 @@ +;;; init-magit.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-magit.el +;; Description: Initialize Magit +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Fri Mar 15 08:40:27 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Aug 8 16:07:17 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d magit +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes magit +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-const)) + +;; MagitPac +(use-package magit + :if *git* + :bind ("C-x g" . magit-status)) +;; -MagitPac + +(provide 'init-magit) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-magit.el ends here diff --git a/elisp/init-mu4e.el b/elisp/init-mu4e.el new file mode 100644 index 0000000..ff38b1f --- /dev/null +++ b/elisp/init-mu4e.el @@ -0,0 +1,130 @@ +;;; init-mu4e.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-mu4e.el +;; Description: Initialize mu4e +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Mon Dec 2 15:17:14 2019 (-0500) +;; Version: 2.0.0 +;; Package-Requires: (mu4e) +;; Last-Updated: +;; By: +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d mu mu4e +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes mu4e for Email clients in Emacs +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; Mu4ePac +(use-package mu4e + :ensure nil + :commands (mu4e) + :init + (use-package mu4e-alert + :defer t + :config + (when (executable-find "notify-send") + (mu4e-alert-set-default-style 'libnotify)) + :hook + ((after-init . mu4e-alert-enable-notifications) + (after-init . mu4e-alert-enable-mode-line-display))) + (use-package mu4e-overview :defer t) + :bind ("M-z m" . mu4e) + :custom + (mu4e-maildir (expand-file-name "~/Maildir")) + (mu4e-get-mail-command "mbsync -c ~/.emacs.d/mu4e/.mbsyncrc -a") + (mu4e-view-prefer-html t) + (mu4e-update-interval 180) + (mu4e-headers-auto-update t) + (mu4e-compose-signature-auto-include nil) + (mu4e-compose-format-flowed t) + (mu4e-view-show-images t) + (mu4e-sent-messages-behavior 'delete) + (mu4e-change-filenames-when-moving t) ; work better for mbsync + (mu4e-attachment-dir "~/Downloads") + (message-kill-buffer-on-exit t) + (mu4e-compose-dont-reply-to-self t) + (mu4e-view-show-addresses t) + (mu4e-confirm-quit nil) + (mu4e-use-fancy-chars t) + :hook + ((mu4e-view-mode . visual-line-mode) + (mu4e-compose-mode . (lambda () + (visual-line-mode) + (use-hard-newlines -1) + (flyspell-mode))) + (mu4e-view-mode . (lambda() ;; try to emulate some of the eww key-bindings + (local-set-key (kbd "") 'shr-next-link) + (local-set-key (kbd "") 'shr-previous-link))) + (mu4e-headers-mode . (lambda () + (interactive) + (setq mu4e-headers-fields + `((:human-date . 25) ;; alternatively, use :date + (:flags . 6) + (:from . 22) + (:thread-subject . ,(- (window-body-width) 70)) ;; alternatively, use :subject + (:size . 7)))))) + :config + (add-to-list 'mu4e-view-actions + '("ViewInBrowser" . mu4e-action-view-in-browser) t) + (setq mu4e-contexts + (list + (make-mu4e-context + :name "gmail" + :enter-func (lambda () (mu4e-message "Entering context gmail")) + :leave-func (lambda () (mu4e-message "Leaving context gmail")) + :match-func + (lambda (msg) + (when msg + (mu4e-message-contact-field-matches + msg '(:from :to :cc :bcc) user-mail-address))) ; Set to your email address + :vars '((mu4e-refile-folder "/gmail/Archive") + (mu4e-sent-folder . "/gmail/[email].Sent Mail") + (mu4e-drafts-folder . "/gmail/[email].Drafts") + (mu4e-trash-folder . "/gmail/[email].Trash") + (mu4e-compose-signature . user-full-name) + (mu4e-compose-format-flowed . t) + (smtpmail-queue-dir . "~/Maildir/gmail/queue/cur") + (message-send-mail-function . smtpmail-send-it) + (smtpmail-smtp-user . "matthewzmd") ; Set to your username + (smtpmail-starttls-credentials . (("smtp.gmail.com" 587 nil nil))) + (smtpmail-auth-credentials . (expand-file-name "~/.authinfo.gpg")) + (smtpmail-default-smtp-server . "smtp.gmail.com") + (smtpmail-smtp-server . "smtp.gmail.com") + (smtpmail-smtp-service . 587) + (smtpmail-debug-info . t) + (smtpmail-debug-verbose . t) + (mu4e-maildir-shortcuts . ( ("/gmail/INBOX" . ?i) + ("/gmail/[email].Sent Mail" . ?s) + ("/gmail/[email].Trash" . ?t) + ("/gmail/[email].All Mail" . ?a) + ("/gmail/[email].Starred" . ?r) + ("/gmail/[email].Drafts" . ?d)))))))) +;; -Mu4ePac + +(provide 'init-mu4e) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-mu4e.el ends here diff --git a/elisp/init-org.el b/elisp/init-org.el new file mode 100644 index 0000000..3db0a54 --- /dev/null +++ b/elisp/init-org.el @@ -0,0 +1,114 @@ +;;; init-org.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-org.el +;; Description: Initialize Org, Toc-org, HTMLize, OX-GFM +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Fri Mar 15 11:09:30 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Tue Dec 24 14:05:45 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d org toc-org htmlize ox-gfm +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes org toc-org htmlize ox-gfm +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; OrgPac +(use-package org + :ensure nil + :defer t + :bind + ("C-c l" . org-store-link) + ("C-c a" . org-agenda) + ("C-c c" . org-capture) + ("C-c b" . org-switch) + (:map org-mode-map ("C-c C-p" . org-export-as-pdf-and-open)) + :custom + (org-log-done 'time) + (org-export-backends (quote (ascii html icalendar latex md odt))) + (org-use-speed-commands t) + (org-confirm-babel-evaluate 'nil) + (org-todo-keywords + '((sequence "TODO" "IN-PROGRESS" "REVIEW" "|" "DONE"))) + (org-agenda-window-setup 'other-window) + :config + (unless (version< org-version "9.2") + (require 'org-tempo)) + (when (file-directory-p "~/org/agenda/") + (setq org-agenda-files (list "~/org/agenda/"))) + + (defun org-export-turn-on-syntax-highlight () + "Setup variables to turn on syntax highlighting when calling `org-latex-export-to-pdf'." + (interactive) + (setq org-latex-listings 'minted + org-latex-packages-alist '(("" "minted")) + org-latex-pdf-process + '("pdflatex -shelnl-escape -interaction nonstopmode -output-directory %o %f" + "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"))) + + (defun org-export-as-pdf-and-open () + "Run `org-latex-export-to-pdf', delete the tex file and open pdf in a new buffer." + (interactive) + (save-buffer) + (let* ((pdf-path (org-latex-export-to-pdf)) + (pdf-name (file-name-nondirectory pdf-path))) + (if (try-completion pdf-name (mapcar #'buffer-name (buffer-list))) + (progn + (kill-matching-buffers (concat "^" pdf-name) t t) + (find-file-other-window pdf-name)) + (find-file-other-window pdf-name)) + (delete-file (concat (substring pdf-path 0 (string-match "[^\.]*\/?$" pdf-path)) "tex"))))) +;; -OrgPac + +;; TocOrgPac +(use-package toc-org + :hook (org-mode . toc-org-mode)) +;; -TocOrgPac + +;; HTMLIZEPac +(use-package htmlize :defer t) +;; -HTMLIZEPac + +;; OXGFMPac +(use-package ox-gfm :defer t) +;; -OXGFMPac + +;; PlantUMLPac +(use-package plantuml-mode + :defer t + :custom + (org-plantuml-jar-path (expand-file-name "~/tools/plantuml/plantuml.jar")) + :config + (org-babel-do-load-languages + 'org-babel-load-languages + '(;; other Babel languages + (plantuml . t)))) +;; -PlantUMLPac + +(provide 'init-org) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-org.el ends here diff --git a/elisp/init-package.el b/elisp/init-package.el new file mode 100644 index 0000000..dfaf2c5 --- /dev/null +++ b/elisp/init-package.el @@ -0,0 +1,100 @@ +;;; init-package.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-package.el +;; Description: Initialize Package Management for M-EMACS +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Mar 14 10:53:00 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Dec 26 03:37:58 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d packages use-package +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This file initializes packages from melpa using use-package macro +;; as well as auto-package-update, diminish, gnu-elpa-keyring-update +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; MelpaPackages +;; Select the folder to store packages +;; Comment / Uncomment to use desired sites +(setq package-user-dir (expand-file-name "elpa" user-emacs-directory) + package-archives + '(("gnu" . "http://elpa.gnu.org/packages/") + ("melpa" . "https://melpa.org/packages/") + ("cselpa" . "https://elpa.thecybershadow.net/packages/") + ;; ("melpa-cn" . "http://mirrors.cloud.tencent.com/elpa/melpa/") + ;; ("gnu-cn" . "http://mirrors.cloud.tencent.com/elpa/gnu/") + )) +;; -MelpaPackages + +;; ConfigurePackageManager +(unless (bound-and-true-p package--initialized) + (setq package-enable-at-startup nil) ; To prevent initializing twice + (package-initialize)) + +;; set use-package-verbose to t for interpreted .emacs, +;; and to nil for byte-compiled .emacs.elc. +(eval-and-compile + (setq use-package-verbose (not (bound-and-true-p byte-compile-current-file)))) +;; -ConfigurePackageManager + +;; ConfigureUsePackage +;; Install use-package if not installed +(unless (package-installed-p 'use-package) + (package-refresh-contents) + (package-install 'use-package)) + +(eval-and-compile + (setq use-package-always-ensure t) + (setq use-package-expand-minimally t) + (setq use-package-compute-statistics t) + (setq use-package-enable-imenu-support t)) + +(eval-when-compile + (require 'use-package) + (require 'bind-key)) +;; -ConfigureUsePackage + +;; AutoPackageUpdate +(use-package auto-package-update + :if (not (daemonp)) + :custom + (auto-package-update-interval 7) ;; in days + (auto-package-update-prompt-before-update t) + (auto-package-update-delete-old-versions t) + (auto-package-update-hide-results t) + :config + (auto-package-update-maybe)) +;; -AutoPackageUpdate + +;; DimPac +(use-package diminish) +;; -DimPac + +(provide 'init-package) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-package.el ends here diff --git a/elisp/init-parens.el b/elisp/init-parens.el new file mode 100644 index 0000000..1914011 --- /dev/null +++ b/elisp/init-parens.el @@ -0,0 +1,116 @@ +;;; init-parens.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-parens.el +;; Description: Initialize Parenthesis +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Fri Mar 15 10:17:13 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Tue Dec 24 11:48:49 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d parenthesis smartparens delete-block +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes parenthesis smartparens delete-block +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-global-config)) + +;; SmartParensPac +(use-package smartparens + :hook (prog-mode . smartparens-mode) + :diminish smartparens-mode + :bind + (:map smartparens-mode-map + ("C-M-f" . sp-forward-sexp) + ("C-M-b" . sp-backward-sexp) + ("C-M-a" . sp-backward-down-sexp) + ("C-M-e" . sp-up-sexp) + ("C-M-w" . sp-copy-sexp) + ("C-M-k" . sp-change-enclosing) + ("M-k" . sp-kill-sexp) + ("C-M-" . sp-splice-sexp-killing-backward) + ("C-S-" . sp-splice-sexp-killing-around) + ("C-]" . sp-select-next-thing-exchange)) + :custom + (sp-escape-quotes-after-insert nil) + :config + ;; Stop pairing single quotes in elisp + (sp-local-pair 'emacs-lisp-mode "'" nil :actions nil) + (sp-local-pair 'org-mode "[" nil :actions nil) + ;; Smartparens is broken in `cc-mode' as of Emacs 27. See + ;; https://github.com/Fuco1/smartparens/issues/963 + (unless (version< emacs-version "27") + (dolist (fun '(c-electric-paren c-electric-brace)) + (add-to-list 'sp--special-self-insert-commands fun)))) +;; -SmartParensPac + +;; MatchParens +;; Show matching parenthesis +(show-paren-mode 1) +;; we will call `blink-matching-open` ourselves... +(remove-hook 'post-self-insert-hook + #'blink-paren-post-self-insert-function) + +;; this still needs to be set for `blink-matching-open` to work +(setq blink-matching-paren 'show) +(let ((ov nil)) ; keep track of the overlay + (advice-add + #'show-paren-function + :after + (defun show-paren--off-screen+ (&rest _args) + "Display matching line for off-screen paren." + (when (overlayp ov) + (delete-overlay ov)) + ;; check if it's appropriate to show match info, + ;; see `blink-paren-post-self-insert-function' + (when (and (overlay-buffer show-paren--overlay) + (not (or cursor-in-echo-area + executing-kbd-macro + noninteractive + (minibufferp) + this-command)) + (and (not (bobp)) + (memq (char-syntax (char-before)) '(?\) ?\$))) + (= 1 (logand 1 (- (point) + (save-excursion + (forward-char -1) + (skip-syntax-backward "/\\") + (point)))))) + ;; rebind `minibuffer-message' called by + ;; `blink-matching-open' to handle the overlay display + (cl-letf (((symbol-function #'minibuffer-message) + (lambda (msg &rest args) + (let ((msg (apply #'format-message msg args))) + (setq ov (display-line-overlay+ + (window-start) msg)))))) + (blink-matching-open)))))) +;; -MatchParens + +(provide 'init-parens) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-parens.el ends here diff --git a/elisp/init-pdf.el b/elisp/init-pdf.el new file mode 100644 index 0000000..d54ac31 --- /dev/null +++ b/elisp/init-pdf.el @@ -0,0 +1,60 @@ +;;; init-pdf.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-pdf.el +;; Description: Initialize pdf-tools +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Tue Jun 4 00:26:09 2019 (-0400) +;; Version: 1.0.0 +;; Last-Updated: Tue Dec 24 12:11:20 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d pdf-tools +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes pdf-tools +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-const)) + +;; PDFToolsPac +(use-package pdf-tools-install + :ensure pdf-tools + :if (and *sys/gui* (not *sys/win32*)) + :mode "\\.pdf\\'" + :commands (pdf-loader-install) + :custom + (TeX-view-program-selection '((output-pdf "pdf-tools"))) + (TeX-view-program-list '(("pdf-tools" "TeX-pdf-tools-sync-view"))) + :hook + (pdf-view-mode . (lambda () (display-line-numbers-mode -1))) + :config + (pdf-loader-install)) +;; -PDFToolsPac + +(provide 'init-pdf) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-pdf.el ends here diff --git a/elisp/init-popup-kill-ring.el b/elisp/init-popup-kill-ring.el new file mode 100644 index 0000000..68c679b --- /dev/null +++ b/elisp/init-popup-kill-ring.el @@ -0,0 +1,47 @@ +;;; init-popup-kill-ring.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-popup-kill-ring.el +;; Description: Initialize Popup-Kill-Ring +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Mar 14 15:15:40 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Aug 8 16:07:32 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d popup-kill-ring +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes popup-kill-ring +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; PopKillRing +(use-package popup-kill-ring + :bind ("M-y" . popup-kill-ring)) +;; -PopKillRing + +(provide 'init-popup-kill-ring) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-popup-kill-ring.el ends here diff --git a/elisp/init-projectile.el b/elisp/init-projectile.el new file mode 100644 index 0000000..771fb8a --- /dev/null +++ b/elisp/init-projectile.el @@ -0,0 +1,60 @@ +;;; init-projectile.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-projectile.el +;; Description: Initialize Projectile +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Fri Mar 15 09:10:23 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Aug 8 16:07:35 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d projectile +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes projectile +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-const)) + +;; ProjPac +(use-package projectile + :bind + ("C-c p" . projectile-command-map) + ("C-z o" . projectile-find-file) + ("C-z p" . projectile-add-known-project) + :custom + (projectile-completion-system 'ivy) + :config + (projectile-mode 1) + (when (and *sys/win32* *tr*) + (setq projectile-indexing-method 'alien)) + (add-to-list 'projectile-globally-ignored-directories "node_modules")) +;; -ProjPac + +(provide 'init-projectile) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-projectile.el ends here diff --git a/elisp/init-pyim.el b/elisp/init-pyim.el new file mode 100644 index 0000000..9e39adb --- /dev/null +++ b/elisp/init-pyim.el @@ -0,0 +1,69 @@ +;;; init-pyim.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-pyim.el +;; Description: Initialize Pyim +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Jun 20 00:36:05 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Dec 26 21:54:20 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d init +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes pyim +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; PyimPac +(use-package pyim + :init + (use-package posframe :defer t) + :custom + (default-input-method "pyim") + (pyim-default-scheme 'quanpin) + (pyim-page-tooltip 'posframe) + (pyim-page-length 9) + :config + (pyim-isearch-mode 1) + (setq-default pyim-english-input-switch-functions + '(pyim-probe-isearch-mode + pyim-probe-org-structure-template)) + (setq-default pyim-punctuation-half-width-functions + '(pyim-probe-punctuation-line-beginning + pyim-probe-punctuation-after-punctuation)) + :bind + ("M-j" . pyim-convert-string-at-point)) ; M-j 强制将光标前的拼音字符串转换为中文。 +;; -PyimPac + +;; PyimBaseDictPac +(use-package pyim-basedict + :after pyim + :config (pyim-basedict-enable)) +;; -PyimBaseDictPac + +(provide 'init-pyim) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-pyim.el ends here diff --git a/elisp/init-python.el b/elisp/init-python.el new file mode 100644 index 0000000..0bdade8 --- /dev/null +++ b/elisp/init-python.el @@ -0,0 +1,91 @@ +;;; init-python.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-python.el +;; Description: Initialize Python +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Mon Jun 10 18:58:02 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: lun. janv. 13 14:24:17 2020 (+0100) +;; By: Mikaël Capelle +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: lsp-python-ms +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes lsp-python-ms +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-flycheck) + (require 'init-const)) + +;; PythonConfig +;; (use-package python-mode +;; :ensure nil +;; :after flycheck +;; :mode "\\.py\\'" +;; :custom +;; (python-indent-offset 4) +;; (flycheck-python-pycompile-executable "python3") +;; (python-shell-interpreter "python3")) +;; ;; -PythonConfig + +(add-hook 'python-mode-hook (lambda () (setq-local whitespace-line-column 100))) + +(use-package flycheck-mypy + :after flycheck + :config + (flycheck-add-next-checker 'python-flake8 'python-mypy)) + +(use-package elpy + :custom + (flycheck-python-flake8-executable "python") + (python-indent-offset 4) + (python-shell-interpreter "ipython") + (python-shell-interpreter-args "-i --simple-prompt") + :config + (setq elpy-modules (delq 'elpy-module-flymake elpy-modules)) + (add-hook 'elpy-mode-hook 'flycheck-mode) + :init + (setq elpy-rpc-backend "jedi") + (elpy-enable)) + +(use-package ein + :custom + (ein:polymode t) + (ein:use-auto-complete t) + :commands (ein:notebooklist-open)) + +;; LSPPythonPac +;; (use-package lsp-python-ms +;; :after lsp-mode python +;; :if (or *python3* *python*) +;; :custom +;; (lsp-python-executable-cmd "python3")) +;; ;; -LSPPythonPac + +(provide 'init-python) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-python.el ends here diff --git a/elisp/init-quickrun.el b/elisp/init-quickrun.el new file mode 100644 index 0000000..4d4eb6e --- /dev/null +++ b/elisp/init-quickrun.el @@ -0,0 +1,49 @@ +;;; init-quickrun.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-quickrun.el +;; Description: Initialize quickrun +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Sun Jul 7 16:32:16 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Aug 8 16:07:44 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d init +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes quickrun +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; QuickrunPac +(use-package quickrun + :bind + (("" . quickrun) + ("M-" . quickrun-shell))) +;; -QuickrunPac + +(provide 'init-quickrun) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-quickrun.el ends here diff --git a/elisp/init-scroll.el b/elisp/init-scroll.el new file mode 100644 index 0000000..f05dbeb --- /dev/null +++ b/elisp/init-scroll.el @@ -0,0 +1,58 @@ +;;; init-scroll.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-scroll.el +;; Description: Initialize Smooth Scroll +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Fri Mar 15 08:30:08 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Aug 8 16:07:50 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d smooth-scroll +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes smooth scroll +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; SmoothScroll +;; Vertical Scroll +(setq scroll-step 1) +(setq scroll-margin 1) +(setq scroll-conservatively 101) +(setq scroll-up-aggressively 0.01) +(setq scroll-down-aggressively 0.01) +(setq auto-window-vscroll nil) +(setq fast-but-imprecise-scrolling nil) +(setq mouse-wheel-scroll-amount '(1 ((shift) . 1))) +(setq mouse-wheel-progressive-speed nil) +;; Horizontal Scroll +(setq hscroll-step 1) +(setq hscroll-margin 1) +;; -SmoothScroll + +(provide 'init-scroll) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-scroll.el ends here diff --git a/elisp/init-search.el b/elisp/init-search.el new file mode 100644 index 0000000..3f51247 --- /dev/null +++ b/elisp/init-search.el @@ -0,0 +1,114 @@ +;;; init-search.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-search.el +;; Description: Initialize Packages for Searching +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Mar 14 11:01:43 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Sun Nov 10 14:31:56 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d color-rg rg +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes ivy swiper counsel color-rg snails +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-global-config) + (require 'init-const)) + +;; IvyPac +(use-package ivy + :diminish + :init + (use-package amx :defer t) + (use-package counsel :diminish :config (counsel-mode 1)) + (use-package swiper :defer t) + (ivy-mode 1) + :bind + (("C-s" . swiper-isearch) + ("C-z s" . counsel-rg) + ("C-z b" . counsel-buffer-or-recentf) + ("C-z C-b" . counsel-ibuffer) + (:map ivy-minibuffer-map + ("C-r" . ivy-previous-line-or-history) + ("M-RET" . ivy-immediate-done)) + (:map counsel-find-file-map + ("C-~" . counsel-goto-local-home))) + :custom + (ivy-use-virtual-buffers t) + (ivy-height 10) + (ivy-on-del-error-function nil) + (ivy-magic-slash-non-match-action 'ivy-magic-slash-non-match-create) + (ivy-count-format " [%d/%d] ") + (ivy-wrap t) + :config + (defun counsel-goto-local-home () + "Go to the $HOME of the local machine." + (interactive) + (ivy--cd "~/"))) +;; -IvyPac + +;; ColorRGPac +(use-package color-rg + :load-path (lambda () (expand-file-name "site-elisp/color-rg" user-emacs-directory)) + :if *rg* + :bind ("C-M-s" . color-rg-search-input)) +;; -ColorRGPac + +;; SnailsPac +(use-package snails + :load-path (lambda () (expand-file-name "site-elisp/snails/" user-emacs-directory)) + :if *sys/gui* + :custom-face + (snails-content-buffer-face ((t (:background "#111" :height 110)))) + (snails-input-buffer-face ((t (:background "#222" :foreground "gold" :height 110)))) + (snails-header-line-face ((t (:inherit font-lock-function-name-face :underline t :height 1.1)))) + :config + (use-package exec-path-from-shell + :if (featurep 'cocoa) :defer t) + + ;; Functions for specific backends + (defun snails-current-project () + (interactive) + (snails '(snails-backend-projectile snails-backend-rg snails-backend-fd))) + (defun snails-active-recent-buffers () + (interactive) + (snails '(snails-backend-buffer snails-backend-recentf))) + (defun snails-everywhere () + (interactive) + (snails '(snails-backend-everything snails-backend-mdfind))) + :bind + (("M-s s" . snails) + ("M-s g" . snails-current-project) + ("M-s b" . snails-active-recent-buffers) + ("M-s e" . snails-everywhere))) +;; -SnailsPac + +(provide 'init-search) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-ag.el ends here diff --git a/elisp/init-shell.el b/elisp/init-shell.el new file mode 100644 index 0000000..9e98059 --- /dev/null +++ b/elisp/init-shell.el @@ -0,0 +1,79 @@ +;;; init-shell.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-shell.el +;; Description: Initialize Shell +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Tue Mar 19 09:20:19 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Tue Oct 8 00:20:32 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d shell shell-here +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes shell-here, term-keys, multi-term, aweshell +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-const)) + +;; AweshellPac +(use-package aweshell + :load-path (lambda () (expand-file-name "site-elisp/aweshell" user-emacs-directory)) + :commands (aweshell-new aweshell-dedicated-open) + :bind + (("M-#" . aweshell-dedicated-open) + (:map eshell-mode-map ("M-#" . aweshell-dedicated-close)))) +;; -AweshellPac + +;; ShellHerePac +(use-package shell-here + :bind ("M-~" . shell-here) + :config + (when *sys/linux* + (setq explicit-shell-file-name "/bin/bash"))) +;; -ShellHerePac + +;; MultiTermPac +(use-package multi-term + :load-path (lambda () (expand-file-name "site-elisp/multi-term" user-emacs-directory)) + :commands (multi-term) + :bind + (("M-$" . multi-term) + (:map dired-mode-map ("M-$" . multi-term))) + :custom + (multi-term-program (executable-find "bash"))) +;; -MultiTermPac + +;; TermKeysPac +(use-package term-keys + :if (not *sys/gui*) + :config (term-keys-mode t)) +;; -TermKeysPac + +(provide 'init-shell) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-shell.el ends here diff --git a/elisp/init-theme.el b/elisp/init-theme.el new file mode 100644 index 0000000..9ca5dc1 --- /dev/null +++ b/elisp/init-theme.el @@ -0,0 +1,79 @@ +;;; init-theme.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-theme.el +;; Description: Initialize Doom Themes and Modeline +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Mar 14 17:11:56 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Tue Jan 7 10:15:29 2020 (+0100) +;; By: Mikaël Capelle +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d doom-themes doom-modeline +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes doom-themes and doom-modeline +;; This is NOT Doom, but doom-themes and doom-modeine +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-const)) + +;; DoomThemes +(use-package doom-themes + :custom-face + (cursor ((t (:background "BlanchedAlmond")))) + :config + (setq doom-themes-treemacs-enable-variable-pitch nil) + (setq doom-themes-treemacs-theme "doom-colors") + (doom-themes-treemacs-config) + (with-eval-after-load 'treemacs + (remove-hook 'treemacs-mode-hook #'doom-themes-hide-modeline)) + + ;; flashing mode-line on errors + (doom-themes-visual-bell-config) + ;; Corrects (and improves) org-mode's native fontification. + (doom-themes-org-config) + (load-theme 'doom-one t)) +;; -DoomThemes + +;; DoomModeline +(use-package doom-modeline + :hook (after-init . doom-modeline-mode) + :custom + ;; Don't compact font caches during GC. Windows Laggy Issue + (inhibit-compacting-font-caches t) + (doom-modeline-minor-modes t) + (doom-modeline-icon t) + (doom-modeline-major-mode-color-icon t) + (doom-modeline-height 15)) +;; -DoomModeline + +(use-package hide-mode-line + :hook (((completion-list-mode completion-in-region-mode) . hide-mode-line-mode))) + +(provide 'init-theme) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-theme.el ends here diff --git a/elisp/init-tramp.el b/elisp/init-tramp.el new file mode 100644 index 0000000..0e330a4 --- /dev/null +++ b/elisp/init-tramp.el @@ -0,0 +1,62 @@ +;;; init-tramp.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-tramp.el +;; Description: Initialize Tramp +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Fri Aug 9 21:48:32 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Wed Oct 16 16:05:51 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d tramp +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes Tramp +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; TrampPac +(use-package tramp + :ensure nil + :defer 1 + :config + (add-to-list 'tramp-remote-path 'tramp-own-remote-path) + ;; TRAMP gcloud ssh + (add-to-list 'tramp-methods + '("gssh" + (tramp-login-program "gcloud compute ssh") + (tramp-login-args (("%h"))) + (tramp-async-args (("-q"))) + (tramp-remote-shell "/bin/bash") + (tramp-remote-shell-args ("-c")) + (tramp-gw-args (("-o" "GlobalKnownHostsFile=/dev/null") + ("-o" "UserKnownHostsFile=/dev/null") + ("-o" "StrictHostKeyChecking=no"))) + (tramp-default-port 22)))) +;; -TrampPac + +(provide 'init-tramp) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-tramp.el ends here diff --git a/elisp/init-treemacs.el b/elisp/init-treemacs.el new file mode 100644 index 0000000..bc93c9d --- /dev/null +++ b/elisp/init-treemacs.el @@ -0,0 +1,105 @@ +;;; init-treemacs.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-treemacs.el +;; Description: Initialize Treemacs +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Fri Mar 15 09:56:12 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Tue Dec 24 11:56:52 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d treemacs +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes treemacs +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; TreemacsPac +(use-package treemacs + :init + (with-eval-after-load 'winum + (define-key winum-keymap (kbd "M-0") #'treemacs-select-window)) + :custom + (treemacs-collapse-dirs 3) + (treemacs-deferred-git-apply-delay 0.5) + (treemacs-display-in-side-window t) + (treemacs-file-event-delay 5000) + (treemacs-file-follow-delay 0.2) + (treemacs-follow-after-init t) + (treemacs-follow-recenter-distance 0.1) + (treemacs-git-command-pipe "") + (treemacs-goto-tag-strategy 'refetch-index) + (treemacs-indentation 2) + (treemacs-indentation-string " ") + (treemacs-is-never-other-window nil) + (treemacs-max-git-entries 5000) + (treemacs-no-png-images nil) + (treemacs-no-delete-other-windows t) + (treemacs-project-follow-cleanup nil) + (treemacs-persist-file (expand-file-name ".cache/treemacs-persist" user-emacs-directory)) + (treemacs-recenter-after-file-follow nil) + (treemacs-recenter-after-tag-follow nil) + (treemacs-show-cursor nil) + (treemacs-show-hidden-files t) + (treemacs-silent-filewatch nil) + (treemacs-silent-refresh nil) + (treemacs-sorting 'alphabetic-desc) + (treemacs-space-between-root-nodes t) + (treemacs-tag-follow-cleanup t) + (treemacs-tag-follow-delay 1.5) + (treemacs-width 35) + :config + ;; The default width and height of the icons is 22 pixels. If you are + ;; using a Hi-DPI display, uncomment this to double the icon size. + ;;(treemacs-resize-icons 44) + (treemacs-follow-mode t) + (treemacs-filewatch-mode t) + (treemacs-fringe-indicator-mode t) + :bind + (("M-0" . treemacs-select-window) + ("C-x t 1" . treemacs-delete-other-windows) + ("C-x t t" . treemacs) + ("C-x t B" . treemacs-bookmark) + ("C-x t C-t" . treemacs-find-file) + ("C-x t M-t" . treemacs-find-tag)) + (:map treemacs-mode-map ("C-p" . treemacs-previous-line))) +;; -TreemacsPac + +;; TreeMagit +(use-package treemacs-magit + :defer t + :after (treemacs magit)) +;; -TreeMagit + +;; TreeProj +(use-package treemacs-projectile + :defer t + :after (treemacs projectile)) +;; -TreeProj + +(provide 'init-treemacs) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-treemacs.el ends here diff --git a/elisp/init-ui-config.el b/elisp/init-ui-config.el new file mode 100644 index 0000000..9b2e7d3 --- /dev/null +++ b/elisp/init-ui-config.el @@ -0,0 +1,103 @@ +;;; init-ui-config.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-ui-config.el +;; Description: Initialize UI Configurations +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Mar 14 16:12:56 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Sat Dec 28 18:48:31 2019 (+0100) +;; By: Mikaël Capelle +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d ui +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes prettify-symbols-mode and other UI configurations +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile + (require 'init-const)) + +;; PreSym +;; (global-prettify-symbols-mode 1) +;; (defun add-pretty-lambda () +;; "Make some word or string show as pretty Unicode symbols. See https://unicodelookup.com for more." +;; (setq prettify-symbols-alist +;; '( +;; ("lambda" . 955) +;; ("delta" . 120517) +;; ("epsilon" . 120518) +;; ("->" . 8594) +;; ("<=" . 8804) +;; (">=" . 8805) +;; ))) +;; (add-hook 'prog-mode-hook 'add-pretty-lambda) +;; (add-hook 'org-mode-hook 'add-pretty-lambda) +;; ;; -PreSym + +;; TitleBar +(setq-default frame-title-format '("M-EMACS - " user-login-name "@" system-name " - %b")) +;; -TitleBar + +;; YorN +(fset 'yes-or-no-p 'y-or-n-p) +;; -YorN + +;; StartupScreen +(setq inhibit-startup-screen t) +(setq initial-major-mode 'text-mode) +(setq initial-scratch-message "Present Day, Present Time...\n") +;; -StartupScreen + +;; DisLineNum +;; Hook line numbers to only when files are opened, also use linum-mode for emacs-version< 26 +(if (version< emacs-version "26") + (global-linum-mode) + (add-hook 'text-mode-hook #'display-line-numbers-mode) + (add-hook 'prog-mode-hook #'display-line-numbers-mode)) +;; Display column numbers in modeline +(column-number-mode 1) +;; -DisLineNum + +;; Whitespace +(setq-default fill-column 95) +(setq-default whitespace-line-column 95) +(add-hook 'python-mode-hook (lambda () (setq-local whitespace-line-column 100))) +(add-hook 'LaTeX-mode-hook (lambda () (setq-local whitespace-line-column -1))) +(add-hook 'markdown-mode-hook (lambda () (setq-local whitespace-line-column -1))) +(add-hook 'web-mode-hook (lambda () (setq-local whitespace-line-column -1))) +(add-hook 'text-mode-hook #'whitespace-mode) +(add-hook 'prog-mode-hook #'whitespace-mode) +(add-hook 'before-save-hook 'whitespace-cleanup) +;; -Whitespace + +;; DisTimeBat +(display-time-mode 1) +(display-battery-mode 1) +;; -DisTimeBat + +(provide 'init-ui-config) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-ui-config.el ends here diff --git a/elisp/init-undo-tree.el b/elisp/init-undo-tree.el new file mode 100644 index 0000000..a327279 --- /dev/null +++ b/elisp/init-undo-tree.el @@ -0,0 +1,49 @@ +;;; init-undo-tree.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-undo-tree.el +;; Description: Initialize Undo Tree +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Mar 14 15:28:48 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Aug 8 16:08:13 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d undo-tree +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes undo-tree +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; UndoTreePac +(use-package undo-tree + :defer t + :diminish undo-tree-mode + :init (global-undo-tree-mode)) +;; -UndoTreePac + +(provide 'init-undo-tree) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-undo-tree.el ends here diff --git a/elisp/init-webdev.el b/elisp/init-webdev.el new file mode 100644 index 0000000..68fa1f1 --- /dev/null +++ b/elisp/init-webdev.el @@ -0,0 +1,81 @@ +;;; init-webdev.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-webdev.el +;; Description: Initialize Web, Emmet, JS2, TypeScript, Tide +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Fri Mar 15 11:03:43 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Tue Dec 24 12:03:28 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d web-mode js2-mode typescript-mode emmet instant-rename-tag json-mode +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes web-mode js2-mode typescript-mode emmet instant-rename-tag instant-rename-tag +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; WebModePac +(use-package web-mode + :custom-face + (css-selector ((t (:inherit default :foreground "#66CCFF")))) + (font-lock-comment-face ((t (:foreground "#828282")))) + :mode + ("\\.phtml\\'" "\\.tpl\\.php\\'" "\\.[agj]sp\\'" "\\.as[cp]x\\'" + "\\.erb\\'" "\\.mustache\\'" "\\.djhtml\\'" "\\.[t]?html?\\'")) +;; -WebModePac + +;; Js2Pac +(use-package js2-mode + :mode "\\.js\\'" + :interpreter "node") +;; -Js2Pac + +;; TypeScriptPac +(use-package typescript-mode + :mode "\\.ts\\'" + :commands (typescript-mode)) +;; -TypeScriptPac + +;; EmmetPac +(use-package emmet-mode + :hook ((web-mode . emmet-mode) + (css-mode . emmet-mode))) +;; -EmmetPac + +;; InstantRenameTagPac +(use-package instant-rename-tag + :load-path (lambda () (expand-file-name "site-elisp/instant-rename-tag" user-emacs-directory)) + :bind ("C-z <" . instant-rename-tag)) +;; -InstantRenameTagPac + +;; JsonPac +(use-package json-mode + :mode "\\.json\\'") +;; -JsonPac + +(provide 'init-webdev) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-webdev.el ends here diff --git a/elisp/init-which-key.el b/elisp/init-which-key.el new file mode 100644 index 0000000..72169f5 --- /dev/null +++ b/elisp/init-which-key.el @@ -0,0 +1,52 @@ +;;; init-which-key.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-which-key.el +;; Description: Initialize Which-key +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Mar 14 15:06:27 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Aug 8 16:08:23 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d which-key +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes which-key +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; WhichKeyPac +(use-package which-key + :diminish + :custom + (which-key-separator " ") + (which-key-prefix-prefix "+") + :config + (which-key-mode)) +;; -WhichKeyPac + +(provide 'init-which-key) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-which-key.el ends here diff --git a/elisp/init-winner.el b/elisp/init-winner.el new file mode 100644 index 0000000..09ad7af --- /dev/null +++ b/elisp/init-winner.el @@ -0,0 +1,61 @@ +;;; init-winner.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-winner.el +;; Description: Initialize Winner Mode +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Mar 14 14:39:31 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Thu Aug 8 16:08:26 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d winner +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes winner mode +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; WinnerPac +(use-package winner + :ensure nil + :custom + (winner-boring-buffers + '("*Completions*" + "*Compile-Log*" + "*inferior-lisp*" + "*Fuzzy Completions*" + "*Apropos*" + "*Help*" + "*cvs*" + "*Buffer List*" + "*Ibuffer*" + "*esh command on file*")) + :config + (winner-mode 1)) +;; -WinnerPac + +(provide 'init-winner) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-winner.el ends here diff --git a/elisp/init-yasnippet.el b/elisp/init-yasnippet.el new file mode 100644 index 0000000..8fe5124 --- /dev/null +++ b/elisp/init-yasnippet.el @@ -0,0 +1,66 @@ +;;; init-yasnippet.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-yasnippet.el +;; Description: Initialize YASnippet +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Tue Apr 23 23:08:17 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Sat Dec 14 20:56:21 2019 (-0500) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d yasnippet +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes YASnippet +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; YASnippetPac +(use-package yasnippet + :diminish yas-minor-mode + :init + (use-package yasnippet-snippets :after yasnippet) + :hook ((prog-mode LaTeX-mode org-mode) . yas-minor-mode) + :bind + (:map yas-minor-mode-map ("C-c C-n" . yas-expand-from-trigger-key)) + (:map yas-keymap + (("TAB" . smarter-yas-expand-next-field) + ([(tab)] . smarter-yas-expand-next-field))) + :config + (yas-reload-all) + (defun smarter-yas-expand-next-field () + "Try to `yas-expand' then `yas-next-field' at current cursor position." + (interactive) + (let ((old-point (point)) + (old-tick (buffer-chars-modified-tick))) + (yas-expand) + (when (and (eq old-point (point)) + (eq old-tick (buffer-chars-modified-tick))) + (ignore-errors (yas-next-field)))))) +;; -YASnippetPac + +(provide 'init-yasnippet) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-yasnippet.el ends here diff --git a/elisp/init-zone.el b/elisp/init-zone.el new file mode 100644 index 0000000..9b77d4f --- /dev/null +++ b/elisp/init-zone.el @@ -0,0 +1,59 @@ +;;; init-zone.el --- -*- lexical-binding: t -*- +;; +;; Filename: init-zone.el +;; Description: Initialize Zone +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Mar 14 17:38:34 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Fri Sep 13 00:41:28 2019 (-0400) +;; By: Mingde (Matthew) Zeng +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d zone +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This initializes zone mode +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; ZonePac +(use-package zone + :ensure nil + :defer 5 + :config + ;; (zone-when-idle 600) ; in seconds + (defun zone-choose (pgm) + "Choose a PGM to run for `zone'." + (interactive + (list + (completing-read + "Program: " + (mapcar 'symbol-name zone-programs)))) + (let ((zone-programs (list (intern pgm)))) + (zone)))) +;; -ZonePac + +(provide 'init-zone) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init-zone.el ends here diff --git a/images/KEC_Dark_BK.png b/images/KEC_Dark_BK.png new file mode 100644 index 0000000000000000000000000000000000000000..e55762e2610631e6c07d564958eca84a574db156 GIT binary patch literal 88588 zcmV(-K-|BHP)asB@2<8Z8sb8^n_T>ZiKzRz<% z>%HIi8TWnN0{n-cKoV}_7!D!?zy+k@3|`|tZt7mCn2KviM<%W#M<69=T=SAYgdelL z!A-Qm6C8yuDtue|JRF~U@Jbc5M>Dj58awQ*|FSBYp)H!C3I;(LZO{QVFs8h_;U5i& z@~*%?6UXobN3jo`gmq*e;XbZ4Qkjxl6fS@W`2a>VlF7+v zmBsTLJWo}c*(7+{)Ge{jM()mw`rgjPV-52O`reJ6W++9?#45$}m85RYnRQY#H*Xmf z0OSEE!p^%{5J2dSw=CN8df#ibhAQ;mnHRNzF501gd3Vcy_82YXFi=^Kk>7H(r~-gw9Q?H$_vUKD@=-Ji{}*&ey!f z+q})&V_nfjvr9miEA^Yh2?@Ag-d*$$!+&3a5?}|eAQs8EEovZm**;$fpcG8BYxox8 z9JWK-ajQb8TP9D0Ua*^lqKGil+K;ccU=e)ZIOFm4Y*Z9M2&o784*(&A6@{0IZUKPc zBr1y_C=}H~5mF@}faC%gN<#2P;yEA%K~>RX+`0Mo4Ip#98uAf)z2f4$XCq?QU`L(7 ztMDNB?kU`7qVDQh0Du(kEfVJDUko+R2nC8XsE_s-T;84c+v7hK_%2>!Eux@@kcL?j zx{Xz5vIuX{(*g@_UJQ$LnJ{(H0i~>59ksI+(kF`m3knK>*k{OtXn(_FYw-qBsDx#PP*$!m$$nBrh;Z3+&w;=r>p;69mzB{^L9x=k zk%~~>UVl3X05HcrEM72F8EB4bC?Zf-_+rFe*>1Ty*32cK4n?U|XlZ>Gl^qY@-LN=F zM6E&*UQJAdB*%-MZdZcT#=-6Dbd^HocOB)X2rk(Yg5|i6G>Bx;KvYx#_3*Y58bGLu zNzl@nJZ!sf+gl2#qyFIKs-Cl7&T+8RMPr*H8ygg1E0O@bREw!!D1o{#!3ao~cjx|x z-y4_Ui5l2jv9^+@19x&OZ!?20J5O6+INXKjvm3dvU{XCg+vDZCoDQ({x9|DzMY>Kx6Qf1D&S1aRv13+U%ui}m zVM4riK6BChlN`CklLu+&}*3<6wQ}F3xpuM zYprDmPS#^hfjU(4Yi!#5T7*k@03qZ+2q6tg6e0uHQHU&56qn17HMpKrguJJ(kcrpG z#xvxBC`2vfAR9u2#5af+VKl1a3_|4yokET^)RFJxha#MX^bNbPM%&i( zG{gP@&s$46o8ijseJ>CzaI(k#aaP^ypB=p1<ZmZR|WXAw=Z`sSoBp(b`}=wZ2|>+W;tzb`?v=c?gL2Zde0dC!BRR#ZBWQ`cg8jOWHBJi-3LX_@8KD{CHO^~eq5f8nRh!S^Q5e+GSwM=0C~rB3 zlX!x$c!^aL3x`}=u<;U^@Rn#{-Y*qyMy`ylma<7p^!yoJ39f67f{NWGaI<8{~(h!Rd zcz{-T-Y8c>4h49LOaP`G7hAo>Obq={bP;aiJ=%Pn3w;|!Xg*N^N*{ju;?<7a*bKgh zJn9sw-&ACC^nnQK7!Lpt6cwkdxc$X;0SZunL+h7TZ!+QhC@4X8W4rg4_qRpAVN*8& zxKY^H9ygwtD8C6?b-aFLba)0{=uQv2sp2*MW=}<+8?Yo_l=)m#-8tCip}Jjnh3+2;%)u6%EB>z|>OdJ)-k)0J@jSmk zybK@!$Uz1o5CwRPeBi^ESpdoF$UH1itXB(;2oylz&5 z?>d>ASH~%YFs{dub7%@{jQu~EBK&`}5&$q0-dIt?RW{uXJ-7S)lZ?p5?kHlxN7BMgKJd~goN=nP=Uecq4TxpeuRrVH%78(=hWZfL)ZZu={| zqbF__JsE*?Ewpo+H6Z@Zb^WK}M%6&s*H!m##bZn@?;-q4@vr|1gkw1t%BJa# z?~5jA-`LIJ^`s5+rp+?7(9C?LTrVgx@T9$~vXq|r3V)nL%LWSvr1#st@99HGU?kMg z0%vgpv4|DK$k_@O41CdV3eXKIc;9BBa{9;@<6@iQIw&_2K7a^?ct`%ZOB1{FID&i> z0suCPl8Qdw5mE>ip9=sGK?EU)LP2%;#}1JHOo#xoGd%p=Km0t3Cpd~k+(TQ)p)QtV zgTcX?hmh71CP>F#NG*qS_>zlZ=gzkG+j zb?qFkKntVpvDC6jayU5jTn7hNR7du-EgCC&rue?s!=UmW$p26_7$ddP#9lnYOWZQU zj5<9K?( zX_rw3jV{y$SbcW~qb{;thuQNE?=X$KdELsAA71H5#VN!f5PLf?Z;J8zCU2X(X+nA7 zC$$qn5)$G^UkFLaKn}8y0+8R}Zj=2@!kSEN(yvL&CJIedTl0a2=a=n!3};9~4h=99 zZs-fj_%%^(<~EC`d79UFhu74H)$1DE^@VB!xQi`~Qn4Js{sui;`fTSJzT;b-SJ&aX zEvTP;q@Hsb4(xSwQ@*c{+4FA%J&;!I`I;2De#_EGt8Xj-tBsOh@19z8mSe@79e%6hVZdPik2x{xlS$sCY39;3lr$&cI_lM-B)nRKW!qN-dtdofx%r!5{0+b19$@p`CVVpT-oEeb>S zBI@n7SBVn~t^beD5B^cu3`#^dZL7`WyvFqmV}dyVz^Mx#t{6;Fv*z5yET(Z|)y@lA z0FFon03^W)0;JWM(X3}jkAqC+d8YAL5A9_d04sSntfn?^9g}&IyP3u`tNHSsjXQ5^ z2UN!pc;gTj4P!PhFj@SU$~2}ijkkCyw(ZZg=wb!l;Zr6DC0m=Ixk@v$W>L+qssc$> z`GPOR<)m>pPcnJd2FaG{&BB{e!U#=qx3z6&bRIC9X-s1(lZVfdX}+`>Wz4Y|0C60n z0XVj+r_Ezb;A_UzZsI?R_r~fF-FoqPOph#u$s_rIm$`FhYszdc@4@{K-^Xr@M|*7P zVL6{~_=MpRor)woRpEXEt>th*upBpY1AUmyEhb|jcUr0rT#=0x7=!8wcTkR^+Au~W4u35DiiF7&u3)Hp z=&I12p-unqwrfbK8|5fgaPJZ4thfYZg}~XRPUuWx-o>I4CM-DFo!wJ z;XMW0YR-JSd|H;=A-REakQ-KOQ6NLPjE9-S94_xVb)m&hd23Vy;V28)x#JniAf_>g z%gv{5ZZQ?LFa`&(22%hy%G9oC?!<%4VLtO$So9L|7$b^A^D%BQPudxA17CC5W}QBm zgp1`p(7zD>qUA8L0+XbI>p%4HX@zW=fLvFPWug#8G?43a0tuM0sB)IIYY#L~_tt-8 zlj!++7e>Jc$8iXAFix?f^^~@#4k$wl5(dyj*FV)@6XJ0X%1}c?C_)mt5TXGZp&z=T@i%JSAIeoS`tKZD{L6ED_08uq z!@fwBkL_5CYj}c}qJ4c+Wey<~&+)DoM&j&#%QtuLApxi10vQ~}VeDW8MFE$-l%-}cKpR=*kjraKC80@+Z-th%e)p3&G~ zi5y%<6Jd7V{Bce*S4u|daBRmhcgG zjTo+18L(Z(14cC;fdZF)e8E6I>N?kO_5S<5rz}LxZe9Qra6;%nLEUP=b5^pqwjZe9K=@mKo<>B z8I-!ExL0BK7ikjU2{lk5Lb0}@MR#uJ7Vc*z540Z=(H#gve^9|eF~XiZc%GTuGFq1s zb_j(TfOGHxMWKooow=PEd_L2izC5{E@t9!97+wqMJ-iR^^M!ll-oC(Tn3ngz|A%4> z0wrVBZ9;jE`x-w2J+2!S{X0GOu7cgEhEG$%k4)nJdkpOu(|ZHWD33RE@_arK$P2itphM+bDm zU<_~18;sah!cB@(*nyyL-n|Haw1p~$V=^Mu##u6$Z+VXquHJ*H0P8Ri6R=lvlqFX) zlWVP)IX5^Y(m)h|i05T0@d$@G`eF=%5%ckC1jd0fK}{S6%}wH2-s)zvuVryNN8yFMV|%~-Jk48Nq~7g- zsxB54*ACmE1(TXXjCqo`c#D@~YCRL_PhrxEcD7Z5BKeTF8|zN1VTc`n-QfO*?_)oz zB2qMFG&gb&pX<%jhBtP|F`V1{Y7o7ZxQ&HO?K8_(k?09$c%UCBNK#$o$z^=Q^~UZo znnX7NgvMftD=`K@u*k8J+YFv#Qa90;rBXPy1-o( z=py53t?I^GJf-VmUgfw52nGO*1YjdG%9;s$I^4&j7oQkUzJ#%$Froc4e`a!*p2Yx3 zAgt82{SQBliFjSbvKNo?qSFRz#c4)7W6__&7|6Nd&bI9=-#Be9+SDVo5~5eLm!kdY1X|jk28fgd2vJ^oiA2=y%98zH~0sV zdv=IZcvYqr9IL?ljor3CLgT#=i};BIGXZR ztLmR$O@R+Yux?>8n^(Dm$1SuIs~8~w0I&*Uv9;EKA-uw?OkUl{4i^BN0WfwxpYa+` z8|odYu^12ko`L@lz#aIb7A%ywjgNSWp^qw#1wlVvUoKl0VfA^09~9^MBwdbcTQm%C>SL-qBFyp&h18{7fZCnNNfkN2!M|4bSv)UYP+cy+pEI@n~az_ z!8)dyRS56$;Nl5|vg5Gp?|&TrKe4*TG)Ep|wwKAAam?)1*bluizZuWz%`o<067P?l zw7;)uo9=gDEDq{p5d2xx35`QTJZ{F+A^!-AV;JD08(LwF726FuYXx4LKai_HDr!A zr_`tE);3}$4|Q$cxn@cgIoNz+5RxXpx@NX~3wQ#U+k0v_?{K}}dfz6L@&^%wL6`$u zMQvkV;`!b^?P_u#51y^R9vU({#bJBZi@?;}kV06zi z@tmkw^6PlBzr&~L>_yXtatn7clc$x2O&_|qwI;l=3BwTUz-Qdn%qX~HXZV6LW0ed? zau3tTEm_#30$gDQU<#U|e^p&G#_$;*b*~qWfGUjOdQX+sjkt>s$4|M?)C?=j=kfUW z!xfZ>YQPYtYS?+Ta-YGYUDOCjGLXl(lBamv$a+uxF0jNQY=Tpl@4tVmH07JGJ!Fn$RDq=+7N;{KGHJ#y7PgT4@XNNi%)Ut~k z(|9V#tPZZ$Fg4;ezT>&smfetQJl)V-ipC6qD>7#z-70 zqol^)Qh~z$CRtzXY^{MgC~>H9+a}X2d5Wiag?E_c8b@JZ&B>#f%y+y!$@GA#A8e3P z-BFiGyut8p9f&CafQe`WmnPiDYvinLtQLTQ9hp4D%Z^U~xMPL-Db+Ts6y$65gU z^th6_PW}_6xq~~e3P)p$HZReSmw3_4d9@-j1^W>WLr^eIwc}jgW>TbmzQQh9Yg-=T zW6s-Pf4w5$gR*To0zi{y%=yYgwk4@r+1u6%z+q7@k)h~-h|nst9D~XH7OuVcDuw%H ztV0(7w?q)d3^sGGH>XZL!WqC-nT=C5JekH*9xmG}0Xo zEA$)8FuvFKbL+-)oh^o<2KwmmJ`1>U@hD*4PxSSF_ym)XSj%`Uvv@aHkFqf^>B5JT z2d9YwocW5k2U!O;w!}UFz-jMY2B{(7z;LEFg!i=*DGhyDJDTd>hYcZCY8k3jR{r5Xw{^hViYgn}4 zDPEfu%9qy8%aIJqF_s(X%OpMbDV2%Y0D$gL!I~C*o%xIjKF*uuGAm6q<7r+uU+Pz% zBFkU0Q*lAqs26X4_I&NxG`TFh_`e>PBs$uCb+LYGYO}Jui_c;#D4ecj6TtJl;%0TJ zrWd*(OxArIxA2X@EIm;tBm!^+MUnMKFX4sGE(>h=c!DnxfY4fe&H`TP)v?caS(X07 z51@rL6?~TP8neQ*fvJ<2tka1yUQKw2IZQHcs*l-N2w*S9VQK}hB}`_T!Pw)qreWzM z9^z9YkG1V4VG~w=l(-i&(F_#;sKTk#^;wPD=+ukXnJ#|3V%jQh!}(v**2$RsQ~7tG zokUw_=KVgzRc4Rf2@QpHntpN&!;>RBn8G^|kGJ-XS!&svB4fm?ZXc;7vMpy@;& zo4$hS+%;?Hol3=iC{|bxz@#6em@vX_QZ-#s&w^sM1<|%^rQRy9}~EARJce7V__Zs>j+PN@AuB6F>a| z3~f^Hr$=HHD6mkPv4E#}cWhrxOhYFuZOTo&;l9tcekeXHd{Gr* zLqS1^DKoj%Q1h5WW zuu_XrOy`y%iXAW(I}qK6uNJtuV*p}5li3y!v@zrBj}OS*ZhgaqrL9>koKOdS(F2C) zEWYN8Jrbkj_x*6j{cWsl!;AL5?@C>p&oKo35Uc2C-rGXMqNl}Vi;d0O!?+A`&cYQf z(G;%O4**yTQ%u0z=6xKP#Km12Y?PP#NtO%(aT#8qX!USzVJ_(%L}`FR zgP}ah^?WzpWvtNezr}IMaUFoZ6)!M#=8B85cM;!|$y~++USh0SEj{>))9K@wqMj~K z^N4x($CW;Cwkb<;HzOW@$=D`ToXqUcrU~~4*8TZm*^5xQvGaL;`}nd-$UrZBk|(1? zWtH#;BH@i*&_EAZVojMOc;IOR|88x%sde-3_N4N(kJr5bXg8!kZ*jpwO#oP;I^2)% zxG++)I0X@f$V&CQ@fxp$weJMqR?O^fbXFl~5l^ekS=#dFzexWVAT)5b$gr<5;x4`U(kTJ(M_{J=5T6%_QY$*p`bbfS*1Dn6K-C89q%c4wYvm(S%!z z=eWX6^HW>M^`NYi1`ji%ew)wbuB*a?uk4qcd{)ZGt~FX>2DXZs5;x+NtfL>_lT*iE zE2T137fx!lqXqzMQDO$kW9ns8fu{n$uHJ5@vSmA0{v0-HO#Y;QiWu5o!S9p%L@@kS zd@u6FYHfgsz?|CL$t&Eqs@aE$p$j%Q?q`&=nQ2 zegH$5#dX&D)&KNB`kJxeD=Kg-xwI-Uu%(sr)a_GK+Y134l64GZA<2_Z>mMs^bLDt> z`Wyh5tHgAY$M8j6;&G@1+qu~yCbE!$on;$-ytWeh=p#0FE;($$4S(vPBCc9o`SVmy z1w6s4DH_GUhT*>S*gm|+gY78r!~{d$<)IMOj-~CX z{}*h85qfIzY+L(TdfYR@FGPA6I>>W5AFZB22|aNtbp%yvugfb;a&DAdF=*6MU0tlf zWT+v!`JBzX!M)vdH_14o?w_Qaf8BuK{ipYlxG&w%}G?yrA6Ob}nQ*C?JenpjQXh~5pEVHY^2E+e^VnhHfv06fP+j7N+5Jjffv zhTWGR+?1zznaSNv~^7LXz`X%vb`GsEG|}o_X&=lr+5a(alAhFhtZG7lHkLZb6YKeJ!3|27(}muj972U(s`#P|tzNU7Y(K{g?Xj|2@nKt#`=|GJBEJR? z@wtZ5k7e~m57STl#fp&=u=052($&f5>ngyppVe$Jx>RI1-x;}BRRAuCua3odj8xoAE!U)cY1b#)^qKKB73k>pdAjb1 zmS4V@=Xl+Ec(zLMxppd?;Dwu2R;=R10n>LhTMq!Zhgq;{!gI{#%czmIXbkNRyv|!Z zGbFIDoN`$@?%#%XpwMR~-!r051vNy}#K{blMvVujYN`2aBzgEs30DS= zpm36-_`REbrWF1H7Z8Bf0G^8&Lb8YjEMTGdNjp5>bDigQ&wZZzJhyln%;i0j;Tduz zk!ywdn?8Qs(&rfD2}g;EB7clkSS9}7V*xjRO$8=<{5g+1Cb%F?9#-Lvbi`@uVSY32=XrI*lZs2*^B7O{?0>1cQ5j0} zMn4o!{j0zMdjJ$a%yyQ1P4c~$E=x?2_6jL=m`0L(V^%^Hc!?EYm8jC*y&o-& zzK^6i&9pJM1k#suVkQfD%iQNs>k=gYh&*hUyHxSRDYBW?7pEs=-jS~c8CZ=vm^PGG zd11PLO!Lvx`I1+SXEl&?M5rcDGi8j{2cqrk7=e*Se9gO0|Pj=jc5^5py%F>-w6CdI9)FwdKpJ}W=pWZsi+ICEM7 z2&yn;1{0XWt95%eYszB`@ax$MbEO-aF{P$f8?g=17ywHR_>7F#YmE+=Ta#P)jHmcw z^03oxgB-;jM2Nz#t>_?$uO z<(HJQAM&Ja=aLNTQK3G7e9VWXdKD_+rZ+ZpWC$;Y_&<~@HaIze4j58}QG9FR2vn`kZG1JuELO1R zr^-EwMd*VFY{X=|t{F0l*FQdFv84|vbXS(UNRlV>e=vf_v9UjIi`NbtR@A1DLf1%= z{*Jzif_=?-iYU}OM9eXxv0-f9@d}A(^g?O)XG-!KN4**v_CVr@D2{a z3;vav%XD8c1cyLz~#KPaMoj~VvmXjP?PEA&3)5)ysSQc4v*Js+5y&jBvXzzkNwF~ z{}E^nphthE^!H@)G)uq~M*VoP&d_+_hb2)n5Mw9tmFt$X)pqvcavqss_f)>8`0ikw zRdAm{UuN=f&uPTK4@)*54o4|2U?S6)yh(jh8A|(yp&gp*@QkHV8!TAHEZa!~ba|owus`k} z00i1rJkz@mE1C9Z2G0&_JQMfDcimuAQT)*+$pW7C7*Wz0VA>}t zP@@YA`--hkSE>#g!&F}8Wo9v9ZIwSuzbxcxl7(TxWf_sgs!U>j1EY~1%VvHgiMinJ zJWK77q7am0#RFv#i-Vx7WoO27!HmYNIKBsu_H&JHQ0zVCg?L#vZx(XhJgJp3I{wUY zvfR{_4|q1F`L;5Z_78yyx}Z%zrt{#Cnp$90{}>kVuAN~8vki5}TcA5&G zF>lo5lAj9{wxOt3agtA9vey=W*+L#X&t5 z0yrnTLw0~Hx3j?Si}}8ah^KjlC+3#PCnZ3U8Qiz48b!{NKW^5N10XV9M%fF$?cF46gEF>Ybibn&!eYd0yLBAGp6^6kpJPV(&eQqH9xLr#w*N4tMN zoz!Gzt?T=_xk4&7qu3I^Ww8oe+28z+yAIVI8~rh9T7`v}11)UXLQb^&v-FTr%vj)i zuf>%zxo+Aw;VZSt(KuU)XGs<^olid68@=JvIr9&c*coUMIv}WOQ)LxpUFDRT#Cl9a zLLKhrjlm-qVoM_)m?#CjM2O?^9A5HRoxP56u$qh3k$*Qj3=Ms{e%ohpYTxql^R)NnP18iXP zm6QQn$gnAYzB+jx?@v@bkCJ^2KZgwhqxmSLAF$n#?@4BKSF@@uCXm0gyU)2AS&}84 z2=zvEmHxwclF#^z&-ifqh6aJHLwYrQ#nshOv!`kD?50UMO-WNg58_qQmzj&s;2}dGW5n z#raNtH{Xz{bC%ry<~zEb*k$I&zQf$eQ_4xI{I`PslcwKAdzSdI2D)aC=8KcZ#?10!B&F(6r{cz>t{ z+STKJlJ9IBQ$_PZxQ6qk`UqlV*&6h_q6*Xo@B)wWjF#(JQN6l6&~09Onc5%kw?LOp zOwq6a4gpw+P(Nme&E}tmb(!baRiLwF>1wl2N^c^clf0W&=fD`gCVAniQnA0(P_5D} z{vOG5BT4S;`n^=g4Ni2s_szSVf1m=(k@Uf1u9k7lFTYcq#|ND%pbYSV{s=zQZwaJU zWCY2_o3&10O0fao_PwPzDal0D%3S$z=j!81ZBOg%;uP+^_?Ri-&6{HSFkYFvC$(6BhH2GXoOwX?n8j@`KnF>%u(f7}gBj5~fCYdu$jY1wF z`F8q*8M@45Ap`bGp%l0ZH$7&OFHBLC3p+8NMXtdVoGSJn&iCl@;~9A(B4G^x$SkG+_yWTMk|h8j z8o+98-r;GNmMsx($Y(s9Siks;L<6RExrYlI$xgH28@JekDt&wKqUi|W!4GTjkHBzf z=rEJ_AF1ra8+ooHr}_EHj{SJQ4jO7PWyqvE;)f&?g%u;h_*%nB?+ZJ8CVj1&dwr$? z@h&0jxBSq?{&+iHAs4RBgZ)6hCz)`u1`m+D{n#GGkMl(&hRTeZ?xU>KiJ+ zFy?J>p;XZ~@;8BQnMlE23;OnAp{)ZYDbyXtB0k*NJQ36MNxmKCeZ2&W;2X8}sJaRO zAV%ryo(8->tigxWa}n9R{W=_g=(ZSG<+Gr9g)HA)U?&P#l~ z()jlvtNbZAVKBPrFohv}#Ds(OC+jlTYc3_M#rKmi2ufN^F*YNLX?RZKUFDD{=IBlD zB>XcmPoB`h^9$c7lB+&j3s|fm6KDOXWna=Q7CYIYH(F!p7}pb^L6P=`sRj^l>v4C9I2 zrCeBELp=7P^u`r`V31e^mVHkJUNL*i)D5K*`~!>~#SBy5LjZi0d5c-zZ3{8BI-jv% znDOHhoRHj-;aZ+9Hu9XU^iBVV`*EHB$Ws?`5*jW{8qi_{wsvM1kFKl}0AL&ZF|Q7H zav$S(Xr%sY`9NhJWxzmb?_b*HzZFlh0@M33oogu<0KmK*Qz!Xvl>8%zL@fl&=luz$ z6f6J$+{2S9;gQS^m`>5x4?2rPI}N$xlP|#?hR><>VKcBN0wnv)BYC`JM_m4jyw5Fh z)g8gDB%dB@s3#Lu^?50e$9^6|#47MDOCzV{B;&Y|`?uCEo#gL>^Z0OyB5)K={w&lF zxFNX=!v^pbPsAu)E;V3s?5zeZFDdOn*wWsmFsB{_{T3 z>5)+G%oI~|N)WG#b119`XTbs|ilV+DGZlWI^!d@d%_7V^%;uY|@2mk60Kf(eK#b6M z2H!Dvo_Wbs;DLmZ3puqb5IBUd`F2pFu?Q%!yWy{ckyr(Wd_x5mEGPNiYdoJ1(f`?) z_n*SkWz{T7#N${iUghl-?RMdWB;!~VY&xw(`K=5|9+MFP0A*+Te%1M>kPEkcmMaAm zbg03*T5|wD9PGmo9*(ZN5CAX{7WEj<1zwWY^>~mAT^I1ZyMKO}e6!0Pj@Vb1k9qo3 z>m^=%%Y}@mueOZq$NL>nUyCWDO;sy6`L7)V018;@$v1)a1rqnZEBPMIUej3Z;NT3V;(8xPpZ|LM;Cz8o}QMU9k!@_=XDX2x1WnhI;j$$_(cpvI>

ysZ*5 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

$i3u6%PB^&=F42kihg_86-XLT%=VJPMmy6Yi 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

&e^xpvh*sso&JQX4WHZ%`e!CTC#-)CAK zs{Ox8hyDK-7vK#dMc>nhSNVy_(T+!z0AB!i>+o!QuVIpfUI?bFWM;7Pm-mMPs6UXe zw{-XSYY@O4{J;w;zHR*%`^MGiD=HLGPz@f~{B5231N;mTSc#!13ko4RK4gMFL->#% z_qAU;(DI=f#~t9`l*c!Z8s^oq=(G zObGTb{;9~qEaaH>wB#z@VA`ZUt18xkuN6Nwtu0OJ5mAO)!gl6}0N^4nBU^TFdSV()kN@WBrhfmkd+CurbA#UUmY z>(AcEv%JPTyw-l8TU%b}KdGeZ;v{nzyr<3uJR7170EB%t-nVz7U>2y<#)KF6f#+-V z+G0VaL*Lq=fAP=2arD4+Wv2#=<~<&)2#Xkwwm<+Y%20`vMlaC%%7(Z*HWxy69!^-IqqEE+5oroSK0Ko z(I3RKe9p(*%VZ|3N$_k3eM`O7dRKITil~cjn2b0a#fd-d+1If`~gfrd%RG_M*v8Nqq?79i*PWy0s!)H z_{Aq=K1m-Et$reVz{W-M(ubT@I*kX&$Lo=j@g{;0>pm7h#;-6PMR<<_D7`&0Prr|+ zu4lif${+9%pYa(=63Wp}DB{P@pOq9Gk3XS*jdEQ9B`D)Pwrei0hGyuB#)bNuR}^O8 z4(?-t&ilSa@h`AO60mX!Km!24wg+KrUX0vx2ydj-g~d+y``qsM@i?@@ag7l%A>*2C zMwOmr5iw<5&)o;^>L3g8|184UpN9Vt5deV30D$eN`}pbdteulJn@yOn+;*Mc%@8ph2P2d()#2qBoBxe-GBT1M$Q)d zanmmS(>Q`hU4EO_GQNG2D*Zn~9F!I&E%K>HC@Mh(2F`z!ZdV62aRr3{uozm%UGLu+ ztOkuC*T(Pa)BA$pEg;U=_yK{ETTFn?yEWv)ynHP@zy|=x!bB0e%utnIOV~AiVw~B* zGn<>XtlT!}t`e@{W0&EL9xk|zPepi$hZuwJV`KUk{}mv%qbDfnB${Q#7#8wA_cPC^ z>P-eB!3YQgh!oQT610ARN$u`Jg!g%K>|BZm5UE-rgU1i0c`h*kc@ z{|f|x>Kj}47{DvM%5=vxh6WOW$z3ZS?)E+d`HrZw=mr3Yl)CpoOh*aLvruWnjJ%JS0|1B6 z=`*k%y#N4$nu5;Qj+X%NLg$=!rMZvp{aNdu{<3dUO?)eWL6ZMB6F_iY=IwC_ciJLL zoWugq*^Ut{ePZS0&1y4^tKlg&;x<;|{GpkH>yEEBd0Ry!<7&v;n{)fWK3&iedANiB z?Rb}8$e{VpL{&KBBu*Dpd8|4~V83s8+tH?H@pR;1!yWtLTQ`a-2hpof7FdPJf(`cV z1lK={?>ekH%weO1OF>B$v|rk@SbTJ-$)$)Vk_hG_0;rZP`cy1$Z9G=tzU=7hmYX^v zy)x2#%XJG-WFyZ~*RJov#j?=Hw;xgLrYgVBV=-!*cdJ<;PrrH7r1+VgQ2EM?hI0oE zPjPMIq&BJEaRKi}Y-o~6yhb8}yhYcG+(f>l!L|B%`q%KP( zMZgPc(EI}{{CQoq`BlAf2LQ@%#gL)?2~vu@bI9r0@{q)*Sr;KfuVNGU;0bo%0#rYt za_y0|=UG?ANhn3V%I;|K>eACXxQ)}_mml;0DgG4!1&D{_R-`?>@ic$vLv%2>(|>~? zzXxmqs3Y%9mnYYr-2RMFAG4HD+^lc~s-X|gsCLt+Dv}Q8CqPjp$-KV@5LybiDzp&p zKDV(}D@eX2#U)xV9$s7(Ve*qweJ6>>dM!UKcIf|5fR7L5@o#UTVd#1=lzQs+)euAjrO17Bmz{VWU_FdMEieHjHjj# zOH|I!lZv+#% zEgk_qp2t-fK;U;Ydf=qu$qxi?fntaWD1SLu*nb876@kCNXaGR`+k)%5nC|_;w*nUF zsydxkK2m(YCu&A*gb-P8_QMRST?f@zfX`kChPLp|W0#^K=n5lb+9Ip!j*@k%DX2eR zxTt=@$EpC1Koj$d0T#RC4xXUbXW$kAihylm=@8vEEI0C_Pym>D6=8#4b3foYVl3kt zv)iZF(IcK6f?x4QzCa?b$#TB`i$BJ{BJdwE001B$J_Ge0-wzbvGm6$8sj?Oc7~MH? zG>UO^)WA`e&;x+iI*6-fstbLzd48cUil=ZS>Z1y(Km!1Z)gkzN3NP^nML1CeR{1;w z&j7pvicxI$xi&hKd0fS?8U*c(l!Tw~7I8X*M8_(P?H4u6SvU|d19%!wQMbLo3COSM zd-rwAVr#T4=$zFOLa3lVfX)DbU(J#F---W?J@6ln%eagkIEZJ$eDzI;Lz-ZD&zIf2 z0H7ExAhzhAhAu=sBlJ)oRZtZgZ;{zNYLTG(&FsMaLx zZShSD*g^zV6iSu@0;uC4E=y9jewqh^;`8C*kAczfDXvwhf|lrldeB9Ozx%QLSK?n0 zC>72k7bkHFHxPwf97i^OLrSyrCP#4;AA}z#p_xMAB3wcA`H{EP3w{{iO< z&m{iLrSAX$03~!qSaf7zbY(hYa%Ew3WdJfTF*z+TGA%GSR53L=H846fFfA}OIxsNF zK-j;DP)@iXsxy zN|$tZbBWvc&hHQ1UEMX%b=Td`_xJD*_kG_vb7tne^PV|#<{S$DAD=`x-r_2Rcm@>! zJJ>3UYGgD802S_~CV5m5YDo>sNwZK{W%C$q9VSg)UP?suD5GnFq5`EZbW46SQzWI) z#y(Qlo-4a~Ku6>^4f8f>PTU85X~DY;15sf1_4S z*O%-s*kR(fL;Y3ik++?D8P5$k9JW;jofWw~A0DxTgq3DnRgp~N-1D39=Afo)C#~{x zx2I?^C!dRqz4fwFbU8{C}|pa21KTjtJUA78C?+WL3sl6nCm1ujy7! zZTR#TxFH^P=kEGzmCjAtg46IxoM~t?wd`Tj zY*{AP&v9GZdKGz#j8gqXSDV^`?Uxpm<}r@#Q?ENbns5j5W$2o;9@Io^isneNQut-ZrgBrWmMp(nvJheb}$eJ3Owv_aA9;3>VA8Ih`?qT{p@c1DfmArwjw;jK4j8E*c zd73vk$!m39@UWTAp!93l(5EA}eWM~% zTg>L2ZEKL&>e|)EO)*C;n)cV&zvOzJG2c{vSzg=psmM8dl|g}Lb}##OGOc){g)~{^ zuGU1VN|RPTQB#*w2xh#Mp=(kK5Q!Q~re*;Eq@X~96l8#$w|0qwimnSKK!cc1)1rw; zp+rirl86K_XzJde&<{+eUQ^LVbsPEuY zf5{|ko-9qr=ow!o+MvfsdCu7WGdZEJNQ^W`%6Wxnm<0uB|LiXQhwy(wY;7?R1!%%- z+9395#$yxjv0k0JswpbRzErrAVdOG-_mksRwk{j!#kDdrL9#W(p|oBMp8zSpsHIIL#= zJ(L2R+2ed0n4W}5nCg-)acViFG^R>iVRo;pj+01s%05OBEQgorjtmT}>cz^RR2yYb zp{Vk_ulFmgoYnEQ?D-^X)zQu?&ezCBlQL#rs~57(E`o_<1WAN5`rv=t?(o0dHUI=S za2xw!Np)czmwD){KXSAsQO=Q%^RBKPKcRH_%)rB)OxADS(uUV%k-?Spg0?r8J}?w5 z8Y08Wi8xx1VOgs-ZZj zM?JXUK?Dg1C?X4as6rcRP?Zi83eW%=YEgtY7z!oKz)aa#`V+(eaA!OlfG0THzs z+{;>qUkeC2$#8{9q)yg>I`zvf1KPavxAS+e)|Wp&MMwKy2nG(cRX3oQHYTol>`@{q zh$3`hFA|Av==MK5y#K510+5O*q+>6@3{_(5`1hV>!*b<@UM=ozrO!UOQHwit*UQX+ z12u9zcFtl(>})kL*4Vh-%tJ_HBv&V0sBRzPToz4s@FK;)ak7)NM;4lqi`}%9?|O}Z zzD!Y5p$l4rf)r8+2~W~s%IvtS)15eR28k!wbcF%Jy1MZcUDhc?S({vXpXzj$+0)M z4vcktAEnFN zlnIyw?{$Pff}#LDiJr(zq%I_?phHva9@Z^Yg{Ds#AtGx?ai!D&rQ-9Pb0h~_1d{|; zVGkd_suzV+I?Uxyp3ignrH4T)j&@`F2!gJa(mnyc(!RXQy$TCd*OYS}S$d9hnrNG( z*rU8|^^>}=r)A-MdGN6f`agR>elY$AXWQfO#&b|iUaMmFO2^iEQU`in?5feh1BdS) zcV~5De75z-^@gb#J~p}ryC5p&D+`o^6B_QsMkK6|c!|f5RmjC5D8mO}?lhaCqD_SI z*}e0X3#kZBFTF12Oo{~-m|zw#LP0?aoCX)hP_B*iU*7}?0L-E3QpdpqK!J`PXa_Df zO5X|dJ~fMu4FmXksiBFc8u3 z#un-@L*F*J!!ie+3o%kmF5jNin9N?f`m*=MOM}I0nb~tCj+6I2w^r(p4&vCv5S8c| z<$>kfAcH<|_}K&V1Mxp4wghL;1-6uuc1l;8k**uf1r0Hqqt)8=09)l!+4t2m-mk~dO=+l$qVjk`e}5wev5+AHiuxtJ z;eh~z;IOHTwN!Ch=N@{Mj1Yz?uT2=E z9OA>N2Xa6_5s?xIw4nwCu)zfIM(O$VW_P{>kcv~&7MDo~0A#C#Ix8y55jFq<3dzU- z6ZOS(vuBQMHo$-^*ie8xMe!fsp6Z{?QJwWCcf=3dw4yb4>hRo8XEaX>ePv{P2D~B z^)Jg7jW8pU8BU_sd6!-m1#~Q2i(Huf?4kMr_@8+Bn6QQvPO^g?y@n9;@+OTocdtHq ztWh{>K>KN%HXMu=&8izM`%G4`w6&&XT0%p>fT(U2-ZlQnKr6h42GnJvwBpoGbT`%F z$ko~w5Y1G>>VmB9$;;%E>hAIeTio$v$_V*lVM^H!pU33@un8UzA`2|F3Fqpy6oceN z5Y@!#7K`5LwB-F->|@Y+DfxL2IRW_KLI44zvc{tqo-W+$FL}4dOTsgpK|gfGFaQhL z9POLTTwU3Y`E+7rV^`ClnJ>dX8$A2%GRe$(Cg(N;7y(;s*6~w+)V126-qB6J*|0e@ z=8U6#y-d+zj*7|tn&`_{b}nRimT=he`UOgX%by%A+K;9G`CEP2kIm+WILrACpAn$?JMrkJXTNYSL}y*C*?#KcnlGx8+lPE03681p&2^ z-n*61J{t~7ou&sp*}UJ6SBG7qzsNIyhX}_$j9|_*it9FDsEGlUlzm$@j^2jhId}K%lA(&XHdDI%Oh$KZ>OKGd zv9Wc7noJ~axQ<)P3aFfHo1B)wHgDMF-~LJ+H@2vh%#yQFAFrh z%|r#fe$^b&NOD_TiB&MeQ@U5DA%pA`9uo}@0zv2|%y^unOv$okGPa)k?|TJ*!J+3LEUmg*u+mK8JhLW1cVr>qtHi=s=ILV=m6 zQKeEcbaZ=>2~Dp);o*|W{TOWY3FPg|Hft-QD=HtP6V)oJ{!z*5%jn%A}Eb;1tl`LhT08}XmBB#gu;C^2n}2KN&7 z>}nG6V9tHz+%nFB;h9bdJ(xW$&v+SaOdrXmu%rjP0;%*D=@7iZDRzWmhb{q{mOZsf zIZ2!Sbn;xdk;=P?DM1*J+8k0)+rzV<>Z=^u)EBYlJU;dqxBXk>|hrKPR&^ zD*>+ns6VSeRl`+j7Gf`spf^$GQy7BjaWV0OnEBUk(W^AJ4H}{*nkKLnWcG=rl1sBs z1*{LarL54iuS@Syl4-TEp*|_u<0}bo6n9=~ak|yx9a@un=#NnHG*Ry)%c@m~HrGto z)jV;;d+Q3tgT5j5{#X5rD)dFaVBOCi+Hb&rY_=VO2iRggqGR5`Hk3+kmhzjh+qVMv zkG0yIj%7sd+~6P{-NX!gwA{O2j+xj74H$=UdNZt4>sI%mwr*%J4@!!_cd+C23*kOy74=((yyfCmMeo2q@_KpN+1gjQlFoafBr?hx_pPxZM25; z?#;RQz}HGhrHo4n^HuFS(NWRuna!0dqn!R>J~`Rgfw9@h_6YNAwPRrOFY4y<{!vY5 z#=SMF+;b&+*xO#7d9$Nz?}o-E+~Ou;Ggv=+s9S*ljM!3WEkB}dTAyMYNTXFY%f_0l=sPJzhay&EmW6qp!^No(wJR4 zUk-koBYgkcAFucm)aL8(w_*dvn>CmwcrvWg>K*R!@@$h| zTRt0A)=HU8BdZJ}&Xuz4Yz;(5Gvk zmohu&l^%O9SOih@36y+>ZepT1407*X)Am6tQ$Eu*dZEoP_7ygI1M~VkdpSB}YI6l9 z34>oPjR~?>=~t)GOYg9UQU;1x6^^{}8inY3eTUWYNk0CrZ|p@sd(8jySc+(D)I2#> zc&9%6#pWuX{L!EYRWOj_H(=D&1!BMK=SlN!I)b?lr$K1DjN@lCKh22_KT|nkow=6E z<#xh-yr=2sV^(uLGW$rPMQ3VHRYnxwh?q>;+_p8BC76!^AJmqCQoV)?q=|e0DJhA0 zV;cHRT&L4Q`w7D4bn>9yZ8t5rz z$*rT?@SoHi9HKSYkaLR^lm|^5KS^l;a)0)~e-Z!UuK@vtqf{?OM7t3SMFs+$dk1b@ z??0@+yVAM9SdBJ)PS?=OlJi4pev69x^JOuLCNbdmY&VXkS)0Q1$qG-Et94sFfT|Ws zQ+z99SJh^5hqEV5@8J;nptZ2J*fx)do+1XF(F(dB)VYA_;V{6L()$A^dAIwPXDt3E z?k6d?pWDOy#?{RUXaZ}S?Zl~iT1Qtb$s^y;<+`22PMg{O;i9xLFL%bPR}0^7$ZcWR z4d^+TA*2~LW{vk9(9|ibv^tt-660aLCe$U)4;q={R|d^VMme^fd#NbzdtvF{KfRCC znVf~TqIave9$qG@PU5n#RhJ7d3}p5%e~~FL8OatOyD~kdOLZZ>O*Q)G@UK-8?xPe3 zWLoQ)jnMD5H@x+A4bT1tA&dhz#&Os5iCs43_HiXB8)|1Z=8U!Q)E>Sda0jf`+&gFN0KK1*YKOCuW#8)_b9Y_M|reR&Y{2YV6I_b zZc?$|8;i&yu0?-)Pl0-uS|-;`oF`mZ#gBGxG#b!xKsGbvZcgsBF3vrV9@kFP_fqpx zYLqWY6**uBuK!ed_%r^MO2T3sWcoUG8qIbMh)X&$XNIid{&`ho?g~@4`fA8L3aWb` zDt<08Bj-RV-L}l_JFt^Q)zg>aNHdH20S*=_X-SE7A@%vOl3ipHE`L+an$#SpjnAl$ z55S7KXR_Bd)OG&mb_~ZTMtep%G?6aZD?UbYKhmSWj=`Nyp4GAa^Y!XDN&mXC-*4Om z2YDEd=hOr0JY9wM)+*dNn9&%ZoUe{KblFzd+D++TW|)*=b?-!)sJ^vcyFunX>Cy~; z`B&?+ZwLrdX~71)duUD$sFw}s(tqWN<38&w2FFkd{`v5n*CGn4IH$DMR<*BA z8<*z5NAVdGjnli@*f*r^da4mMwy6X|zpH5rsm?~7k81V)z#jBIK)oc@jK|n zAqw~4g%0TS9i@+(du+EF!u*3Fl{DYECRsJM{?qNNf+lVu68>lag(3jYa0Rkz%^eO5 z;G32u8iuTmy2_cOyJon&y8;S=H~8MjS&Bt4#GcM$M@TyAD6AiEDrrBtL45SuXdEpn*s`{qQPcfrxAp37v7u^0fsMXZD^WFdzh-=Lkz0Q8A%N*)pZ z`*nMDVJu|S_Ai^%%DSPT*Npn+&66$lA`^z$X}Xk`Df*~*_Ye*M8?!J% z|46r@AuNt;@RqP5)|O!%Tm_k{eKiuwYaKA}w%X>)nCgFEe4a|f^f z+PPiJa+T5WjkGGU19?!>Z13D>K#jgZarQm;U{GF`H%BpDW8OaY*%!8#Xd@0PCJQIk zdYK6-w;rfoJWaMC`1Td~?bDjIG|p@YORbIhK_mTF@h=kF9`LlD&|SAfoqrvzWW3&s z@Y6d?{PzmwN;0gxH$!{J%2G&d|Cv|}(%F<5E2$gQ+T8C?Q-${?roO1G?U88iW2;wlo*4}-vlKkTtqeQzhZ zZVGBvk*A+5EA~-!?N%~YNriLc=Cko-SD=dZtV5l~j91mJ)UJ@`EgKd(mu5X-!6IRK zV%o~1jd|PA`$rAG6~6f&e|!9)|M6Oqh)3tDB!)DYifk z!T^@kaL_nex8ev^phe_3$wXLlhBh>ds*>#*f!V*kgER1~!_iHKJ!$XlBwAKc^&Os| z#Uf{hg+#TSS@?0Q(@w>YZox!kZGp zlCo{`Z0P9=-c`HU-bhPdI%Qit|wV&35~^!*OOn#Oqp>azWshMJ9-|XAon1Pp$@k^)P`3?Az$9!3K(O7h z_GQWxN9OO;T4RxOx}W$XjWGPe6y26`;|P0n#~}nE0|0Ob3pLK{s;l50xgg(C8s->6 z-J)^Xq zqzHgx=nYVndZEktkLn&@>IkSR+#6YST@-wG!YRea)NzCWw3GG?*93v*2Uo8U-Pvip zP_}epU2Ij%%gG%S7E%P;ey9ZeCvi=sZaFt8VeLGPt;+Yd6(`(W5;!sB>fULI2Ec2K z18|P9)%y89!L6cS_8S40;ETQJhcxyhlfpHEvoAGPN6}oR4=z`5E=jE#-zy zF_`)?t7YypSAc-vkmjZBP4)F@`@2TAxJ4?o(-!A-Pg6kSIKm|*fdn2xj~saWav;b2smVdf!VH z!?BL#Z6Y|(^ip&&#>tAd7}@}pWU*yN?gL49WZ#qWC9aYuWlwg_PrYz?#uKw3`fz;9 ztp7iS2pk2$B-N;SoVSuUnFGN9)~nw-DyS}azNx1nQvg?V1u#lEdW`5~`nmI7$CW42 z#$hd-F@km0s&E0{hwmLSbJ|BH`NdA<5x))9ugE3sTgufha7UY^9e++h?LXYHr4;vD%m`J7VCH4uO`e_SZ<|VjLI+37#(*$Rll#cX!aJbd=*lJQk>IG zGOW!QP~0+kX<(*y@7DIC#wrOX8dvc5KnwtSSjNcd)*eB3f@;QL6DA|Lu`=XBbxF^u zYh)tQuLe~Zh^>XfC%$FU@7*0fwM|Z&+W_J zj9tiX4Oal5NhPtjj?O6kmexrOq)LR;kv3pTL7-OMr^+A2zuuKcFBkbuyn}fBB^rJO zwa?XE*@M*;_9U_;Jmk^b+UZ$hY5M(^`Rvv)Y7B_#$FHb@(#YOxypi(mm#b7Wj~3oz zq_Xb0`|WEhFa!;f!esTl{ECTP_?tFAoF33u&|Uoc^)J~Tf=)dwEpkngnKP#e@(*pS z^w>I2?zPdq*QEh}hj4rqKTT{E(MuuU-C(S$s*J`mm!65FVNv9&!Q2`3H!odSRu52E zBwyR{&;Uh4;nT-S>rIPBH|IBRonC!*1Z_ZlQG5AqhljkORWR}PPjjbxF8`9e4&COr z3r(V%y8BQH9DpOXDz`Gr&H0kqlOl}z+uj!0W@A;RD5wJv(E~=84u&RLj%q@|OEy>i zwJ1lS4S-^XxAY>^APa&xsIqfB)f{ub*7stsXK}sReHfnI-)Y7|QA*^wh}bMi%M4(; zM1@a@{%}}<)?l7#^Q+iGDjVvT(q+EN^k-(mCm~788YhF`W>f8rf;TGbbe1oXI~RDO zc0R7wv_Fs@J7|d1Z62$Vle*0`+gPeF#&LCt#+B2xC2D_@gnS7vb2DS*y2&vBfL~a9m3Ti-+$mV~6)qk^9|~v%GojfV6u|P2O#UwP zBLD=}tv)g;Q@wlB$_vSnmq{iCA8jAYq(YUAZUZ~?@9$Q1zJ2N-&^Uv=^Qr`Mtz8m) zB6+X%j!zD$Z*#^<@%9YyndDMGEc+*f=I6o><Zfq)|IOs-KZcepW(@%uy3D-k9^8NC^?=-LyXR)#p!uAW*?e1KLGH$rHl+Xi3Pa zOe;yOOsYw$PRdIxEhJKsl-U&+{obwn)3Csf-VGTSUAy2u?!c!s@4*`r3Evi zDd0F>Di-bi?AK=0~|`cUrm!(*2j@1L9%@#bhdYfx_oh=RFS4%mTW z0U)%VhL@)$`*F_Yo;`i2yVD%GM^;V8#1|6#Zf3juy(07Tu?Wu<%DWdFjM@}FM-V1H z7h(UfAOA${{X4^<1OSHs+VS=R?|R?!9?;F-B#F&j?5=4>^ZKS*HlY_}0npF}>pfMn1I#5Y;~D$9q%SXcH^)+!JHCBM>OXL3 z;N07j@TUY1FX07Mc9x6Z)|5w$FS5OTmc*?sJdy4>O{3Q7;=1fpgX}=%LX5ef$wf^Q zq)F-yjP3?dS#E;oB!?SycXV4Bl^-S{Ex|vkBsif4>Ix=fHJ23EzFj>vDyZCjmCI3~ z9PLTm?#pF;gp2To(p5b@)y-*d{6PO0g~)9&{Jeb?&u7#bLJLp7p{9)xA{_T%kJfO< z3Ch-xKbkvI#R*c;^TZ?j8xFLHN`SOJi(U&&iE8&=XR=j3JJDT26Wv6YGs<}`U005l z`Rb|njQ(0?^z!;0Hx!LKbQ%c;NsfP5TFasV5>iWR)1g&=$jbCx-c~jkxzF#*XRqV_ z*?dp%h{a@rNd25fk${3cOgVnfEdFFL z?g?Nt-#lhk_Rdy!y35IqIdxEB(p2r0!ye7KmvD+VY45rYAu`t)4M1=1h3gAM)@$eX zWQCp5F~NI~<`a|SX>r?+$J8jck! zGi4Gc6Fwnvk5*VXu)DImvOBP6Tc+G5VhK;mCxi&4P2z;6<)anN*KfES&(a4eVA=JwsD>9!2?XQz) z89d;CVG3hMnfKhbH)*0|uYvW5DV;VGW$(rD2NY{4yhgcTDu>KC4}Q0h35r6*s9Lf(N3XQmamY0$_eO>?VjYi-ZhSZX z0|8O2HWZh>*;Bp`RbW!`bcd$VDt7b#L{&nos5CO5l#Mww$>tVwOu@23E)Ik~zWX7o zu~iD@)GT2yK8p`N#n|mvEe_Cl2 ze@l0zR-RK}k|m zGm%8D3Dv85NSgQuddYs3#BbQDBTgVf>6PPOSOx4J+FT)RuHL#ve*OC^6XeAHF7^*tF4?kgDf--(oO^ zC3Uh}b!uf+etK<|R73>j@vqj0JKHOp(SRcWZhX_Y9m56Ifr*8 z)Yl=W)6U+T2sr?l4nhsm-8??}+|v=Bts<6)!ke~DP+RwYR+vpyc9cH<&4|-n@yx&b zJm%Nx3svc82;&9ABxQsUX~~t|y$fFu33;7n>bH#WD}xNbAyMsX4H7^^g3xW2rVQ_@pE=S0LfUFS(~Fphj+kQ@dZg*CbWVf2&)tN;jh$Y3 zR>X)NXE=en_7|k(-vgy5vy*Od@7GW7DEp#KP8>fce3F5j1^{OOF%CIrVs5l8!3*!HmbSqjLWNce=8y?5{X%_LLy z4bOspU;rC%7*jw%5bj))k@{?y`G+*OD%b5QdtJUO%aZwRuKY~yiPYy0tq42gxRg&M zMDV`Fb(PYc1T-2}`ik zAa*17F?mg1?dT5r?sl*4Bzx=r zyH4C{3_>h*+1_rWiM`TYO^NwD(X&FoT*C7BP>zK>9M!!Q^;Qk^@rK@=lZrWXU zgmd`vUPm`0s&8@Ko}zQw9WRYu8{4!wi8FCN(}IuvIA6T-K;j884{4ov_kS5YFFWG( zTB(}uk_#>NZvMAI@yWdA$ox^DgL*Sqnk3nk@332LJ%COaNbR)GKXdPBS?}@6jq8)| z9&Fc<_ThVU->oV3PcDeWd(Yq&%oxCKWU`Cq5djfKU+mtRf0pni1UoVZy8{$I_e{5;*Up9Ne%dc4cOnsz5^2w0wcce|hUI^FCaqmfWc|Ji zA8qcxZd?13GbIo;-xR*n1eqf_VGRSeGuAHRH#at3*gRdg;vf+cUgp88hM+p(>ya9+ zBh#?{ASai+bF>##2JUcwN-qT%r@EwE=iJS6ZLj}qeaewGR)i+ST7Y`hMR>hAA^+{Y zwJvJ2=r`wS?@EKY#z;JuwCZcL1=VN6oS;JiBX2 zC+*{m4m9rp*S{4=5ia@$rwMpousE&n*bd0s7-EO@ZQP2`)1YLf0lfIy6%tKMM)~ zJ;q%cB)BsW1kCv*PtxDc6^Exo@4epMR$A;-+n` zy1xxBZIXTd*#nF1RF)$g%W*}Gf4#ZlZEyPz2Je(*)001MkM7uw-^4bV`B?Eh^9x^5 zdZC9jg-CN(EmadT@?wNFU4m=M4{i+U?O#-PV}IpZ`*U zU^w*YZ#qdXiKlF6oqRd!^^+kNJj?E%9<$+_0`+|h{wCda05+qI;=(Z_SJ=pm$r_ex zR*hc1bpQ_$X4oKZgc1E%(ovNRAlE!k|csZ($@Gb zvfLviI|%ox4+#3KZJ~oCKd%0ww6eaxvDS@C;tH1j+^&kR#n}u;ra4-KTr3lr21p~M z`O?p7g$4W!{#)|tmDA_fQ)8)79&NVD&AX+#8*|9WKb(lYRetB%^Mr5da~n)i5%wO$UYrXc{_i$fR?H9^kP?b7O(f}?}c`CHt_`{hwImNXDl?-kn z3&SMAk%5aB2eq1KtNZLkoiB4{hl$>bcM&2v`8x3w)obHb8%y(T4}#e|mg4d zk<>zH^bH}Lfpq#RXJZcpsAk<^EFZ>Jy5WLG88LfGLce~=n{)wj^ zE$gQ41cGZgC+9OEEjsGNIAhB{Q97sGa8_FR!S||8c&pO!0u2CM(N`nm1SxACd-{v- zv;%rM=e>$Ox?juRgoM^roSs|XQM8l$4N>i%;RzmnXI~V4R!K;uGB%1ENWLI8e(duf z5JGUfO2UDHSA(5>FvYwvups$%8_=VMljgkZ4tifMd6U&VnZyYO0JEuROH%j=e>Dlu z=Z49z&#OaDVeYJ?Gfz8g(I_7;3E<4XqDZh3pyzfLUn6hoZ=CJ7MbY1y1d>B_df#@| zxMlboX4^x^P&_!X*BW{44&;7QQB-=mf8@=xRN;bY=cU!OhM+ydjocS?5fu?75mml|J-O?(5+NNA2PClD_mz4!RFq^w{3U*p z;2&T6!q&ZeYpSLyQAKr1&$(|^*Y9lkFT4-uN}@_n&bS_aPwSvW67v-WN6g zdcXIPVarj0kK#>a#tb8t4{x1I_f=Bs&aWcAGG7U75TjJ>4g(?qej)OLf+F%~b_Mi& z(Qm7{8jNi^emOS7a?uHuR9{ZGLZAL)uPe*~TVfWLe@-l@DNqUt7q@ofNyn zy368FpQ$NNzPKDnz7p8vFc}IX3IuS#xk}ohsak(ZwU$$T3m+)Q&N3rh zx*6p($`V%X%flXhG#3nF-n;12+>2O*q^`3XYcjeAUCpK7V3?7^jG5fK`~USOh0!pz z%X(bD>y^Q&j%iOxjC8Zqa4Z185unyOrXBZQ?>n^kV$qwIqnu>=n`GVzKC;r_^TFi^ zDi8}FoWM35$6c6#0J!RudpRqY5JHm9&CvcjSCQ)K_! zZG|7H6!yIig6nvrShbf3KGYBdyuf{($d)W79H?fJ z5|wfhO{SeUn16ja)H&_ zw6SRWO`ZpzLIY`%K0;ahc0>5Ff+>6sz2zN?{xxH|L!W z*c2Ux5)`2bMdG~h8$M@leq_-xV5{qMc`GaQ3D6TVwc$q!pUBP}I87>_0FVwLq2WB$ zdpdjQK782%d9`+PGu%Mi{R4aThbjrXDZbf~^{S%NdxrJcEpOFI)+lL1n_>#UXh^7G z_A?jyBq>C+n=Oow+UF#B<~DAEq4fHaK}93+0;oz+@q|O$)(stQKM_1p|Qj!n=V3Wx517)0#%Fy$hj>=BoyXev3#7Z-; zF|6|X5m$-%l!1slPis<SJ?nC2J*Ds4#ns8FFNEP+1d0G;n#|fl;}UEj{L2? zk~5JANr~{2*_e0IUi4@Pzr9BsDM+aqq4S+JtilM)0D%poqjKivz&E{mnA5jnIdxSd z(Q!TFYbQAfM(g=sCSoGy6=h66EB_oj@f0Hv_}=rDfM6MR{h`!a#3|L!l_b~fxTytf z#c>eq*Gk=y^K6VWs16|5ttZ|pcp&oO&COA`(V^k>y*&=9)D<6$uVbF|z$z zgQaFpBtlXm`h?i-1`wlKbF}Qf|0Z!((HgpZi{m~0hF}Z?0jTcE>H4Qf-PkBC%=Q2u zK;XX}Xg&cz0(_|*)aWmkHi85*WD-V*@}&imhk_(gM&6_ynxF_SqAPBq6-I!C+4yr9 zoG1WKl&Tj>lIynmX#pp(8o)T6m+Rjgo?s2?5(r8R#eUqhCtX3?(5c{6ZTgiNLlwUs zLh2vHB@oPJruULw%3qdzROnkfR&a)UDqj`YgLMG)uuaz4{Y#8>UhFN7I_`@1`$3zq z6#-~TpkEeqb$?z+Q!X!F93_t8MN2D0Cr7H^2C$nN-M;Xpq`aGMbAFW@$eXB|Hn+p6t8+!Zw70zkcVYLj@JkDKs15+o2b`gjtf$w0X@NZffb7LpyxNQf zpv}fQxT2F{NA=EsX|_FwE4cZE`(F}UV6g1*4g7~^m0=e2uxiP-uQXQcUzuAQP3i~{ zRhQ(ECPIj~W@*cUZEuE(O!^RMlC+>^(E^2ScnGqO@Q9RDk@C{Y#In){*ZS=J;yI9m z*r`~xSdz@yT&^<{pi>4=ko1+r)Sk}QYL9cUl)XMO=%&y8r*ol5Si)_R#QZ4)NB>H9 zzsC=;B(#Nhca3!w;uQ9?fiI~eIdybygk>6}KrB6}O~>`JD)#ptIJ!)|eDC%>7XN!{ zpi8JM%8$yR%4uaOg+~uxJ2-a8fZpC1jOPdrtGd(M%EZp51#Nkt;?%0~?edq9p29ZB zg3*YYzh+LDPSwgNefJ($lb}@)UfKH_%O@-7cvK5ZLmKWkZrit5bOQnq zZj0Kp0UMc7{VlgZxo-cq^Yo^55NL|@!2|_Go;;^oM?PSneEpLjP;!`Qg`>s0tKL|(s z6vZ5mms#WNC#ID&r=U)z^5EgM>8vtyq<@u8gG!TJ<5fZCyI;Y7z426K$H=ZlcaZ(* z+ahFrarI1-b}azQ(g-m!Q1_I(TkrpEtL+y#n!6H(aTQCjs=kBhQK5^osZ&d&)*Vk+ zB?EOgP)b$%_FXh=x(HBCJ<*XgXQ${qt>^5`xR7W;E#u8?n)gLID{-iC!}*nzWpB@} zrt*quh0gbh?%imn(ZoX{u5X$Ud{ZCQ4(h%1!*snMX$;bQkXamGV{q75-H4`yHxQG z05H3>1jW71^Whv_Z((T|e69XUgi&Yg zfrrf2u}K%7cZX)?;lkUOoj~10AJoyW8_(_B*?mFh7q+FWec$haMCbggD93Han|3}eT}{F`^Hh( z14B0C31(oNdfpB}V#(0Wt%PS9*KJXE1<*mUW+f?zyqw;9Gh3Y=;U&FRJ=p83$5{VX z?4ve1#a{|qbfi`CP*F(Zt>%l#FHUv^EfHJj_lM@)yV^rV>&4QT<69g-TLi#M^}8pnA9yLIj zU>LPp_tk!WeX8H>Zf}(c+I>f@>#+)BF%kgqMvuE+e4@}a)<%4mx5-zv4VEBMpZ~P> zX}mQMPe0%g>YMSv#^fiaXc~<>I#uT-g_Xk(v5&I?+C4cC@k)4X3xU5%o;o|O| zI{r&y&P;Lwtt$Xi^~D>TE6A_OK&1T4M?3b*FZ|Bhr_elP$H-RwV{vsp#(1iexzAl9 zDZO<2gX8OmP=THFtE`9AbO69{+vr##O@DLtGtw{$0@F(WJqOdD)}2{BsM7ECuugwz zwJ{LCv?%S}LO=#gU^2Bp|Na4fRr#|M9Y8CM<`#^9^yJ73K1KTVU#?{0hp99)* zC{uU()r8+Yam(P%OhG{0^RU3=<-=6%|6*O=jkc_!31S~%sKhsZ(@vu}E8d;DHAfT( z2(?g$w?lOBibLXx+{jJCK(j?Gd{p;^ui&M%=+2TIrJ72urn1dx~`O)zohjXaK zF4g#bBA%eSYV0D~?+xfnl_bCl|nMTw9A(Wi~Y_KT|dUfiUk?*4HtDBsh z>9$zJm^7d=KzzO_jJs!}PVHdf)BN6lB~AHv7j;BAa$O9T(NeDMXjQE=y3~@=V;NmM zy}URZ)oLaywXC!D+4ixTBKuJ0mN%~uy}=whdac~Y$2lpn+@_cp3E!vSzC<)4zZlN` z@4`{2v+Udq#tWF`j0kT@>hD&LoBBG-G$!cwsBVf*NDu*&`Elie!5U8&2|q>WD&%C; zC)nvIJ*Rc6iGKWgxRO`5sfQuL1Cg z@>LiAY3V{^cI;=}YlHwm=MH;1 z&O1-|X*wF1uiVSBuwI?y;}M>d8-Aj)xUQ0aaJi!0z}oim(hcr7^1T8C0O=Ts2o+9S zv15|P73f1xXnR-YhQsm)ZALy~GR=n7$W}wH>HOZ}7?0K)RNaRgFXG9$*{$f6CjV_2 z-+#wvyrSM{3Jgy^VKsp+Qc(Qhi&a-5OtjKgPc#mLs0_ZS z#S`+1jQS*%OdO{o%mohXUzAxY)guR(oz1APc9i~uF^8pqm?izz{JkIJB_1*xdY)Y4 zaY^<3mQ4{JC9Lk?i2ePlYqb{)6eV0Ous%PkNP!|XIZ2PFdd=KnGO4k0#lnIOn%xt+ z2hb;d*O-5Y*b)SQOWkx;aH~4Wf2}aqbY`RT+*vcVx1CVq&qui;V<_S4yqq~@pvmpq zo^?atm*Rr=DF$goQ}kZ%8wnZg!Sf$FEPn?G8c8Ze)VzquZ$*ZST?7*6W zLyDC?&_%T-uOFxFZ0ge)6BW^!`KArKR=+&PMYZymL;#?m0lk*7@k6i#bJ6E7(y(RR z>#w-mZi#biMQ8iDt@hpO`<6WiC6!mU$Chp#y&=^&W5}#|j%~0>GW4PNiifR3RLFL{ z#xfluZ##0j{*&)o*?iY*D`t4RcbN73p69_12MhMUws7C+;L>pWN)dJSV zrh~1O;J}*V-yPLD!T{$P^+mnzpj#0ocnHw>i|kox-6;qZoARfM&p)BhU+Mnkp|Fo?^aoOW2-iO z=Wj#joU=|%8)lY#mygPKh^;?N6uT|7kq`GB$Q{LX47qe&*C0LMPyi)$!(JDa3F!&m zT*l;Jmd;RAh8Foq$f=+0Tm_7q&v@;4aUe+WLIubx3IWv7zVtfOtLF+BkU z;C2$}$oVP?zKNZm4fT=3*^VFV%TY>gYlnEMPXq;r=(_v$oqEcI-)(k_=uffL5m@ba zHCMrH0gID+)b3HTpMu-=cE`VCzWrvgeU68;XI{*<48;}W@=WG4XDV%XdLDVrXKNE6 zwA3D`^(^qgiowqcE}ReNUjAUK-W5inVLK!RAMCjkNW}Gl4{~di0ob&!S*77BHECi_ z``H8W6;#8RGNMt$R;1oQ89XVowwX4a{)eb!@iIpi$oDKfzWns#yOKDuYQrZiHdDb; zgV>gnO;ezTNP$TR(QKBJD-pLi6Z_A=9E``%-+mRL(pkox^@o?TUAHqj0D%?f;pv8$ ztMh&Hj$PC1=hto`-BdE=jq*YDN=EG6h<&XLycn8`*67)s`erV^S!{d5)?`f2d-vYl zP;@$Tnm=7(LUm7v>yeoRz2p-I*Xmz7?zZC4Uv?_@6nj0ja=w~CUZje|g3Qx3WW%jE9_*68lGFH2JXp1@d z=TVH~xP}j+Rmz?3t7r8`9|$G3CLI7M%&2)B)TBD!xgo$%+LaskWEH==CZwH-ZvgNm67Ec9L`6 zdbfSKP<-p;xCLESOSFtG%lwvvt^)?)QS+e(=Al__;+P!h!>Q6b{SB{1=ZYzp;n~w< z7NrEp85j21aM9qqoE!fstU*sO0c??8i|g&H+rG~W&BlH+S)#6Q)=PfP<`XFrKBPQN zj~CQyPz*)gyDH*8C+w||UuZ%v@2*Q+w_WI72{5&9_Xv5hwB~2G?@Q39QZ)iK3UX@& zOF)4jhp+aUF&HL)c&zq(w& zXmV{osDqDvF23m-^G&lY!F)Kh6FNSNoL=!-_^5F1wVLSotO<9cYp>Bb&bF&n(&O%q z70cmFRq|n4T#t#iy6g|$!^fBf9dTA!>GLF?7@u^XlBndmVw(BFu}^0{F*y2Sqms5_%LB(Iee@%9#T8go;!<&qy(gnIZL<*h|^Sv@e=D&0)`g+j4EH0AljGU|`s3zbkvhbC0?D7y5f zYK7WIORzH-0}qUmUX(tO?w1ZGZkU1|Oqx2SNy&roLmQ7Hhjfgz5&a}TgO-7SPXI8b zjJ-&x-SF7Vpx?4PiCmHUh732i_g^n#(D*)&pKcKO=-v z`ukR#LnKqhnxP}nY9^bG<**&62eYq$E!g%Xy`1BDZC0!HlFP|QOU(NBjQRUEomMe| z7QDGtx1sdB=zhxh?HzdQvyaU&H^*~K?c5kLvG=>N*#yXm_ElVds*#KEFHpM!Ux2=4 zzT{n&LSgzm$QIAwrEFVr?_a)emZd~qNS-8_0>C{wzhBl<-!rKTD?{qM2iX}S_x)2N zaD-Z>vP1r3i6!vIQVaoDqT56q|JYWlL{gx zjpYluqf(FhJ$`ek!o>koI>*0~@PE%!z&pr$zlC&OCa7OraLN68M^HUzhlVu7Y69LqThca&IbS#AIzK9@U5hfxzQ;G{wyRKMW7MVkx$61;`sX_eMh!KWRF-eH z$QghqNb?)H01)RV!*-t!&h) z()c%?r~d#1po{F^8XylSlq~WqD%#uMvUg@(4SU4!$CYMPOR*0W?xG(ttylOhKv@79 z@eJcZW5mgeRbRWqG%IY+o~NN}$#$&Q$mm+0-2Gp4to4r=r`2^%&*9Rn=H0o&t(>*z zLZ+2bE7WFWUP(f5;_@|XXPES-=%C7*YwtB4bbTKuvw>ybPNWjQ-z!lCYNTgSw&&1c zmvT`B@-QahMV*UQ^;GtzvC1|TG-a>iOmJGt%{PcGi#?-{l4%rcto{8I?fW6(w)>m> z+!KHZnE``!RbQUEQ{5TBZR|7cF{mbNe#D|LYH4)iCL`A#vQy0UA#F;_EHl*A9Kvd> zJka(|jPzfvBLH9mkVw;{0I&oBk~_&OiqF$5Msi||HS@NY1s;4!s_&o_8z8`(_s%{& z(H%Ff8?{Bu>khn*4QeV1yho3oX(t(z?O3V!YIKc3^NkiACiqEkQ8v(IKFq&!AyYAX z&B^z9(|Nq73*vyX2EA~fk~vSsG*CI*eQ^(qf7NZ@Hplt2wQXYsnR>xp9^c* zl*Ta%z(((NU7dzcr4@InyB}2N((AI5OGrz1dRr{EN=P>E>(-F2Z*!p6rKFX21H%Z$YVmNaL$EduR1BQCz{E zu8xSkq1E4iSm&RBE0h69Y4x%jumwO5c)_yn-pK)C{mvU79qg^K=3-BjL4p`*tQ0T; z6KNn)m8L<1`ghfpfGJm8lN8b+y2#h5z5oR{g&{U71FFN9eoK;ue;n?`g}c|+&S}b1 zyr|87XQvhOUkPr$;ZU%{Z0O}P@)-bRk@tZ;OitQ6sXRcrds<3y_^q`YL$C=<+B1R4 zRL#2Qw+@=y(bh7C0JQQ!65pJOZY=e$&|7W8xl8zj5Ggn9VXqzNLd$d)To$K`_rB5D zKn?uaqx1!&L#QP77dKTOTO#}GmfkuLoU;n^i}yY~G_&WWoh1*e9#kKzUsJ!Pc6asO z#yYp@y-_@gdQl*QY9&WtpC*Su}^&+is4XeBcbMevflbiC=( zNcB{OrJjj_O<8HfkIS6M;FX?E>(XHw`ze-b$x?;<_DXt`9DYyApu_9M>l`tVAX7w=O*k9u6?``oh06VlQH}i_bLUEnMC#C&cFL5d% zqUPY!1I$K#L94R|ANxBc-S(TbNOl?yKwBnjQF7d#fzH%4xKUT!D?`Q)4WCgT7lP4BgcqZYY|FGhlb%1{jQ54)6TFOiqV%Z%!C_^xU2JaMVQ>fsedkMFs~dk5Q(&F3C5V{)z|a z--%6_EinI z#;Gt`Jx{<|c|`NJPwJ?l${fGc4$`kj%x;lxdzP`JyXCZIn%ShQ0-j$eZ^Cc^$MT*n zUr6iPzpRttkpODNBuU(p3(SGTJ4>IYMVphHuhP7a(Im7)^+9-u>^${;+O`Pn3ZQLs z$mI>xmO1?pvX4~!TfdrxQnRA$>Xc-!ZiAYGkCK{qe1-v{eR+}R&(q8X8}tF8K&LS| z3Euk>JzghQ5BNjm!<&$Sp3EZ;n|1ukR9_oW#LsTjXV4Gp!D4OcDxA@(8=on;S$rcu zqKey|L^sIBfCmZiK8`+~93B!|d{%>DNqeD=g~MaphBai9u6qe|~S% z63q-n=hdE4wG1O=`ONws!Z^Vh%_pbR&#do~w65}5z?pzO{MUPX^`blCsc!Yz(p?@Z z=O?{=@vt?hCT5Lp#W#9z5dgzX7J0q;g=T8*WK(NR>YL@5*fB*B=p+CDpUjV^4 z7H1%dCq&4JINZ-D`MompTqo}qku;S*Iy=a6%~z@HzyP!67ZJD9ZisJlPE2ZDwY%uV zeSP2=)~SRZIH}8#I$=LMQ*&4K55ah1VM>q$eH*zwPUw2gMW5ozK95B z#c*j7A)PanION5OM*`wE^$^?SER z8|_w>B`ye?1w|nGc+jmdg&*K>ycO59Uf*iIKgs^3N;&EnDWgLk9PepM2VS{G-142= zU8Ctx{>g{hKT;EQfR*Bdk!fE4Ua?(*@rogvByoY8d=51y@i!i}1@>V#62DrK0D$7F zF@g)6LtFYo<{7>(PQ*WjCjU`@tPEaYu4`n3FnPJl*QtGVNoGw;^qB1Qiay%Q-k#qy zRBhs%Oy8qVEJY?tPE%VeIvowQQy5Zsb8wR158O+yfSmA5s%F-=c?JEGh(w~0os~eR zwKG;NDpAq2^IWa{T065`SIEOud_JYoFc{*z@`>?1=QC38A6O9kM6wt0-%#&AkFin> zer>JjRNx(@;t!L&KN0jO@Tl`58(T=H7;X}aCVQL{_Y;bHxHoVk&HMUPzRX)F6$><^ z{C0h%)@JRONtme(uFCCSKNfy@8vN>#OkQpNxcmO4DTZwt?W|YclF6=;2HWr}sU0@V zHcziBN@&Asvuh%q#34VlvkEZ}UU>S~3H@y_MnQ?rv1`FaJx#5HlND)hy`~td<`yMO zACio&yoDI@$x;%!s!QEGNo&PtSw|+8^+rs~VtW2W)QY!1w~m}z`-FJ?;SK?XTP>z@ z9sn>6z~GdeFpZuCyD#7DGQ*}QBvC3|`TB7e)9Ivw7xKzaiw^UJ^so*Y7Efb zK#P@P{MzYk+*W#|u9;@Y-eMK#D#Q;kZ#d$Y?5bwK^zT)(8|UyE^C(cDtf=W2fv~^S zSrm@{tA!RQ#3qEvSXaPfbiFIpUkUxg|qrRK>PJ+;v)pTL|bCKHI zw*$3hJ&?hUGmr6JHl-kd}nE|1aYe>W~B( zAuUTeyS0_Ei;BK-NzTI;872H{R}*zFoIAUKHoa zU5luwEkFBJ87%#TK=QXhDmP8bJuto?%24bf35qr zt@l!jaFf~5tz^iEA&>_ww~akJxF_(|<=E!~YC6gJ-aEWj;6eT$gPRvNX016^x`T zx=q`yr5Lt`7ubqzyoJ=C-m;|WJIU)Yc*~j|)|+3p-R#wHgcF@`r?>4m5L|295WHmA zal61fh06?SK#@$Ur#M<7{4GJNSeh8=^6r(`3lDU`_5VoVj_(1%FF1lNw4ID8whxas z`}3X@EQuZBpaLJh@N_C{px4 zkacl~#_Rb--j-GX5a23|Ad-)Q(($9$pOk$UrJwv~qRsqO5Xz4=#`x{z>IeKs(zlrp z;!Jfw$6>3D43rS+8u zPMZ8Kl|gOu0U*SlZ~X^KGAX}=NGmA6G-zq5zm#MO zw=l~!B;tZro2RXnFi&xruy1g4^=(8&rqa>blhXFDo`)rXh_TC zLy94xIXZ@B$RzT-++~M7krx6$xMcpHUJYWI<6`v`l44a%R~tcpK77@Ne?!FnzZLHm z3fG{UH|6YuhQ5o<4(zDoLRU-0IicYGa@olH{C~gY;D>`=Z#=Qjsy18}1?8r?CvRiL zm6@=@70k*|64(yaI-Ej{9?8l?`-&-0gJyrkkJ3UH@6JU582S z(v6~y^i0$9%utDG?P;05$^n3~T3gRYQTEElULk%jvfd4Y37!7u@z8+2JPnd28lMf8 za+gYbWc+)#4}K&l0EdLz?(U*&w@M3YBS^78fhyC<6!3mFXFmf6?FOuF)kF1tfLL+2 zo00T~I{pw$0>2{N&&JD#ILBMKE;mLBkenBpAY-*`P;YmRzAVSuogetQ^d6s85^7bI zy%dW=eHk$`_n$p%P>h)C5r8E!`Y<&*#}{|Cl%9O{tE{>fu`Ba@hd{S%= zpdbCAvz^pX=Gh7NYr?4y`w3Iy0&@sx-kp`?WnUF|DN1?w$Nna$U78+WMQrgPBP}hy^oNXggm+%W@1ffLAWD9C zotMMqa|MD5aYEd|f<^5!=MWpD6J~vYqeSX zw~C4@Jc!b#>iDGCIx+jZD%tF-)@qpIJK}mq8oPjbCza?hcK4Q5QhOoOp-O5RbmN1- zfKITjXY4pX@zJR#r?1RgJs@+NFy28p2KN=ydoWa{E-2j4lp+?=+qBs|Y4Q<^ZrJ@l zZpY2QF>FAi1O#L`I)g?4kgpvI{a-=*2*DeO0jBE6u`-_wvO}j+bWjvb(OuLzjm~n_ zVF#+{jcg}Fv&QYFE)Q4|^6<&B$F~_F&c?GpnW^oQQ*g3UD>qAvp1qdJ-OLDTKGw6$ zPrq;qMrb>@v151e4)!|pXm?=~8S&fm+7Ob0#`zH>0s#8L1YNNngBfgB)f4hH3iAyv z?tMFPG}T4N()Ez=R{4&VS!MsDHiavwKn8dqMm46&T2K}<_R0WUh5{{z>4Ok>pySVG z@o&X(i~v!PdAIzg5p}6RzX;+#Ng4GnxlkV1BHdSl?&Ce$o_pF@5nV50lBYy@ zXxw7qO#owlTN|^0-)7L~c#b-{(9o)*@n8+}8igLMnQs_D58@JCclOm9(|fc?HU7q~ zXJa{E_VM{IAr1$ShgI-`mrN_e0)|w@>lb;;0*R>!>0T()NF?si)tGVQUdG!K&1tax z+3fyJAXtn7R+YKcL|XUvE?V`RV)>IiP1&A*kTV{u@twFV#^Rd57ml86<@$vBwpaAB zGS^^k+0v(NrnT;12t=mVDfF5Az>?RJ44-u0!Hu_C>$FlzbtAJ#5_y(oQUJ(>OfOnI z#*myKh2lfJacArwvp@f--=vgwR8;hCn^*ko)#!P8>(L!MlsR)tUlK_}@v{Y;RR34z zou?oG3(EJqk%`SKvhT(D*ZNl9PFNdtRZ>C(L`bAWzHvIBGa(3+sAZae?vr}(D}`*BpsY__VteO@V3E$hl#j}8T?oM*Si zhi%E2V@K9L1n(;1yGJ|HW(!s-#;%&=w;)W#ipt})KY`MS z%HD8dvaIgdVKzL*llps2rAYZ7TC~N&21lvwwriFfOjmYA8Ry)FJv$yrV&YZy{IY6* zv7=B$*@&$GfFPr~AnX})k8b*}trsIq*t4y>sqZa0Z8@8EQ3*}5NSD}Isqz;k_>Jk~ zqS*RE-QCEol8@ay|Ewg?YuvP21!TJ}KcJwJFp$sCt2^c=5XhsKh0Kjq4H5e_`}HQj zC4;pWC4XVpM}<#b!4`6mHoWzD<nsl_TI4tPZ&TjY_Wo|eOjacUb8PK2~>pfu_J;; zA`zy=Og!&&cvV@hxP~9ny!Mbip@9)+RA_YZUwgo@B{+yOfEsC`<~>@!k7GWF9%Okc|<#c zjadJ)oAQ@&mUeS;ZHTnCJnY)4XSSe$x~eBQLO6s-rDCyIEEc`EIm+gaN}v+KTMWbR z39$|!l(t4GVG1{_VywPw^W{sMH>&_UuuU`Pa!vSQH^^@9#7kJ!x%ZbX-}|Y1=7rZc z4lPtxV1d4}O>Nkl={n5utXH$^1KJtCi_f$ep=xE%)~vqy1+iNRf>FAUR!Bl5HH8p?DX^rr2cSYd@Qrg=e-!J+@SGowBT3YZhEpP%H#RgBvrcXveXtL*~-(m(y>w&j&~ zvL~)&rRwpY)MquO2_h?pUmw|!8hXCsWp#0zagUX}-LrP{f`w-y`W{o$rFvq*&u-3N z#3tI>UJEupT#{j9Cu>fxP&_xJ>ISJ6*GtNCp7q@{Xv_4q^V)(Ij09BS<4^PfMrdc@ z30`pa-UAMUsHJ0y!qe^K0f1GwE%|mgb03ZMt7^(OZ8-mjh{u0W5-jMooprh{vEmM! z>*G}IHGp1e@Y+$Nt(I=yx_DvzyOW!5(a%IxwoO*U7q%>);x3ZP9vm%v=&KW5i<&Ni zl6x;78{B5~8P|)~s@8uYIH>*Ez5ShdhFHwUC51u5&P<4DzPhWwcYBqtBT1cG8~})= zy&cr$H4^RQa^@PE`kqZn7%`ff*Yp~7#-}98nwKL6RXy(&cP#z6$(VWV_SeK;*f}z% zm}h`+l%pTI;NP5ZowBwI88z8cC?kkGcEqC2q5N4n0AeR%NxOcc zq?E=o=a_BXxH$1%Ba7JPs|!OcJkl3S>ZB^A@%Aq3&1v1_*s05%_RHZ*X|Dnl#lAH@ z4^~Q-@{b79NMqcYOAyjfa>D0yo8+8REE%{Vqn^=ml6ZpfNRc@-4Kq#b9JG`4mpOk@uKisuJ`7h_JW*`ar2p~Opf2VdGWSmv_Jy|YB<&- z0i{2?k>7|Fm<(ocj8Nd)pq_-(qZ_swg&8(F%hXrjSJxg! zwso*_%_EvhE48FTPVhma3+yq1aCb2Cgma$T|H3u6~W_?j1rK|5b z&zxZ;s^OMV^fzjw5$<0L+2LNRY-R_{XkyM^zj_J1d~6S`lT&xT9iK2Jf2@V$Tdg~E zI*wsHuKZ`zs699aI)m8s=xWiUzBuU6>{$g{n^Fdgw-8OjM;+ec(Pv672e*;IndbZp z;~IeHk_X8H)pd*yQ6BKBHp*{KGYxAeysf}A>FcKdkxKfJk}whnx>Lr^J-qZ0yi~%I zuPP|dA`(|)%@O(0i|dyF05s@gJG!t_<{jy`cj~Wt^~;~#&)Bur-K#z9-0gsMtaEX(a=D7pQv#)7UA_pHC5Nr zu1a=e0S^C1+#S1#Zu!5;HF0IXmBwa?+haV&x2T*-U2vfN=sO0;2Wp9(FJr2=YjXw& z%9SHA(<6_gn{Pqbf;PVTB>(rG_~>(eOmD)Ns$%V`dd;eVx;AIC@@lCu!U7jJ5>F%$HmCUJSEDmr(G6bT+@ddm;5i-v=!nUGiOzu!{-5$q zCBri-`W0S$F|(M~Q?WuZzKx`xy1V;1|K5$I7HV6pEu9)EwTMh{#9DEyAKH1}j)QoM zWYj_vX6Oi8D5EWIAQ#ucU=j@?BZU-1L@)Q0^u_!ZMkUBb0?t96Ml_^yQh*qBkapzD z~ip42~<#nHNwO zQMhG~d!nnSMHBC^KR08nCa<-D6JyR=rXo|RN?K5pPyD2HlB(HUZCGLm^$) z!j(U9weScM+@d71YOR%Qq(lh{kRdYp`msdhr&ZobS>}P}pl)8eL`s3iNq?ePtC&Gg zj1UCD@<|{BP=N+X}nY^YhBRjLG`r_E|!dGFnO07msDom+)DRy?4WHIn{&Fb29dQ=-F zG6JCF=d8Y*{1aEHf@l544hCBc%PxlAyGHm%8sH+P1kM3sO7 z9SqPps1OLdO5ANG(ZT|LxzUQLgj$jfJL9us}SsQh_|h| z+;N^&w}Us92AAXwY~C(0W!${YuTz#(YBkeHt!(4Sfkc_bJ-?&2kR_GqdyaRor47_| z8D>Oxl;n3(UA&`DbCPWypOSC~cN!_Hd~dHxW@qKAtp<(oSVb%4J7aazz&EdUK*x&(yCTW2DF!EzO&LPq$)uwH1+}xZ-ZoZ774xZ=dQ7 zkb^b4VFx3hRzh;o3<`88K@JU22Z03fIH8p9=(wh}YD4ISBlVhRU;Ewl%^fqQz+s*=Vf&!nw*QxbQmL-fLhCba@D=PX;<^n)_tG7Ong>YAtwTW z7%ae199FYzJJMX8!Lshu*@G{W!>bQ^t?KQZF&P}^*NkE_`&r8vx6XgeCya9M41gJpM%Wk<5TU1bI`t5i$u4Xs#=YKwVY06V)y37<(*;+I=1gI$z3{5 zoKttp?%)Hb4((fc8F*D@PZ`GWJU!h!z2>pY=unlLZ>$RI+Wum+ zz2$G+dJ@cEhH@HF%d{yRs@-`2qc@|RcPz-Z$v9rpy3x*kaHUA2S-rKso;;$0>yt-T z)fl9VRIApe_(X%U*S?)p@uI6?RP@sF#vxjsV1g)FbRu23{Iqd9J2iGmwJDt@Ehw?t zID;#7w{EYP$u-If2!7z68e=(fB1>M~Qocj6qM}|80bNKzkjIk5^z1-)%)KE95I?Ci ze{Sy|ZdBH7>Zqx6*bQpQG511*nXbzRflKMRIg1$b<(E$cS)Limate&P_Eg)sx99pH z5{f|JML5$!QbWV?+DXO>#3WoMRX*3Y%}50UYZXTZT}pv~&kR|O?Jf%4Byr@{ArKsM}_hcUHXWL zjNV8l+qJe#%k*;mBmf_Tu8Ux~E{Pu~x6L?b0W<}py6X;nvh{6j#i0F5saelBGTWRg zMOz)3f40a1fFk8-a&lXv1)Zr>mv>+5i9z8i>_Q!y0T|*qcHudCvC@qjx{~6X@u$l7 zU^x0>o6H51oonRnb9Y~Tv_+ESR^_GUs4UXq2G*pBmD}{A$x(9o^t>kJa?N;wT)ae| z@95mgS^zPr&En9QT7`;lg~~F{Y0aS_dDerCbfL(Qt(HlnB%p#CFFfIw?&MiCu7W!T z000V*u2#?q?fWwBy;b&|QWqxej4^6~>=CVvx`N)2_AJPN%b==cpA8jvkTN3@9nz8# zPnDb3M`J76({8GoTJ-2!YaYU`J2oY9lX9c^=HXmxEjo0HqlI@KmNdA}bMY>-s58vC zo^zogA3Hn$;>@s?A}qzBK|dCaOyN)(_=iD?m3 zG3ANHO?|i&xyR16>p0lTxWxOHz~}Yq(w}qeBwtpZrO^bb^iZJu*`-s)x{mHSF0S|q z9Ovt-<-esp?)z|8D~nkgkG-!BmH;2jwr>na{}nMmte2v@ zu(a#*l;iiZ`b(Z*yWn_6mrXs_TC7`UG=;A;uC;kgSe{6m-B!&ea?F!dVo5J$52jS@ zYK%sz(kH?m;`-X$G}Q)$uyJpjMLlW^W34ht!B_s$c7Ajw}|?A2$`d zab67R)Xw|%N4_{guyafcjhi#K8)v>`spxD&#?$ejEmjd7-8%~kk9swQp7Z#8oxb2h zh-29H54CX5vv04%RB}Z#7cy|K*phM%h?JAo!<45HmYPds!Ni2yY)y=$Azw~K# z$^fth1Si{O1d>n^LZV4z?$fF*yxHT;Kqr9V&55xO>Whew5K=36Q+if7H*BQ78I;_O zo|!%|s+o7JVC(TNVbT;i9X8fmRL z1IIC#Zlk7ZvTgXn9?&#a0xlxJlzW=gk}MLJ7atqL4JH93Ob}IaymHK1`NseV23yAa z#~mGR===|j+?UZB<1M%ku6Md_o^YFN0)UgsqUX!DjZhidc7kWMci~~Y_XK-C+se`} z+7(nuV(4$!K{ON(hND*!q<#u(9Xh7Kd$44c3H0uLzA6bwu69n-X=004jhNkl!L{djj{VZ- zHQX>-SU-cXPCVBq9aaw3X;yqqGz4v_(x7-y|*hD@J2%OZ{TBbT>j zUg+k(idIc)GdZN&^`OTutm|!RgKDGmi@-!5oWerW5$k1#Nr7g?7_;;f#Iy6Ds*PM~BEf6Yz4hgT>H*8SbwyR3p zizVuebd_PI_tQTp(3{=7zry$6;KN;F9eXju2G_iq;skiQ=K0l)icrqIEjjw@lgp5d z9Fu^~PusthTaN?)z^U;~InwIVyQ{jqRsIF@|IwyyW{Q`Q`1(r{|IAsOYvo~n^WNHw zX1$x!vXz^c#s!R9o^bTRd`}gCU6!S0$XE_e0;{&S36^u_El0KqnQsL+aAIeYbFO^?xyP!UtK7Ua} zqRG308D_o?>ErGkRy}UKabt1Zpp?;v*JPh*JUC<6_cn{r1`1#XKJ;k(mKL>E9-2Wx zu@CQ{9uyRJEOql~TlQW*8(>!tW#*{<|C}6)JNVIP%e#s1?lfzDwe<9=?!bK#-Ah({ z;bh5l-SAtp?_AFx-En5;Y@5k%7(k>}zi7oq4D`r%1Kuz1pADj%c{PoR)hsGq9JtBxCv#p9I#tn~j zTc+($LdtMWtDo-Q+N)Kca<`b#jRuV7TFj1!p2pf0re8`M(d+It{@D{1(faGpF{s4? z0IuwN)qrMF9DlIN%+&Uo-m@3ioc; zd|eu(9G1h=bR#b&)a(Ul?g59*%o0Uou?tXvj;|; zr-tJmOS`-9my!+iC$;@Bvf16{vj=HqT;l9HtzV$#TfZg>y|J~fUUj1PG|$Ul+@Zh_ zl$lJK&wm4Ud@kVP{ie*|<+2tHyj#M@7{u^R0>mC44NpGXaN9Zeab=SF?+`~Ud7II4 z^yO@ZsjI=lQZ(HzTOhTc>QTw_HcTqsRce(mDk8*h@KVuQBT|#QvyCQLgVv) zOg}-2XD_J%Z(u#Yg`)$Py{?^0x1tquX<)OS1o*9O?J13Q^yB*Jhsih<4wh&9Uv}u@ z?9we)D0_gKPPKgtub6U;PgF{9kNjNWzj~p&qJ5COIE|kL~SHyLqNKR z%ch$5HGOSw^&Hh zYXT@xD{vqC#%$Mesn4DR`2GNTAdF!dzyt*L@Icw$G`joP4ri3(YrKO`k<2f&4;$0y zYG6bSBd-f{Usn)ZWFyjyN|uiIST;1TDPC})rOvigdH?-4wFLuR?jM`CSJk*nRaGWa&uk1e_ z7&9)^QA5!LBdxHuu=dS8Q_5YN>RxzAyM3n&cjB5srw|}JrCa*Nlf+}*v_7AfNY~$5 zd-Gh=cN^I&{bx@al*iq(er^-MBOH#qm@-xDWE{oF?yt|zIe+|)<$@`pT(N`|P!LK0 zJpkF?GS^ZZz!6-;LGD*hjD!?GT_k*cnDd)n-Khv5T1>6nK4TA*a_DtRrAR!JYr|IY zRzU^5!HIoYG2@$_E#s?4I31dE!sY7{uv`F8T9ie48rk+Y>!+oS&8}i7iyA+{G~-6o zB0?=z4%xgmK{pXV4u`cQzf4B6Z0LitzE#y=00?!J*T~H|+zir+S!`(M13!RJWD-i- z@#S+6NLwrSp`B_CIRy{saS30;SjKNaa9nqPFK(l$@0rd&X(Q* zGyKCKfK6?gUd96-LgH^&TZsbj00nj+ur~3QLS1Jl$7~Gz8y@PPLB~9N5&)%lH4S+t zd0UeD#Ri6&57fr@s1Lp-YTUG~$>OmEkJp_g*s83RM#ri&^X%ivQ98@W+RAQlRAfxx zoKKR~ckEon(x%E*fKWA{JtC3MFgxx_10EiHz zdbw}L-3QsUQWJeU>}B^Ln>wlQ*A{QoMN#W|Vco@SzA!FepS5dLLtW-WsJXynyka`g z*X81-?~<7N&5DfGbA=P<9zHDrQ7+@cHYekjD%4&zK@j!9;$T&)W2fKme1ceVHZv?zPUpB zeZ|6~{?7ge&d%7|F%EPfgh}_NJOTBpXY(U^yqDDLxo+vM#A>7MK5Y@rrp+7d;c=Ba8ulH4<_csnZImb@#u6wd6_Pv)37T{|h-#s!X zb$YuH&aj3tguwriHq1|DC&GzTF4{l-yXmn@~ePhq5XtD4MCr}x5TIwPh$)VWyiS!lVs$;yM@^LhsbZ5?t=bG_zo#J z02g?|8{aL@w0pCymj!VlH$x`Ho<5*qFN$Zl+iGDL?*D|e(**#4KI${6{YTi^{&Xvi z{EYVdi)LTE!$jy%RO6>GHZ`7UI^gs@vr0k;SgJOs(MD!YZHk?^X!D#lhs|p;Pj>(E z)!4mXYxl-DJIxhL4Jxp_IQF7cr+SHw)jB=cFzi&C&|>yASH5lBQVV|RIeAsvtuZBM zAb}cL$ofYoyZkZU1#l7%Rl=JT9|_N&UOn6Yt~(oI5oLosBFiGwGX_DxWFC~A@u52 zx<;%ggaI+-NX9a*0BJIK8Qx;TTF+FZcP2w9_1|6ZHxR=i00o6wap}ruJ7k;Q^O?al z(#jui^t)H(n%Fle%zqTP9g~-kfmU@qedn?CdGhBK5qA>7k0Mk7A@e66e8B&-z9`o@ zh9i9Ghl$i6Fw=-~y>AhJAU_LE6ePlv5f#m4=i9O%bW0Pw#i@E_3nRU*1Wr z@F})bw14*SxIR`@&aDsD*kwIv+W(&QOs)~Y;}0INwNZ8I`&)aQ6yBBm46iYB1onU; z>DI=PX$5$myWTS!ae;Vx#=rH!%{AYzyTV%y)6i;LIk8pPr2behV;8uL8FmC!%sYL5 z*x5(zwcuW(=lTCL+1!5;1OPZJzcrn$zdzchae3`1eEu|SP2~xPiLPVW>2w02LXm?B zZEL&x@JG)!4bIxm9?V>dE#%Pae`!xB)-!8K9ju|_a?N-`N8=yqS@xZH^C$#?u*e4} zX{HMDJ6T2V!(XAKRbqaVpM{I@5=0{&65mBL*mh$`EFrAy*lt*4$qS==4oi~^%{JoT zQS(z2Er5x$5pPZD8({++Ei}5H9&xqaHxoH?t{lA!-6@ zsvl)vK78|dj?bF~^gU6g=ETznbSP+xw%cAt2Pn?c?bW3g5{KdyWq)ow^t_ zwRaN+#d!>0K7vz-N=sM*00H`#Q-7^cUu#tO!&%D*;j%aAM|aHL`zY%Ch5!Gmq&X2T z!!X^So;p8v9@Vp(zpdYn;Z!2q_dt=_g8+aI$@(ze*NEn9i_wm`fBsa(0yg(A??($c z&{yK9wdOm5PZ(m*=vXDEf@nYtW|q#&M|<44n`d+Y_Hg^fW!k$n7qx(tj#e&UCz*bp zGpWUkVPQ|lR*uVA<{R43sJ;AH*iUY~n9Bv^TtRcirY+|qBha(SbcRoN;zft>m0}yk z9Qu{<;?$tlpSS%==hu~BDVCx~=DI~f0jM4>!oEXV+yxkJZ8O+7vhAxM?$6eId%tx} z)O&Vg`{#ZC6`o@;xtXweYE;2{Si0MFxhzKDE)D@eLG-$&298!-lm6)3!CuL)$tb;m zQ0Ur~4!S{wx6%Imdh}v2*@o=~jzAsu!x`TA`K_D>8zto@iv4b_IEdru20wKsGve2!`8=(XlUCzac5`F8g* zs$MAeBF}7Gjp2&V)~(IJV7#ffm+9$e_viI(3J_+>HH39x+XI#@tx>B@4Uu|%>_hG< zu!eeeoqj6`NSl#nA`-dVmWkOi&!%wahfp0H@a^@Ujf?Ol{#6a{=QDc>TO{MiC^Q&| zp1XBm@WkY>?^E-r$|aZ$W&4f;JYLYuda;G&^CWZS({7oKHGO+)PhNj_zu%(XQDFv3 zK+x7U{#;YjOX|r_+nU!pKMiS28>s|d%K!MGt6=N%>&^>J4t!Wz`y4EM0W%Zyk+$0K^H8!{RwF|py)))|Pq znFqL=b;Ev_PVE_Q;whX00Hn#tqi2f!9;VBh_aAvEuOC|XJRjGqcvJ6xch;mk-XxQh z_eeM_N(2Xfh&DWwclfk-;H5rhuNYogQn3-YTTE&ioGndj{=b`TrHr(N`-Ew=#8&yN zop0P&_qN&Bqkq_Xb!$~eM(^8ZvTnnMS^J^8qAv2niNfdClN*Q@#M;xgxj!zoW zzu!9J=3C08{uOo};2Mle2l%waR4K$tNa5a%*Jh~=1EpZWF~}~b1PqnZw%VTAss|Z= zs>9s@0Ovc&h7VzSizwCb++%7s=~EtR=N)%<$ovuOw02q_FmQwjY6$TGJ^;|YRBSjB z-c}8Rh1Rh^*=v31z{=;`slOdDj8z+x4LR^S9_#i#{pjnrmN_qbx1atAqXSs7(t(Mt zQ=4Ap^OT7%=UlRa;!G$MN&ra_=QYJEt9W_$n=i&+gFtZ<8txo0!sQgtu z(27X7008boiX0>YRKn}c<#B2Z830(FZFU>e*U#$?EMz9}Bp%!`d`ml;^!dBTNf7|$ z+lXZe0MwIwhA2jFeuUa+5BIU>3=dcTS09vNf6D_KhKAnC^IH$kC!3t79|SK3V-KO93jW z5bZcpy4Zur(yvWWT>0N__J>e&%=#xMo?91G_UuS2?^48ITg!H7#$(o++NM}Nx%gz> zPb@P9ov)CHaIBR9GUh_W2;mSGmDM5^t1%uFrlP1B)lupuekh7Sx#1M7ocD#OV_i+S zfGKuD&r=rM%J~%CO47bCaqwFmAbQb{F3%PTSHaCCS3*obr+t&wu}Qn z04G?%0sGpxy+1ry53*Cw4VvB7JIVz}Ho<^}+n zUZ-G06C^_JR4c~5)rKka<(O|u6K8$!!>VnG$I+xrP1Bx78Rf&20Dv<9#vs;+pYuTf zS6snPbw-JZW5fl3YYyHkS$DfkhC3<5jsbcvQoVhGe3!=WcH9)0jCSNQ^k~Kn^L3Q)Om~D9nNMiw* zatKMRFYg1@=87$&KW=U^u2bVfQDxJh%UnGGD43ewjQ917*I)FA{v%dWy*}OMp2IN! z@pZ!L@JTjWj|{2(7v{j?bHknbg;rM7sRspp4`BBlquNrhg#VA!b{{yD#}e{K6KO2( zL5M|5WTF2*b_%kDL=A&nZ z{%h_ay{k=YEdpwIcT2PuMwURWT%gW3oc;eOD#3&tvL0{G{e$SxKrAt`8(>oR){__A z*WU++HObNEzwF)lXEpbcAU?(v0C=>GxyZlIT?bu7nVQK_p1sqpEarZ%V_ObelsLnR zq>)-Hu}2V9gMwl>!Ynw%yDMz`FAVD&$0{bqT`&P&$H7EROQG4DbsFxpIAD77{d+#~ zgL$r3q+!jtgPnW52*a{g)K zw=qn$_2!gUT-^WvaeTFUQaZM{*os}<}z`u2++ z&7VNKVRY#nrz5dePvvOVes}-AAug2bI-dDl_13jL=o+2eIUr`h`BjU|Hpa}I&j;dDQ@*vj?$67&KkabKA(21 zGFg3y&y#h^wh3gMgV=;wXuMjP`U!NFgn$*?YwHO>jH z{6Ad(_veV?$V5Cvzu)mBWQ!&*HttI}hCf;A>cxRkb2bUanoN?7ab4f66lr-HeFp~z zL*@5!mpxwlxV?nv8NR&g`!D9tnBRR~)sGxC7{Ck?0DubO&aBY?JE$*reo!A-?+IA2 zPWd_auc|9@%y|`@mJoNrKshvL_{|!Xo?~pnnS?tJh2(0`W#-)%-RZvs3#@zx^KLl( zPF(X+3w504mZ4UP=e|MqKO&wEl8O;3GUj2AW}lUWh=@KavhZt1)S;wGx_a zM-C>n^`KJ*NIsC;hqHBl-#QL%DttUWZb#yjC$_#dPAH$FF1{y`%ocI}>ERZC3gJR$ zhkLbdzgfQiU3f=p6s4D({Pp;!5B6VL^#drWsAF2dev8GhN#EW3*bwMJliV3D!xz3g z7z_5!HHoS<&0x;pC;ooIY8j1drzJ!I@JXs9$tJ=2zIDE35E5|<6gO}YM_=?ve}+BC z)>`Uk3Y6H4fn*qe4F9D5k>px~rQHZCp7dhU%pNkv|8c3^b;qTcsQ%#Ik|_j)HD1SBd=)*NZ^RV{f+CJP zmFqo&`TkZSdlq29008H7zAD|RlYVX)!G&R zn7MaL`kSr1NUO(C#pwMjSfQ1*q|c?S$eafI)x2eCnl{V+SxI#{iyVqM-xwwplg5;Q zN5wC?&;L740#roe$ZtDkr9KTF6<0E3lZhSCk-~rYqU>MrMsJq7DB>cjpkrVRO`h(U zv9_{@y*s0mKiEI%?d9)=-!Zl1rH6W_suHaHD0F$Ed%qQ}^Y9p!eaB9GkyfUk8;Xcy^Bhi1++HZr->>xOY% z;p2u;5pOhk>IcVe6RHtdlU%%b)CI|l?(_c+HCG!eklJZ-thHJh<~2xDSr<# zx%p9?7JfDWEJQmJ0Z@F2j&QI7R&A(tnm_vN1DEXBf0)`H$9J9oBKQy+f2F*7fErjm zfB`V2=Kh~fnK`acZ=R4VFn)91yZsr;S~DJ00}3zz1zfE>Z93X`gq5PIerDal{JcS8 zByzJB=|zCCH=LYIX0Ej=Hr6o^!x+X8LjXS-#F}I7-zxQl?zhHwf6**}+A9V! zYqG}2vy*lXzCoDO_;BjQb;#K8minI&7(X7FWH51MmqX97cKD`WSag5( zt}^AU;mIe;xpe0*&Sjwo&<#eE*JF{*%dDLRBjPedBly9{pAHZah7thJw3E`GmSaa9 zc`xDDRAUsncl~sOzyJ_&r%dhMc&b;ifC?aj2tx3PlY-uAYW=$fQb<{)JzpVSN;c5% z>KB|fII9^eOCN=%vOIX{6{|LV`3c_xmwg+GMhv?(ywsyD{M6J5B_~n(*Z1TO2)KVs z2$BfK9BW2RhT{Pl>p5<|x!YYuH5nf|ssH648V*ArUTxRLACvH{>gg)_$=}eQ|AhDO zC3(}=%#}?Xt+a{m^MSS-F$3+vMvdQpG<##)uXv(6mXW65GbK0gtna70GbC;~S1V8c zzT}h@b_b9AlEVS;Z!{hnu)kB=h$GgUb^epf_()#A*g!3*0F(eA8f0zANNxMODdOhh zqS9R1JRsy2nv*qOYGr-MNz3Hg?rY1J_a5=Xu&VJ-<_vziUwk!mlDplKvMu^eQnlqV z;ivfMFYX5)eXxW3lx=69zvSqo<^eaeR4-O(DU_(iRV*Z1{ilAIWSo_^G@#cSPK<~P00O}Mr3I$)!nLQgzrGG& zz)-oTp--)ox|>1BWoeaqlN^{QA7bcG)H-lsg@0)(#n75@C*BG9btedz)b)H{Ceu>aEdFJTP_t!q26PSPnmc#l@ZZu@jmhqj`C(jEvh>!h9 zcdgrJneP=CS2E4Qf$v>+d{owNMXxW;o9lQ!D@|WhRz5YW zoIim1OP$X-I3-xc|8$h~M@=o(XL9$vUTKEO82sEud>1khLwH*%-ft>CqkPqI2G|Li z^LLk5y?-~Tcg}@%MUt}FLmRslR=fxsp5P&WA15Ec9lpVj7_SI2nk?yl`^V2yK8d0c z_|@h*^NY}Z3Q)dY2;edL5P8zW{jM!X-M;vkOGK7q+j_N9TN9BJH2{DJLI8P8@xPW} zx}XQLn#WRu0Gt*;fI5 zVC@FpvVr8rH?+B5ZTir-OqZ=C<5~uVUAvf)67+Hp&l$CgYM3-@=X0i`+WxBhe~G|= zZ6oDYw&6Kx1$iUA{NB2AB&#y69?z}jjt&|SL_!IrqthbkK+R*VE@;wx-jOf-N~DvM ztWdQ7^5R*Kol7_`Ky8`Uzy(7lTS}=Md?W4p+rwfjL1@+Yk~nQ22e?OPol z@_a=?V2WKFW>EF;-TNKh{`#HA*Ms{y@)Z1zsbr9|UL@3tUx1O&mvh(Ykx!i)$IZsg z#HP3&5{Lkxoz0|8Ec?ejV%5HSgD?ep;1T3hZeHN?#3#^3z;FdLQqfnchaU~i*QmjO zB|2Ue3`ep@1}?W5*jbp@QX6$ErO+=_VNEFmJ{8mtxjjOug*edxPJh2F{sUGJ0W;9H zuQ*$kqIIiR0d)Q4&Hbp^vD*XeytGNT!umQ6v3SBa)KI`h-(Hnv+{fm9eDRmuyEi_M zE(*T&*%$c>Uo%LQFs=3#wI7~`yqu(z`}Q*H zV>?PK8`C})k?~@=`xCbpU?NN~y!Np12@D{9P?CAJZ$#)L&8IOWP}HmG9s zPNvKN0L^G)>~Hp31?_jEU-jiO#$Iz%CQwjnWzu>T1W0NNI}NiUM(>x8trr_i(qe{bB;TO2&ihWK({1bj{k{f) zRq)xBm~DQiunOFv#-4pWczW=NnSNZ;Mbjc7#YFr$-pa1v5YG4?e~B+nrVKdxpzyj_ z%B|@&ZWO6VJzu+I^94WEY40*8lPmkB8(zS(co&IiK_zZrH-5wy*o5?o5xX9(e7Gf} zxc@c5m0uK>qG*+!xb@Q!7A;gyJC;}tA$>y4c%$P-4Db%&^0`Xg{j@ok0Z@&nVwBbh z=r1uJiMs%o>gYL8$YBfu;8~h$El%LX3lKmTKo=;425z5OkNRjfu)Rp6k)9D6Og+k! zCDNCD6FAyZ@4^CCf!fulU1HpJSU)0hdiN_4CB@zThg-f4md6fwdm&fAijC@a$#(Mf zgcWFs0R#e)!^9F-vxDY(S%~4U_GG(oqoy*}?N#1=))bx1im45M837A>2&E}&j_2%@ ze@s_PHuugfPQO1z_tgu1C_sk=kc0us1_SEtorYMZavx@t!*uz2(bYq(boYr?$RRp9HT0UEB90$195Uw{DMLqWf0zk&#x zupK=S{G!L)1>uzDsUME*-Ts}m=FQwmsfBTQw?c0)qg#eJoa4_M5FMQ;Nr;^J=!SLp zy?$kfeRTFMemb@H82WPMLGN-oKq=ZO)z(oRc(6kQ9bxXX_E7ow z1N$FjG=%=8qpc6u^}Mh#$7A`>qU&oCT0a&~4-C6>v^=4v+|zIpr=PBaB&1?AZql^apusMfU-9wrbIVp|pnEoIAUS=qdQSO~@+LRJe$mX!yPe&~BROS7*du0z% zENJf^(wcv`&c8S10`Q<#^6|H_b&ERB;HtT|C&}yHdTc5__}99jE}6wiT*{47>EO^+ zTR$6l{*|kB%ur1<>yEwr&Gwg_8pqTWF1=B&`QPvK*Wpb7z&nt#H>whFeqZ%H>Qy*S`JMbE@I^d|<}fU*wHJRLk8w?a-`K6I|oE=X`y&eoS-3wd;P9zmJ-D z-)Yadk3BQ^dXwqM ze$yFR6DF-msOax<_6Uc|6{6ksz>+nxusWXavu_te^qdk6FNJd-V6a=WD&Q`;^rFYp zB^1I(ckJTG{_7{6+2t(TfA+1YpeaH5?e~kve)8(~YcF$#zjPe~9~gh~?kB@~zm-k! zMU}dwC1jD!toD&zx(`KDkg(sUcEavlccFTJddE?|p3-!4iN6>fxgrAaKmgdomv9}u zm(HxJdysneo3g(`ZKakw;))9)wH)!b>)f>#`4fA2c^Fs&7mTj4$JzD#h*;NLNqNeP zejtAu%Y+uQRKfXDxbloSw=A_nQ-J{hiEHE`w_1zv%IF2|nmcdzLCL_n7XTKkU+n1;yJ!Kd731XIK1z_%}Uz zIUV6);H*+ZGkoT9G|fp!u9?Ym+M^DKp-?Pb4=1eW`>o zkA~dei*k7YC?Oz}O9^Gr8!k}Sv~FcAB~v#Cw6A$s{=bDaQVhq;ffmCqZeCFFLuSvJ zcg=0D9BbOy>S8c`e7VNV5XzOzHKw_zKhfX#pYHQ_q9+3fo$A&$b6cvjuP~jVx?a`> zd}G3RHX+rSangzUid?}pA%aSeJtl1|itMbNOzB}vg9Wrd(L~r#i^oh>3;n-FPMCn1 znpaK*+gOaI1$jmL5{KW385MS|`gV1Y<7?7-i!(3BrjOYDbisA&85g3q6fVO1m3Ksy z*6X`yaB_R+d0kxl-aTsAVZ5$)A0!|G#te7JeRXN`7)k&bsIzdKi=~|tSA|emFgmHn zMX0Z~`!CE{e0%lJDoy-Xpux@46*atvRjO{eT#fDYl6aH4?}Q>!@z%!j8T<0xLgV6drz~2E;aPu{NjY957{IowCgWj5X0Wd~_gVN9K-; z7j(iVUvL3S=#bgjh&lByHna{6{cE;9|4s~|)2r6+c`DqqLh5l;d3dX9!?5L+Hi;)H zGfm$sja_rWCF*1U%EmjnUxsT;fw}EA1?BD$W`Cw-9%L9pKn5{-W4)oZda;3U9lS!{0VCt%Q~_uhD5f?jEncca*v6A3DYALvAFY|E2DZ zMK8%$GaaotTaT9bqM^BQJqm4%!mE9>4TZOg_wdvsq8GRpoIdKKANQgk#h=D806JR7 zt|TvE1}cSm69EqZT6t|oHd2=gZCQCGPwPk+H&9`uhnc6^tI@!*Xo}Vg?O+8x+R(wK zE{A~C+gc2;{imen{%O1m0@sS{vu#1M-(Br~wIOrA*5`WMyOkNAG#zptImy_vqI^sx zk8{gD`m`+&)y$-XN35{j^dH-u11;Va&-DGkxA%am9?lPyHJjjy7OHIu)d4v~NwuX5 z%YD=g1ON!9u;$!>Cm$(uPEU1vFYgtdyGz_{II8y5D_tLdWB%!+z&XPIT+`sU@Q9r6 z?l(Y}@Z^EFUeE2VlU*oyZO`lT_pJCL_X{7XWLn>kp+B?vVr{{Teh^)NE0o3pRmH^) z@4{oM>kP8jQV^ZvM&G*uU-(mz1LeA?d5#0O@^t3#Cq^zgkMgjETI!_wK|*sBAq#ua zn}X5v|8FK+eWH8+qAy>#w9nhq*X_90hk0{~N#o?}g*(|L7DIQW%#U{ruqkb9=@SuG zP|t3YPi4%+X5>FP!Hh6p;xe<(%t3svF^^A9oK<{@ZAJ-!<4=9k0LWkfC4@X69s7!u zqi@)IB{nxAZeF}FnJZ{F7w~`u_?BVy!&_OGw%vzz;n06mk@!tBWq)bbmOZI5Yx6mS zpX4sgj(E6+umo^rf0!Pwr#RSIx z1vsb?pZnkqv3B&_8s{ZfP9B>%W7p9B;Hlb;w0E?P<=ww3N>2W;r+_yT;)fQ^N&O%H zN2=xvgbbQD^7U^vuc+Cnsck|CvJhgnVt`IL-_Wsr`D`5^0AQdzSQtF@lw8i=^C|P5 zWo8GdJHyeJi$1%y{9*Ef1p)DCT^tofcf4)u80MbrQ6RDyx^U8aQ9d?g85t)!>8G$i z@6=~J|5o1D$Lm4wz32zfC6u5}NJY;!E3=?u?3p+KVnQ_;=lZS)UHLRimt*soajLd% z-qB=rJv!m^8S|=YWMKfDnto^@9!HpO9f!Sg>b)6DArUqRUi66mD-cwHDw|Wn*Lu=9 z^LjacaWy-A+50>_xnO|Dnx~MD~GoNrz9{ zUbk&3sn}6`9zWm-xQsXPLWl310$@QP1fT~G_GB6W0jm zVWE;PR*_hS$Hf5sKSC+4XNMWbyq+*?vbA;ty1{)9lT^{8{7Cus1MFQaKFY_hS|nY4hafzC83F3dasZ-PTe>3n?ksr&*M&f>V* zqFQFZLr6h!04x5~c9thu?cQ&Nb4=S^XeIe`R~2u&-*&|`aEz&~HJ?73*s~#X#cAXJ z!dm`o(aLS{ZI5a9o(hUuybo`T!|DGJj!}SGqBd%Yko904Qpn7{*(AKV4afLp;pV=B zC+=AD&4fz(Oy)eeXNfZc?F5wTcRd#|*n8{Wp4@UbxTg(RcdX8e1)mFgx&&Qv|f~i==UlaoQw& z$#8}X6g`X1;#2P4p0#a9(*Y%+U;t2XI*C^q06}o*oXX$LUNE^jh}3{})SH-oKN}4o z@`B0-FE`%)b>+ri;SBn7-t9Nr{=wRF>GzPO^i?__TzF^T8b8#wH7RXtRK`cPwT*hg z^8N}hiFNZ4VNyoZ2?OYo3v=4^eOQjt)G!3Y;E&(RgNlZ?mM>iPu8qDj`Tea+c>tf*Yn_1ttejTMz!*VT*gKA%!KfR3z88d!pry#=n~<;rCDi4|T%n zXoLOyb+Oxu1`Y{J+m+OFm|~~QKf{cmbZcxinNld>O- zD23qOTSwZi$bqMUMP73*iS>Xt^mZ4;?aXx8a->#D?dDcMg=hICOeY5w0fEiGa+xW| ztvOtJ8>-{k5yd^m-Ocx-W8z*K+qAXx(I4;BQRd6IUbC2t4QF~OVH#|rur)L>4m00) zT;;%d%8BmLaX*`e{oDU8+ZI6sKG4;^*eLdqSO zdw9l(?|m~Le%9JDgA@kXQFYWlQit+F$y-7Vg6oK~L)g$2ga{q(mCh6@NVws}<`Pygmr+c1;yQ;TgpgSB^~ zJcT9a3+#KNuH5_bW3bC#u(T=Wb5nY`+YUP`ZGH33RMX4-X2!|OAE|QdnvhEpsz8t9Y6((4U6V6?Aq@dkr6o_O>2HVoj4%p`~I2j`6N4bhln=+QsfM zqUPphZ)&-ewNTV5_x@et1xFC|=5(;sjS$8Z6_N{*b*A$Aha zpgw{!Q|s}IY#D=AA<$lAD^A$tO9b3$vG&^z3~ZzjV-in=Wict+o?n`ES1}F%RqsAO z&@6De-azrW;q7Bf1Jd$sUOUE}lWjKm4bQVhy|OiE8#{DUh5-Qjz>eVyK#Xw2Np7?M zZm8-qhBA8aIEzJqoNJ6h%Kn-Z;l8nb%vH-vWB%#&gBAO;uS@=lI zKlg;+V5uE8C}=q4_5vU3st03}yg4?-sB~dB>7gCL-{xrifDyO&x}2@oSdt%oS_i#; zZphFZN~x#H$dn=AuEbJOqi<~)RbS7QHS^N#`Yld&k;_@0!PF4S3Xw|^I5A?iwT!Da z3<@ZS*9f#s&&Xc9+J|EjA~=0yK}jx^O*pE4pr0UG(OqqNR(~1JxRqZl2w^VjdL%z+KT!qNw2VzaG`W4T5(U)>yH7ZQ{h1U(# zNi0d7Pk?y;l?)66rB?X1kBtaATc2j`0D25S5@SGjL%+`KI+o}GNC6NQkhKX?cr^gP zg2lJGMa}9!>Wkbd;E)z`t;V7povpAG0dm1QFs{t;cl3F*fdtdRgm|9Df<}57x(+lR74>dV?J;EyWSh4SHzX4oqO??_!Y`;1KnfOOsX zQ`$cD1Ms5#Fuwu^-xY3LGglBe^5JN|Pik|uQTGl_GfQ~KRkcHr)@F`im;N&hm&uX>3fA2` z$n_q&vZna_0|wA zZ}7|jtDXkcm9Xfn_~W(V@HXYGN2IN`tBFe zQS5^>*SVG0v@>W1S2E-clX_RbRt3%=_Zf2_fe!Tm+%!1}-p&V%MM{p$@oxS+mry)3 zg9~-w4fSi>-6VUc{N%HV!_JlceB1YHyl*|+8{-y z$m_1AvC}!k&SaQ*|E7}kk!vSL8ugB1t}V6Bp%)AS1)57W02gqAJ@mYINnf^>Tkk?l zp1x;P>sMsLZE-8ief8tInpZHm+C&BXYvVExpW@Ts=T=(u4@?sI=9(Rz}27F{z zGH}wtD{{b$+bg148Sea&2M~(&LAf4k*;_MNZ`kt+&#@`o$RZU;FRK+*UvW> zeE8E!yTxwLqAY9Q4H>d`931AsS6$$+{g4F>s;M@yKYV4`sOmFs)eU>m!UX`VVydFp z3ct#B3IJohE1d6R>+hWVlWUa~v!)!+$F8=ZA>}$p zduokFZ~-raN0m?~=qYOpyc@n=LoaYl>*qYW{DgT~a=PWN6HFn2JJxo#{YOdJUo=Ud zG>va`!&3m*+h%indE6(*I-b%$3oePuj7x6g-0!=P$9_VaWYs{7bPZC-3G3?M z#>J(V5r#6d?NaR8h{nd(6q7OuK%s*M02fMH$O3){0LQ#qaFKxCgNtFXelK2zHykNz zxK9DOj-&7~wH8goRJ;Zw*q{`nMg)#{aA0Bf6O(1rZFtDi-U~`Ee5XL^V_#e`E)x2! zSG)Z~BA$FWVFP(3QH21o6;xGNaO6Ky&3CA85`dX#)h(}#YVX%TPLLBI;Lh<4_nAjI zCOm&f%)kaPz-`?RnK#oEr$1c!&UT!o=Y*$451qA3(k0qnQT4nVm=BLXnXX4*s;iJ( zwdi0DTc`5MkeTfX>3Wv|C`Dyt_%Pw=KD%$p*My2k-K|nKr(aJQE$Cbtb@WQL2D^<`)C58*qw(pa5kw%`;_`#&s6vCWRv z0SsV*!wRXfi`b)bu$DlCMVNs~NE+O7OAK|quG|bbkky{M!H4hwU;+)#6KCK3Ye@nA zBJk*}BS-Un#5)*{8;PVoq2FNfMfqd?a`RV{rMcEhg$D2!)DGjp_^5?{;zUzxqyOT?yasnGPX4x5X`E4`n^u(-y|EJzD~qzk4jpqv7l|>=nc{)8Bl>>@;*`kP_R$~AgqJC`D9kkRYA`^%TEVK z=|sj?v*x6Qf(jV(fvfGlZl{dSgSGEF?CsrgIM%#bR+eyd<8{5m*lV9yS=8tcu0C7f zEQlONEG}jZ3p)Aj=V4W**{!=pJZ9VSTb{ zPvq?GQVU{Ejgh;4p?WhY;aJ<-3W#Ov_G%|f6SFcp6P?`4j+q(Zs(_Qu2q zH6jPD+O#H=#zD&{S+j)7EFc3qRHG0b#f$U+z(JCHe*2u}Zwyb^=C97KJ(BP(u81QS z@&G_UII6O`Th$3w8A+V_SAvYVfH4u0BITjRu*$0^?`k;i=7-+D(?gf$!45xtrI$G# z_f&Wcjdt+R)ZMr6yZpeY1n64U@$-WT^PX7n#8FKEyu+_|BW<78cIEn4G1;li)cSge z6i^UHpKrfjdoX?jZ_&-Lz^n)<(5bdcy`s&|Ys6=vi>HlQKQh>!(E+<@lR$s9kjSMt+_Cj8XQDB`#VnFse@2*5I*@ z`)T2cyS=@#d9!3vdWPKe;kp*yY-fQM&f~#Xr4faGlnVowBa`31y19Aq|Cl-eCpGDWmLKGK*M|$G1v_B5&(dRoBVXny7HCfE0W*4 z`6WNNIt-X=(AMQ>jk&F4zV}E!_4&%nA^IBb{0XShDUIE?T&;^Cu2fr46&WXRb-j4` zA5*EFqS(%K!1jmJ+5y1ZOe%6|c)d#|f`DxH?9*K>Z)E|>;!(lJ+m=s0U>O?I!~Kz2 z3(%>yi?K&t&|X>j-KzJ-J{<42!Kw`aNRuUP7&_c~RTpk3MVP|FRPAEK0{|s$SDUI{ zlUV;F%W89VVcDODJShIq-BZvypxKEau(Ivy)N#`!=`A7P_H{1yt6hp8aESpKV^9J} zBm!riNjBRAJ-0DXBHeP?Nh4NKJvx`ctzx+=M??S=g1`+S04T__asos^2*y!c+Qyv1 z5PRAv_Ifq7J5Xk#B}j8sOdr83K6nZ844SUMhuA zd02b(wjw_OfLvXbl6d{Xxq?GaDr-0$ao?R1&CN1?VqVaaeNvj+;;o)c=K7nF(tSfg4{9nN(uRvp0Tj>13yfLbU!|B!ZqK*SwY%OFDUZBpasGtycy0L8N{ehK z1CYtI8CB7Z%C2xdS|eSO8YXO9*SwrVA;nJQ(-Z9XoJDq|WqtiR06(ei!)6Ornd3P@ z6_&vn$=HDa41mj(R!Lddt**_Lio9m2os+nujNXNI&wOGt+oek_{7u+}6K3#$Ggm~l zsoNJw0ZRnj;Wn4_ny!ADR8h!q9|Dk}k!nS^!sUS*_{R+zY6dZYb9hP_Y6AcuDDKR1 z&WE%!>Z^_tnRUH0+mW2}3ju16CKc-rb^|u!JW+eB`uNtG2dn9TVDWm3jyeXRRS%Mv z4ZUgtjBYn=62={-yf~gyoXIf->RG6{TJM2&kv`_ z1gnCgSq&7xeM?T5TmI0>u3XO})6JYM+5Xo*%b0>_dEicF8Q#QgExlxI}YUE@xq9OBpx|04PFRr$FBd(W@;J_=b+WvY!hu9It4VE<=5Q!PH$T&_ypp5hKUL4?V`@M5ImaDyt?P7 z^7o`~7~&4vCd;j|J1UC(q_#T!+Egd|TLF1Q5uqHcpZ)pH>MgtH$-1}5`^Bepk!QR7 zksX^Hwx=_x@4YHnMV-%6%NH$90CksH3|DDtF$Vz>xfV-)Tf@0 z4tV5up*}3DG(6S?xMma+P`x8$i`^- za16qGnMaP_R{%L?CDUuoY)o1#_ny1xBaFXaYfx0z*hea^k1qHpRCas@kzm8nT%)8C zwE|i$Y+xMN`KC!m>dqF};m~imIw~97dIe(k-ET^YaqPs9# zKHb)Sv94!p_d4rijpB4qd2sseGFiXTuc+-%)s>G>e4F?|boXQ@{{jG*+2)(f&RF8> z{qWTnEYSYo5!OU60stLY*1B7oGCa>uMluw^x(HkV0C_hnmDcpUbqH&uwRK(QXjg_l za_RN&7SsW@oO!7q*mjS7_~{QV$u%RpefimYS^(Y}H?ySnb^ws#8HsE)PtRjHeesOC z?&k=HCG-H4NGcd*P9vs0v8O{+?zh`s`r6}Y6VPt3tPn}o#-%>l8!|qydCSV|DKw9_ zB~}+&Xy{?c`Tk17_se-~fXKYLUe&C)cVn3H`xh+PpW}e#inx}Hm9>Qco{As&OprGg zcjfwT(bq~Hv+nqWsyw#zq0d88-ba_;5Sj-mUk$c8`xEQuPqoKlORVoQf%&v#z18yC zm1Dk|y4m8ou;9TlPI1Plk3{FYaO2l?yVAt&YWoffpGN(jf?AElPu0bg>c1Kf(2sfS zH*Hh;3HeF+$*hxe&X6IB(`RKxr4{ECq}1dVxyjrhN|UC>Z!gJxPIJFVX>D@sqZPg$ zAr>x>JAz<~;TuOQJL49S%^077eW>}<7EqwgUFB$%zCi^5EDW6iva_ghXU%~Qe%qhJ z6-HnI7(v1q#1-ag%xAdHe%szEb`hQfun4P3vXP6irTf7}6~*N#UTlAEQT%{;temk^ zK5cq@`emDFq0p|Owa8_d_~z$n&Ho^~HWD@7g`%MRLL~rP@(k|2^1`q#C1V=6G|&s> zITh>~oW{pkqcbmNb3RLX(rR@#zU0|iKYhPsYSPS>S)a2@r}S-vV+aPIFCg7mH`p!S zI7>vd7csYWCivGcmycAz!6Z&OMEG>>LztkDp_kvJ~J~ll*QhQxI=Ad9vDjGb) zy3ix}TipQt(ThfLD~)d2I)^Yhs>FJZXYiZ>^AD6a&TT0-O*XNi=dR~yYXCShJdZ+o z{nv3>=A3K&hPqGC5df`>o?-R9=@9^VvSlibge7&g<*DPGewDL`fmV5A8vt_TbcdO%E4<70l$yjc> z5~O~j(3a3ppd33F7EWPoE}m`)NRY1#SIc#ihN~hqnOk)L(C#E1AV^%8h{kJj-caVga}EI1LkEx}01}}m%KDlT zpb#u&)g6Wv+o`tyg6^j+2oC^CbbR@)Bw7|#4^vnIfQ`(qSUAgkQR$(gYx#Pi>HTSS zyu=?ph1N&y8{U75Q`Jw++>cdwPcyB~FC6q@#rg|O!^^e`=iuUKDXL%hG*Tn6Ks5z`8~jFzSdpzJ z7{nQB#ghl903ZWObl5*!ve$ff?YH*;0fAP2sYDI{25?{kpysD~CTX+~0w#k}KL;a>D=id9~A**8QuUs(bsJnLcwmpQQ~jV}LP`Q5I!P1pvT-3W+fR00nPlk8dKI zw1CQrde`Ny)&Kz8N$+u()U(i0Q0RqCY?T}UL@4DDJTv+^BnL+*0O%>hLh5t1rFbtK z-6s!VZ_jbD8(8;b>O|HzWk-OZHP1-hqgUGzaYfHpHkuv%$HXG+b5swOXT_zAq;qhV zb0LnEtUEWc3)dTA36CEr4HwM!i-rr%MBvsjj&^HHtcPtZ`{$O`=bqVNqr;WWHU7vG74L z46=lxy@n14*r*7ZSC-;O0KiszVGN{YP6zXfGi{)L#dmOoqPhF^0H&loM-fpZt!oE> zFCgXKX)LS-&Y+3Wwp}VY4PXJj=IG1v+5n)KD2=#Apn%N95MwFoFcS3O!x4aphJW^&s%O18@Pqr@&jPs;{%DIN1R z93`Xrr`#Ug0st@we)L{=;#2*Gh(wj!#2Y`)zyF!qevG%3#^x%fXU2O6M$LQjH7WsM z0)6F?ux?pg*VzAw_RuA;Q%0TP0KogW{)AOs?Xy+zcL(3Ti!3CYRR$IX4I0TccfKms z0l;?{s1-Ip&;r0Aj5Tqws!cWaTI3HrG@QBBlULGOTK--y9{>Bt@``=eM$`g;h`AA> zSB*{qJwU2@a4B=6ngRl`D)Mf|pi%(1h8D`D5&$JIfZwT%6g=1g;82cF$%4Ek1#f5u zdDwm_0e};#;)}e{YP*gz? zR^c31>vO1NaYu0+C^3^2CYqf3IzyD&zw+lbESaBQ7FohiWE#(ZXPg#TW!lyeyBP>g z+mmdckf&YRD>dTZJRhMs3XI=ngUTi4aZ*GfTmt}neszGR`TixbJTR0adQT@vG<07tC^_ma<&w+{vkIoQT?YV%Inlmj z?2F|4+d-zkhyHjWTwK{}d>6AN{(DeR0E->HXK~G${T@Gxia?!+ z9CA=Rbgt-T(W+AdMK~t9A1!ISag5YthW}vdh7l?aPvJ$c?>TI&9U?mqnZ7@a9(?) z-u>)OuYK>{Qi`bcxt@K^w8mFO?@8(eN9cVVhn#G6_jg~DXxDD^IN0KZPZ_ye_2Zpw zqcW&#o1V7ot~~v$|C^2i06es@mbzIKXoC!Z1&jf_6;!VfJ?zoxBxnT>VF0RNz_YJ5 zrChz40pNl#;7!LAm^YZ;RLlBtfGF1YX=}RAIF<_lqlo|o^a(m#WCYC|fA`v&Wo_Sp zU?2(6w2A{PBo$A!OXr-9U~yB2ehaYLB44du~{k zh66ZDlKQt8DbHUvyx)aZ9-_?C&U@FrSB7ug7PFd}W8rTqe20_DIq$Eoe|q_YU!41^ zp++7UC$z#1(>2JwtP&*gfnAthcMn8OlIW0aMwZ}{j(A%t@n%>mc16t@n zA%+1!K=3)|xHf6$kksJ71wcJmNWcLQ#gVs(ZYatCeKn&5h5=x;#yVNQnLa=Z`l)s* zUa@>g0AQF}P+M!TCBO%>l=dy7~Gz>5N&y}{e!l>yKaHyvM{cPw&r_H z0^vEN)}H?G!kTaInKxn#^9~c8GyV-u!q@-J5!V2QCO$qyR8*D2E}_006OER>V;{>VaAqV1_^d<7{-@ zxJ@Hfz|PZ51#l6-G;p{I$97X-D0bsDVnH(i02cN9D-OXQn*nlY0m9G^3+D9R^>UPW zJBC}81@hX(MwTUC^)t40i5ejSfHz=4Td5B7v@&_IWH&#Hyz#t+`RzkP|7cU&JL=Es_T4C!NN=kn*lOMTX?Js%L|p2U1Iv-Fds>$I!5|B}4*^u-klyNI zvk~oA_*_3`V{y(Sa;dnf;H{j`s&C8d&Qu@7EcnIS2p-4A2=t zXF|>KECzm=vvW_*HEuJ|02U_b3&7M$7X{uH0NF~8O`Glg&V`c#9bVs2_y&4(WSMH% zTHUN`!CY8pL53H8*maS#aGN=ey7p*P^9M9Q zZ>_jiT(aNmgI#ZHB`rz43y1$|-u{&eoubi&+4ngXE%ng^WrB!wf#*CTgQ-1pQA-6u)UmGlv zZA*9wVr<^|R~Ad(L!Gbqp(=hJm9*CLdywil~+ zZGRF609cEbb3&^-v1h@jmE?N@JTnqHp2<|i{6xAlT0FoCwa^0wP)10C0MtVUU=aY8 z<;5r?Bpd)Jgc9}u05JqWC;$C0EJZU~0T>Y;0bLGb#fEcgu3*%GQI4Z>9z5n1v~}~W zEWf@7ZSB1|9Du9fB!szs62j=TRU)5=H+@zZmT&3}?#AaR-`~P(rcpE6iUMzV02q(W zL3*2t3tMWs7CV)SMKOg+x9pjE1;*ha?C9qPYx&)3wB5+s*Zym=jenc@_89Wm>Aj>9 zAOI7w5WA5G0BCDaSqvM}wbB^JFtAwruy3EMof}QHnr^qURJ}%p{N>vY6dSPzEGQ0; zrSbJ;OR@*iVFD{LS01Zdi7`Z{%`zMX06b)d`S^GqRD#7lug$0Kaw?-b3wKS=Exv8= zv(_3vcH<9^`OLQCXqYS`ohz2`R3eGaO9KEJXn{^;)r0#J(Xs}hAb|h?qBPR^00@LV zfc2oD6ns6e6fvGROtD8O^6%YNW<))QG(FSx=~e5*W2QOUp8#K(4x7X0p6v>H?3xUGns zc4{tdR(`Q_``v1b=!=QqHI)328v#Bizz~Q=0LMu^(E{k!#FQS(v`u~gfN_cSYZdN) zv3UOg-{BK)kJ)uap^rQaK!2PMWx^Y-x>c{}QY&xbtY4+qh=*BiOJPJH)oCr3s26?Y}MU{!ML_hRjC=j~u47M`(VX89zEMS-d*+MltN)jP*-`X`(-$! znhzM`J`sQt9%|LK6n60_&0jpUiS3+HhN%yc2UcpQ&$CaoZ71DjF_K`U410Ii>BHPvKUp|xFWW}3;+h<6(u}N zJZrs0Qd$iFrKo}0{=|qf=PHM0b0K+_xS>Y_Rs*1%%$~Pede-YY>O2WCvGwy!U!=b$ zklN?j8EOGE7I3pVwtgL84*X-AP=V1rYGlA^nAUgp6hHs z(m^-E@R;6f?;{*1dwj(iG zS(PFjyyrcA!~?0Z5)Q9i^;1*sh=ie1X+j;$! zqRYl;Zdjk|4Vus78#D!Fl{-os+0S@wew^Z2?G_01t}=CM=rBf$`46H9*_JRFzH$Hpg zo8(iF#8O1|CSJ&lfIGx?T7n3kg#*`79Ir}M==TGOS{_2k7DOg`-;U? z06^*7>X(1${b|3Ki&vo=2Yz2L@&rRfsMqtB~y zFibps$dV*}4anD#GQ*pXJAzypak__@%%>6nwlfv(I$n=LEein0QPHEps(!6QOPXI| zeN0JZ9i7^M9V&-OIL#rcL0|W$?+r4 z;$zB`XO7q|3tc8!^8JmTQ(DYF2GF22agj$u+z!bvVsT$19L@mF3`_<=6}I9azGmid zT%AVu-8T>*PLDS%z@{c()$@W{PklJTHZ+@s%QWbiE>z5+vyvD?r50P0tW={$?j-_xCae6_t+|L$jRlq?eDi6sya24?Nr-z zI8iHz0bBu~*H<>72Gyj*I?bB@gmVx8Sdop=r%@n*8H|1wOz=Lmu!b`VNE=6JFgLi` zx{e8bdD7d?$r1O0Lxri|9DK!NSF{IrL>sqa-uu(1%%JmwZR4Z+f4GkExOJx9s%4NR zA-J1kEAHbyXUyy02FGsX4EUd<{Ku$dMg%r@_j!<5MX(yc0$-aj{)2gyT_c7LK%ALw zpwP9-Yphcv{}%DVRxHFQq8w;s<$Wz){#*1izp1u|m5%odt={js9V>C4`$(AK+~r@B&$fQuyk&Cz#Rg3IokWZJd(ygqvQ?72pbSNEEPw;6U^98m9S(klJ{XKK%#(ljjk%6f6y z(zc_#qOu>KzO(;_;}72)onZyUR9ZfKTKsUs`kS*CEa>V`c7eKF=RUnQMNGXO(rk5KARq;{ZG%g)S7f&QW^2E>G~&}Q z>nCZK_Z#}?6n}AS4^N*MgRs76|5@q9M&C7`xTO!O>stMrV8zYL-Fi2?{M~1s(q%Y| zlZ6h6CNriz9(MJ=t)oM6)yS@Ql24w-Q8S=1B>wwbXG;UH!4IKLn{~}VHzFBJ)ZUlV z@v4==zO}rgCgK*pQK)H(e_F@x%~3>98@OUJrU3ZXWT=PDqa!Wr((z`!Nyxb}6PFS4 z!I@9cLg3%{$BB5Dc4jsxnt~z^#g!^!zSfNmCzuQf%Uf*&;H#u9|_d7c@n#<+6-MiD0`6(*r zFBX2A`rlMf|Ie6>-AtbtOKWyVLZJ{q7CGYM)n9QUr8KEa?S$iH3)u*!`i+n5_^T$3 z4r!kzEL@#k@z}^y8sWC(k@UB>tAF!d)M86z$RkbsswqbAi5CnXL?3Ql>9kaJG({d; zq<$(JyxY2K7Skk*O?~Uzz#v(WKdu0fsQT@d-BS%-Y4P9XJM@Q^7dj$%$*jH`{b%?0 zU(;d~eW6923%R(7x3hf@fZ?2JrZrlPT*7O0sFLq(m;>M>76^LwFM&~KR(L%qlxzv@ z_@vEtBx;u?dm2z%k@(tRId7`W>akT&r0*&KVx51fwxPb$8=4Fjp6Ku-vS2#5rIJY- z1Zm6@Kne;2v;YbisSyMnxg-=WDxy@f0ALC(r!8gCT93~M>{sP$c?&zu{Ldk6r~C{X z&JbO#aYD6RMHS)?BiL8SWD?G(%ye9-FvTYF4aa2Is!%I^R$=7>WqF3PkG^N2o<01WYJA(0b1qeVpJYcRG#W1AJ8Tiw#Xo(z|3*R=jp@f^ zWT2zJ?D~=Vl5(@P^HzTH4Z{YGtz9+dQ_q(6$BDml)$e{n8uE+;J%+F?KYsPv%Xyod zGFRbq+ymM+pAYxqM-om~Se*dSzW1xDttX#$DFQGM94RjO_)CT=MDbk~*hjcYE_qnK zRD9+2*;p}idwqNAndq7%Y%p%|t1$ZOe)9t>OXHAkWCJJk_Hki!&D# zp6CsrBju*UmHob;HHxc54WI{LfCj*0G~ii)aV!8T=x@D{0RG@HDaFSx;2i&C%Qi^H z_gxPF7>9Vm@Iu0S1Xmt|+T*UG-0W@tRW0^TgG#g8%shj~Af4;sJJc9RC8Zn>c0GVM zRH-R;e%EY^F}y0LY>XoXkXa@%dN44D4!hf~>K*Ys7G)pdx{=Wo3*KvcD&<)Klw591 zH@{i?NJZD$S%7R~;b67&mAhbVu>@}F&DYMn-)EjOCCFHIWq85wUH7|c+bd0R{joG+ z4>!TN&Qkw%XNi&ds7*}Cv>KOc#qH7>m0+>-#E-ordXJmM1AsIvxu29{`lEpA-kd$lIsJ6q2p+d%KPTY2kEq2S}#VoVvhBPdYs_KRW zR&fEK0hDoK!TVc6Y_8pZTO<|_)+awrvhAZd(?L^WaAhnKPcI2G~z?AH2{G9%1v7Xn+J}g zymMU?*-CQW&3R<;g}2K-!X7hsHzr|p0VqK~)|V=+Hj0bzI&bB`OKI||9psFEtnH)+ zpgcd^FJ4`}-AB=A0;*9+}aUzv}h`?CUo{_^i z+d6XzkSU8xDsmbU0#MYkq|UD0ivj=vm!*bX*oskXH@2f`PY^V*Is-+Pp@HQf;918B z6%#iO0fvCbXgm9Hq$T^FI&y{s0K}uLdHZdZSx%O73-A^dvM9M!>J?PA$MjZlO}y>` zlxY@CPkV0>UyujiZ3?{L1Kw_hLx-iJZ&7d*$z{tv6<;`W3f#*BR?2n25P>>o{IV2WE)#hfJDhoYkc+8Y5Vq zc9GNY))=yfvCpWM569lW-_Z?ANovLrp;$y|<4KzjxLu z+9RQ-Kv(yO~`O2sCYHpNQS zMbd8W?UHn-Dfou>QXEMjhKJoN`G6C>rmA-Q!ea`+%#8go?P8&M$H&GH!;5WrD}r;fP6aH372MYb!IY=s807^d3Y^&7vb{N_Cf5MOmx#;CqZbJ- zU~lu&++fk$0A7+Y9V^T8XXpO`1NrZ&Z6QMB=G9@b zlPB%{Zpy4%)>PJU+#c^LlCvb;QU}#_$+a>JT1=^F{njyh`Pf)80R*l1@zS2#uPm>( z`*Y?-0XCCEoW0zKo~Ch0S3GJMSei2<+Zzw$mLL>kBuN7_r3v2@8N0oH`%6>W?`ALU zBypj+$t{mc07$|@`~5>tKfJ0001EpcMVR7Znban`&%XJeOAbA0+s63{XORViPEjJ! zukquM^`)O*I^fVx0#smEky(a)U!5fw=ePj|dxZ|bmqgD>Oidz2^&a0RdOD3}4FF&S z$~rl5V^8+J6Cz2AD`% z`idQ$Ii7mi+R1gXd!prP5aiMtZW8xoJ*m7ogo***Qcl^3o-0KZZ&azun&S1= z1U)J_32%>;ioeXe_t2z*U2QD9Jtz7vq7R%;;+#edICVWF=@tuY$H$@%mmID;ba1b} zYZLk^d@blZgIADtS41dgV36Xg{oj3O_~PjSNr-pb_Pd^caP1$c-fir^#x-5}L1IawjJn?YwV6EjHbZN6^g1Y?`{E_HJks`PJX-+81Q-p|_&Kp1wmTU;ZCjFG#9cK`8e z3JovZ$9#e5=kwPQ!nqKk-H5f_%)OXfvl@U*GTrXwxOE5LJXG^x^IFSdVS8Auirry7 zdbqA}hzbA>;=ahywV$q?1ptE6mi0z{C1-Ul7^XR8u=Ey}6&C~9D5G4e%*#kM?<+AH z$mSJ(9yi-(2m!KNU24i5>da~|gP+3rjJN=>acm1z9Ic#fGu!qx=Bw7KV`>0UgW-I8 z?dYP?*=4WVzTar>75A@E=%EK-g^TL<`fTgSeP=~QmJNB)Ed+2wjl2EO_2&xZT=>~) z;}hjFCk}+=4F(=@vs|yQz$b^^UoyzbQNab8^+(&d-mRhOL}T#e);sMH zZNx*_`f8zjI`^cMSKM4R`1auweLR=-T+aXBE6KirXy--mIF(i&c*W2kKqE&#KtVqrcNqUy>EY??dc9obNg~&G;yDfO;vc8v^g}ZFNj{Q1>57^HQu8n@^1Rrth%+F{aT6k1cHY7`Her9@R}RCoW@Cv63O)_SuG; zL$yMwT@EK*t&kxGVx~>F-q0Ta;Dv`gS`*ha1_1B{@x!kR*0GcMtwSxty_bzK<% zP#)m~>MS2fRf}A&BOuka7?Y=ot|3%6|86t)TAVX6Woc)S_zXvhwT5+wY)~iX+VMYHMg$`N(J`lo6#Nz|N2^v#=s!`H?9|wpcQ>XFyk!2Et zp1c`uJQl5Asdh@&Aikk}cJMS&1VPx15_A;sK%tf;Pu zjt@(;O=XcvXKt`(DzN!B;(hpS@%wDApT|8E-$NV(`>m3xDEBH(6^273mr+?j*HwZpBl+lJ$M`xb{jEFphHB@4i_zb^45ld)hg7 z%>cl(xcTb1m|j+{hKNKh**9+WsA((gW2vL{H={qTp5p5{$@L{B_?A{#J@hrfNvuT| zy;MI#9A`)0@sVdYT}rNH=ffVO&7&t6H#%;vZLa@~vk9jyT=I_NkQDJqyo>f<{5A~k z-Po8@yH8$Sy&~;%2gI)se{`o`i?zF5*km?C`0&CX_TvxLb|aL9irWE$mCkSBzQxvF zpS&YjKE?g!#)a>_weIqld8X5cdHvgRY84jXZBC}O%9`^VZQn(zW_N<9X3i_qd?@At z&^HJFz*t5sd)@B$%A&@h+GOfz@4l*iemi$p%<^F~ird%O`16PNaQ6AEtce20kmRPZ zJe>U_1%P@lMXY_Evi*r5Wr#6(zcZ5H0iE1KW>U|(0RSqD+hl=dFX;fF7v}%J_P#Pa zs$}bWo%Xo9y9;q4NP@e&yW0%z?yiID;1GgEfIvbVLfqY5x|8-k=lhX_;lA(OJHXhz z_x;wNq@O-rRi|p5I#s*&UR$oUxuOVEFy34D8X_!GPoW{D(mnxLu4H8cZs$a z7FFgkBDbj)1ZhZj>}(s0rbL?o;4Sj$6r)2_sT36Cf3;&7Fz(#hnt|O(;8J)%6B0;Z zOIzAssFL|$iQohl+H#BxqpHo9+tFz@ZGyNLvu2r5wJ1ks-Rpzo^GW z07r%EK1y6}Dw!idXe6Lbv!6fL@XfpCM+5Bo*}I9+T-@`%-o3(y;Uflb7*%YVsV4lV z`EUO<=3$nx=Q4KFgop;=e#oJkHfc~@|H9Wd3N}(Fe&u>aSwW*BOKsfKg()sS%bmr> zFTP8VA308v?3q#{eaaKRUAJ!4VLj4xwf`d9r847NcSrw*9`nnJ=y`#dd5&zERTHlbdV%c*unE!hf6o%1o!wYZSnN{}{UV|!RO$yTMi~7Vkl+$-7KQX@32q_DuHl`n#mpY;y(3hj9ezE)(TdK*{oRO&KFC#eDTLjgCWU zidjoF06;8?K)?t9P!9?msCM1~`B}0Kki!U!0{}Qd?(>p6eFeOk&%Efhq zZ4?!O`P7(ZMw6ErgYa)O_)y=Ld~f``!o!bl@~hVEWX(uDUZd<}mPmL7mrJ!y9z3>j z11+#lW!yKDb}aHWCXFtuO4|TxK$X8cto{~&!9=dBO^=LQ>mL*UOrDO?&l$Z*{=Tb^ z+18i^#vZ$A^E&h0kHyd4q*Z?C@umjMLK6bHw?m(PHx9IbFoEX!#{aq zj$l$|_G_|VhA)V<02D>tLpW~-PW#li?tcW6Ttb~nrir$*&BQka6Qc=iK%OH_iJM?h zE;Syz-q1QFX{Qtbf|PrB$0h2v4g&BauF0BO^o3GloN<5S8}Ctfx10bV@z^; zt=eEhpb=3i2JQePkr0s%06Yi*bO`kcAcHFY)jk+-f!t?0n?R99(m>wtP3RRpH{kkX zm#S8fiHlaxfK}}fU*HmM3iPD9XR?X{ zhG;_4u2jG;C9^%-Sr{miw8tq?6L2@oLf>G|AWM45qJwF2DVyd?{5Nb$3bIZ`mY%leVkH@54|>R2ZIc1W(_dR>W`yT?;FAg4vM{>C&vrYWDDjzAjUDSuhH8^mYt-}3%<{^p?o3L=xAs*ur-mJ0g6ovu(0S>!Ap)r z{RxHoa`N5TKhd{Aru8 zk*Y0=O+GhxJ;$ah`Hfun3k!FS*U{!x%zFB6b3wf7v?H_Hl)r_v6fQV<^rDB~P6TxZ z^HC#zZ5UHeaC3M4g@5s@WB@dYQK9{rbvv1_RHwh##T{6zSc{{huoi6N<5pwFlr7*eZG10su$# z>)cXPX{Kwf22qnT<%$;e>o9sAj%k)ao1m`-(4^4ntzg#iScoA5(7}TtYJvun7+rqX zaR1uV%PM9k^4O&;0HC!iCvbJnE#auiUIlW28_ZM}7*nD1BOwD6L5bEz8oba zzGTL-z9SVij}IQh+jdm6%TK4N84#12cgZ{{I*?2C%BO{^+5XT?$v$E6)YEXxeI{5wJ7O@` z0Xs3}UzWNVskI+YN#w5dnZiDR{@6^7ObvZ)Gj{ttmO>SPRj?;!xv9If-%`sYs#~rt zupo^ChKdG%?DpDf8?IIr&EOVRWS(EtESAfUx0hyy69R>`xY)<7Yb)!xHp zI1QLvDrl>>y3PX3so0ulx%=D&ikCi!V@T>}SYV3S|7~MqFGn*>th@4@s8GJfSk7B* zrBFZDpI32`(O5KS{8!Dl##n=MHlMZ#%szw)8n=PMWnz?$%OKs9_}jM9uQRBf0~0zT zx3KViiTkT*fwKr3ddfjwGFIR)+{#CsYT9-;UTdsrkCIDd<`l~2_tO^eM1EEND`I^A zIaXtP9#Wp8RYElKDPS9PaqT^?O=Dm0LqGNjyPYHis#8!-wiCYKKh}bmRx@r7WbIG|iH_%dH-;v+ZE#W`SqGQ}S(JL;}D) z4$D)kabKr}K@J+6HqEP43mQBc)oi1!gaEJszAU3c{~-!rvO0kMJ!=uu5M{n4?^b&AtY1?bzH&{%7Ch-B@nBNN#Tink$uIKUo%jkFn9KW(9Ibea z_z4@R0d4)#Hea&Ld6jtRg`aTASCsY@v`xZR(eWp7p%XT&UL?u5yi)lz3Khut_z5*k zHB+e!W>2}7S3mpNrqD#l#MkD?nukGB|0MOCApCnVwH->~LuZw)Syl^n}BY;&1 z>u#*A_FA{CKtYY^BOU+%IEFzZt16T~n9BeliB-zc7Yyv&5ph`sPVz16JazguMIDJ) z*h~R?piRjWOvR)5wQ{Wvh5oiK@)f(f#VG=fN9QWUv%~;fS@R{vnK#h6~&jz02c(vwM>Qz#B^N59ONPgvQGc>(-JAE*4u57 z&f*AjK0BMGi19)yvsrVM5dcgj`?ibeA_Y)1l@_yd4zLKz>OVav%u_YnaJrR99pD#5WYD>EikFT(p@j8h7Ba()%21x6VSvGiZh?G1|S%()QuIYNM|z>#O_<`Xai% z+hcLQ_~pJMFVaed&E$Uk#LPClG|q6bnus4kqMRm{t%nP~CCuy~GPt3KDOuohWql9? zPGKzf(W6E)<_|OUCk5JZ_CI&9mAS?|A6BbD5vbQF^;D)Qa1s<|Dh4eR@@DiqX{OM_CP^2`%4ril;HAD%Xh)2s+{resF9x;YR7VceEi+ zKG8?1k(HdGMGN>Cx1wq?07V*4OTcI!G{RfO@SXkZD<^-BdMER~sRQhT@>^B@)1XKu zuu5IPFMa!32mpMDL41}~`bTupmQBi)(S*P3&<0`^fE##CuhSFpS&3Zv|0l-$qOe1S< z%z4*~Frip1q6dJJQUeL!P1))ublZ+SChgVS_yn)q>UD|B6xT_GlDFL^u`W_uKUgQA z2mTpW(5DUbTD~p#Lzsnh93ruue%#Y3;LMrI$DlTU6Kw$kJa&+uw}Wn2SfcFMuAhdx zoA0z)psEv1``LKM(B{M=A1$b_%X9iwv^|Gxs&{5y1nd`U_)}$=4w_Zk1n(U~rdWn> zRvy?sRBiU+1usYq+tmFhl0m@yQwW%YhY_|O0Uv&pt#90 zzFe{tfRZAUDe%_bwPoS_@lxB+XEBY0q_x~P#;`Izd(G!`e062#Wy5ccS&4(i7MHWbBtB;f#9e-5OjG*Of@2yihIeL&JZ^R@eEda=_ zVii;z3>>@vM~Pyv#x6KvD0FE;><7T1CR9aLa%TITl$e@onYctT_5%=>5;YsTjbo^y zZ$fjd!^9@7dhxOMZNmP6J!Pk!2)V&>?M#=YpB&!d*F9x>W0-;d0(#NB_X*@40KMpW z{=?Q@jCpd)Pw>y(3jZ0j31g?W#bqfjF;SF;bnok9^L~12Zo76}+K`Fk6%9@A@T$Ky zc=D^gxJueo-Z3=YCMPHq>D5o_v4u9$v1ZFg$s>CE=2GH@t6Qqqb;9o(ZzCK)Vrjxn z3&({4ByBJNO0ppA>=k)0QSGq!BkFY?RT;gj0VUL^tr+EA`tvgKwZ{mbox+@fF$4(= zN1T1Ry?2~TSIjrWx;0K_8AVkM>ZD#pMiI#Za38L=guY%f_yAC+kZ)x2!KSc7rsO)U zkNp^n4WZW9Zdt-_t{P1Nzy)N}3|pt(p17v?_+T4z}&&Vy$CpsCM zf@o#Rb2NyKvttPa05m&Wk%XIHkhbd}@gqo~%&npGFfgU_uv3$6>8|2d_3Uu=5Hust z$bWcQlJMOJ7NxFeZDB_>h8(@QwO!@5Uo?QhQazJa)%fPIrOEkI?Sw4Ar&gz`)SRaP z41hMz{T;6)ot0SN!t(NbR!35@sj)jPrOQtPs;)!y<~40S`1uQzsPY1Z}KeX9XL3og1^%cZhSPicZOe4DZmg;B_o>ov?> zaN;ggoR4vMP0<^6U5Gn42^tG9wmGVI(bxM+e7*A_b>~y;+uGizMsM7pvfMmp=l;z* zm6B;f8JdN|@1-TUkJHnL`9|6T0Fyue=Jngu@T{KC>9^1gcI2aogh$L?XMOKFS3;70 zLAn4u+AD9>p7~EWq11U)J6&fup_PETT zD)YWH-L;pBypnw{O`3U-(`kS-&ScBpJDD@Z}e8^&hcAZ6*eXhn2|g0bW9Uj#tGH^ zhEUCK@R?QR&bh8$rMr=)C^~lNs6v9T;1Fy8XrVzId9?>|cUJUwgxhU_d;6haW|Q^i zh5&6kkc~J|P%t;uV8O5%YU%6an`I5eeJ7_W5f82;%)?-oNUP*EJ>wP$01Wxw_MEH@ z1zpjdEXHPAYZLu}2lkElk*(ajtv3Y#Z#5eI%hGoj1Hc`0lVfmVWnH0{xeC3zU3@pD z0dlos+fRB89advsGaJ{D>3qpWh^m>D<|D*0bG4bU-EO>gzgo3fSAY0^YPuQpC()aNqOeCUS~=$Cv5%^v=u)K=#gvy_>>mJGxCg z05nvDV=+%;e1-sRx`n0sqo36CzGc$;2HGw}ac%nT*81YqwIOkQGelz}E+Y}ZUAU!} zzESLV-2T?r7xx*_ptu_MMD01tADRI`3}ur4@>pFn+^tfaTFzsceE-3=a#w6`Sju@nK|Hmh30l>4N^{LiZK zkr6jveKA!x~*y2qmDfrD&$plrVxt&Oave`d2itv$^4+*lxJ{E6}ZW- zXtL2&R1g>{)Y`TH9r3#ff?dx9jR54Nddk&IURMpo7w&w@kfAGY@|}*~SLM{2cSXASrupV3(3M)cs!ee9ZqD_4AsUB57 zAdxD&XKqjxI65?Hzlvr+;4e9?hk?@HJ6}sK^uqc)AQh`Ys)SC~a(Z!XVUjcXJxRao znM3+nX%}2HZ2$neD4E^Xr|+o^V?OEh8fBBeAoklz`=$s53u?$a)>BX4#aeFI3~#2I z8+{gK39Q6(^5M(ZVJDZfExspCl)#d-$Gg;pUV}`PffJa6$whaM)`Y$3c293Gt!y-H zRPxhvb;qHo!yH_k9-Tap{1L!*d~&ipf8^(T_5vf{nmj`UV> zt|l^-bjSb-ml)al%Jj<4LkJflO@UqE|0#{oG%VJ-A@BhJ7}E3UDj%GS03aP82`mT- zBNJt9>^%CbZmTep8khuu+=#{=avwEH0f0h_N=T36rA7jPW+d=ZPLNf6d3Rk<0{J=d zaF&o|(HOAAD#-ruqv>UPu>hL-7bZN&%=zR?tpJP0B~!>J0DvKIf|Ptfz6Fq#hU|Lg zWXds?FHq_S00-U@v|R5FZ;s2YM){S@RCxjq`CF<~Eo&G`2rFSE6*n-+cv*Hcg5!V0N}BsRa^8ren#*7QbXKEZ+>n0k15ktsl=YX*(@}VO;m3U7CDuV( zX~#70DQ3}I5+O_b=JDMHfEvhLL?d-;tvQzflnKM1RPP9hoIlEW3pBGHbZh$)XGTa6`CZzogJn}bTsrFKx^-fpQVf*g zO)W3jaa5nPbB>(*puyK7E1##zim=#&V<;CntLY~IKqHN5-Nf3O$?kko*aXY4+2By> zYspFr5v_aq4B0dQAe8NLsWEvSI}ShPQe70Tl>oq9jHI`XqQO0_MJp#rCHq=RhcLw& zRdS?!rG7O45Oi5<_&G%bbtltW7Q;+a><9IcluIg2G|-2qNbtpC0N_JT!Nf<4&IHiF z63G+oOFpY$5udx50Yy;wB1(|ctQcizYFrz)fCS3utEZays6Yka(Yl=Euu^B{Kz1!5@I6|vpt}-<6zK4*GPeKp;c;8f zz4zY6|F##x@1QLZ4*l}GPe%p$PM)&M*lX9h)*GR%Ks1))2Nh*C39VsHpFj%Vrr8ew zt1wh{_`~{h{sWgxTck7)2{56~7H&G_sXFU`s8oN0ESpbo2Dh^ z+enhxxeDy+H?07$AM+W#^jc^g!8?>K=`0GDri8m z9rJT51O(`EPzBHcDFx!o?M>JJ>i8c|G*v6d=+FH)wIU9C(ASF7jx&q}WaXPPkI@@#E3%4Js7$i#TE4183^r%PL6NKlGB;!RDkRq8!8V ztvWusW9B$(>^!-*K#2k_BaPuU+-jceS>mw~P52HNqgZp>k1CAfCHLn)j~_GMbVjs( zGNT-qu}H4iiF{`oWAKeqci&7~z*8c-E*}xFvdZ+tq0IXwb!Vv2C}3Ba_1(nTSnw_* zX?ov8-SgjZb5G$wj!k}@+2H-Tp%n7ePpD$Ea6M45R=^UZB!%T8#-)z zJ26w;#Goxxr_&~I3{r(ktM)>bDw45~oshMrwZl_pgng@2iM+a(SywtRvO94Ot zqI3w|H$~lbZrUp}_juhgAFD$s*NU6MjyzZ*6VgT|3ri=p4zXKmlv!G|2^I&L=Oh{l z3_a-9cRoO3$N-87CV*TB{y`go_-si~1^o*Wb3mh1TxR#ak@~LjFlrSi3{tl;&2j5o z6YtNGMzpa)2ms(CM^;NRm>pgojoIzOLF|34^1*zMMrXi*JL1Ve|3hW~kd9eAi(-l1 zc`YFf1d@!gW@_r=iSkqvqIv)&52WL6qw$++>v?WJK}eno0U;PSLFRl{fj43HN`udd$z zalOb({m7VJAC(R;?8l7ux^TFya?&@K`pvW@V8D-mT$&S?Dl4iaM?(=06-JKK-s2TFZK(qtV({kYa1GHVH_O+e)v$GjV9*Qj4+m25yja02vs`4~Xs;=pn&f*kS+;gc> ztECJo%cFSQhyM@~O$Qx7F+~3`tNvmDV}piYXxkHXDj-N*+%v|Ud`JZLlP(}k3tW;r zj~T1^?3Ok>0sxG~HY$uH32g!ZW%6=~;g8mQO24^H`IQ2oMyWR{DVBDgCo}7{;`JQo zS{T4obo?3objLIe+dA9SQP6*oIR&6qIzBF^VE%Bf%6{}}G8ug4J)zWJ4Q8{@yN&1E9K(sXU$?j($+m{ z*`C4-w>evvM~(~_@$i+jV%c|WhrUOTj|xhB{?o|7)guESfUsNo3h|(}vf!0#FEd2W zMR~8ey}g2p>C3*OU;;+<9}iK_9Oh1&U8H;vKssg@Z8_nqcJqg~GpPPn>Eh3R?-2^= zy$#v73pzg4VLv0$L&G#Z0}$zmELCZfC}17(S&6pI`GY=otXe0@I}c|yQJrM7;RJfU zkH2+pRK31Hp78CsHN2z8S~8etvjE^CBsuf~vHQlRr>~YfWK=ea!z!9o#u)(v8(zk< z@~S>{wVMV87+?aZf%qS2OMv+9 z7@$)Gv)u8X+%p^^p4#Y))#li70bn0`64t8m^zof_J!1FkeIselUB%VOcUUwV0st=K zBN8cw>@Xbw^yq>8m_2-FnwSSw)jOQxXkeDg92Jv(%M}+(`XseVXq}m_8K^=Gq+kH3 zhXh}muYZ|sJN|ajHj1Q3LJ<8*Pm;!@ddPV+UwnDqym<|M1^{3&rAdioU2hht&^f+Y zy}BC!^ykXu#z=WYN@>o=pRE-bKwCbiu(_XN=LyHv)b`q9zam9YRK>e!srAMHQ@AoB}E0tb6BQ%LqpuDmgB@C7@=8Zxrn@$}|XJAKIWhwc|G2LLpKXRE!i zsp;yuRrS-pXE1RZnF<9%3A)z(pPG~5kHtg^p5rngNO~+zha}_hzB~!_J^5_Ei(I8J zt9f>zkahf&{E~$1x0|;`T1aNY96&VeTPNQ$U?+@Rqx3!5%tzulTO8)_F}+wpwjtnr5Y@TI=99Pqj&AUZ%txY}yq_U4|$~Ktl&@zf=gPeV%P; z|1jH1)P&0KW9StW^+-p3h@^^mHuWV}qtuQ;2LLaj%7?}#N7asN*MJ69bR3=A*Y1iL z-?Kuoce6||tk-=GpaL4l&t_a_H9M=cO4HSYIly4<^FnFG@VCA#JMb)m5IqmHRRDmA zd7|W0KY63RP-}_5)n9Y)sOPlZaaw%CsaCvq=Z+MqAss*yD0{^PEw#ZHR@4%>f$xD> z`SDbh5it)fV$w+9E@Sl|fp@F&NUX#G<8lqb?QRK9vU%TC@^{g8DpZhF#Jp~;Vo)*X zmU3}FG7EXQiXQ>oMSElMc~{+~qh*{EsQKoyS702x>atFg&&;PSn@K8rAqRsoq_B2p z%4&}8t2LAr2%wsf>JG5+`y9jkj`+YP<(gZ|$!)fTKY6?HxN?t$Kd3Ea4wtn(NEc85 zP(q9HW9erkcl}0nKpWrZ{aD#+BX=LUX!|+)%gg^=RQ`GXGmPNsgjgxiO!L2R{> zyYs3ET3a`f>&s_G#d_^3CIu#;Gyo7vC+6^spSpKlA3|lxy3@h|@T3s}3lExnFR^1; zOIr#XSc({#naq>cb<}hAjUMsR82Ax=2q`Uxy&qe#x-v9$V*fP;Ab|X~dl97eRo_Cw z8Qtp&o+$VF!ReH@nQ`l#_xl$Xve1H`PypB~&u?ysxH7xu`^3Wx0K&^AaE3)(%rkZJ zG=MUwYnO53;O0Aa-U&>ribS~|Gb;4c9o3TbQ#6yxq;$|)DQOs8l zZjYsw)8uG*=(xBq3Mf@|Q`N3tT&`@269q_hfKeDrV-sail9(hnD;x~~faGT~)hK@n zy%+$f*ELqQG%L^?MNU!e#Qr`2P$>KK+_8D`I36n-1b+Nvn;`0c(1Zqa>HesPmFJH% z4m@|hcK6W2UKo%0kXND2RoTz4etU6T_4kps5<7?tBd}c9k<$Q z{BD}hca$B8S#Yc4pT2NLz5CROe#$cFqYcK=JCQ{PCEB_hdpcZG8#9z0t>1Z4YL7+q z(blwT=V}V-%pB=ap$j=Rq4Wo{i&Uem^hG-WwBoYbAtxmC`5f<{Wt#Evmau_nqOl9f zJP!cCA%>kVt;n;S0KlP3MDicoc+1hF-Jl^qu_8kyF!%v+Wc!u5=JO23$+YryTOYfX z(Satkfds2_O)G-v7tdQ6J?ZD@|9O9}>9cyW95P~qYuC{8{6xAx1rKhzkG?IkRJQY$ zPJf(%(5Cq0uFhXP^tYEsedkOI=)*zFb_4ubuwUKBKb~QU2~eiEO~Zl{&em%C`WxJN_kqCo z7)m?vJCyxZkW_r=qMYa9#olx556FpRXKeVuV0@%QQ+sBeF{j>p@MxoW%=nJ7uV6k} zY9C!%vESKu%;a9`>GT4W!9kM#I&PUD%Wa7$h@~TF6?B@Z!|_y;CA|LVkZdTYUQr`5 zvoIASWmhGw4=*^7I;BC zBJzK^6+x#r#20h0mo7Q@S^B&)w^|)F-1{?g5)vi=&}kWw(A#T4C*z&l)N7@rtaE&r zl(DR((*el(BaO!oaHOB+XV)lD$~0iOgj><3*N2k`05E81PnGnWqgji+!thE(sL}x7 z2zmdZQ0bB5T>#nG6D6sy=rcpv({|K4KlvNmZoP37eL^(kFkRVon(-X+Y08mdb$Z{) zj71=riC&G4_x9geQ5`jG#NT?Q%$2-=fUdCG{*+oBmI-STFy!@Tn6|DV^vd=>a7UH)_t4|K_n!9?C zUj%(0?m|nJpYix8S>UuosCq2_01g5Gnuyl{GAG624G^1T_c7!PxxiuY<#UH9bFW8q zc-A@-acY#vyG^Mh4T2+Om`9#Q@MwIZ%qU8fpyyfLWj(RcS@*baNa|l7;0(GgSb9OSWJ%Z7D6hO#fB2 zdASa7m%HfUwt>2O9Uek$)Fob!$#h+H;!?fJbDnvrE&yaxWP0VB1{EG10JfI5zjN~5 zF~WLzdwJyMvT$2j1{7e7bd@2Kjs4G^t3R61F!MWhCIE09XBgLd^c{crWa8atxoa#SX6;nwF4*5vH=Kug-d@ z)`#QcFKgvTT$E}BtZz2?zNc0bmjH@PK6`4Av(AoH0qf{)n2TjpE$`h0@r4GirBlAa zQTj5}V}!iBZAFQXNCGSQdTvckFo35xN=4Eb0#@f!?N1vsl9B75?oI)~UDok_MHQ}< zHpD?~f0gsOpE}9ez?Qa$<=v$KCB{V)y{4-At^oLr#3n6sZDF5fcGo56UXo%3-}=*DG3iWCN9~T^awz?rBJyM}5I_d`AX}=Ft`$ydvWmOC(eneJ^k}2g@5^^M z42*<&q(<$FULmYXnHjCVTbMxz0215VF1+8Y8g_AB_E>3@7dYcf9(U#+~zOPRtm>&PGc$5p-AxaD*@sO~7Q$_{RGZQoR8 z{{1yjRBZB-E$vOZn{#_7(*b}&ZR?5Ci6%g zz&vSAFyZ*Yb{GolS_Kod6llZHKc7{)I4H1lG-p?3MaY|uR;8fFW%0)77}9{tm`{!? zpt0um4?sF=PXA>yB#C!U&pe;o+A%oW=mEVS>>M{J@?3DTHue2UdwrNU13fkpm z{M!HkhWNIGsEe#B(xwT-#iaN4O^Zu-e> zi(PMO3CnxtI?L)Ag(f;`?g9Xapy^vqa-ESV=zRUZlap{mlMl*9007qbaafj#{e-KC zSW-?DBB2vf@)ys!R@oh(>pY?8w;Plk@P%k^@@41v-uMtG!ACKu{#TyPJk`Ogcp!8$W2Me7#Hhz|Z^XpCyEnjYr?k^NFi@ z<>g=;#ypII7k-qQOWRqBOkgnFB@)g(%}6cV8oF?rcQi{vRh4|q@9t{YSrUPbaiguo zF576YbA=U)d#qppfQYipk%qbsEpxj(z+#nz{rJSH>*j5DQHXN@k>5*Ym7XJwOl3;& zy=z)P5B~aXvjz2;w|BI41=pX4sZ77%N!o0D5kD-T(+ zrK-tytK}1Q$$sp>bv(cv*a}ZQ$UAQ8^fU10l7;+GLJm~x7v5s~Kqu^_ zKIrh7zLBgW`7l*9ls~Y2Aa7uCUn8St&&9UDLiB2vt39%;;9~kRC*uMaAMFu1C3_z( zltdVIl{Bx4RXAeYG`T^Ijd|53#s;bY)i-I#(+Ojkc16!?p7yduLd^TYrSyH=}giTCfCGN8+8 z;d4HYNPQh`+|#7z;%SzZgQQ;Tjx%&scCEtZhWK9Z>KHqD1>ggMSkk{$bAQda9SWcO_W!IL|TOMwiw~S$>r#nXn zaG~B-Uw&t5P?TZu)*!^j^sGJLC>xyLZl3bl+UU~yD&5d3RozVZ@_jn{pudO!&SHlm z*~f~q&S?GF`69cxL!~Sh-3*=9%guNb-SeDE%DkVO|x@!W3q2|tZW zcBhsB1dOP@t@LXED5o9UVpR^^JlGidJw^X7{2{d6hmoQWw^Ku>O*-H)6Yp6{KC`zN zj;vz?yD=Q3uwRq8YOjU&dU!K|Z#fq^1RuiDc;>>ew-5JcSF7^xJj%Nu(lJ}k?hp2H zMBpCe#ezJSt5vH)lV<%ecMI3TSQ$hffG})P*fe%SZd&KFEtbD*7G3a8Py}Eh!gWh+ z4TL6Qc{I>1)rQlC0RSk3tJ}Kx^PbCY0Wef#GamBlKTkVrt;D|c?8>%RkBuRt8&)4( zLK?dEdeU9~os-jB%T|g;=n@8<f9q?k$?0jyj} z*5N@ae9P$8GKyBBQ}}t6Fc5k&Xk@5%_^W9NL{Z*yPBq%GDlx1WB;0wZkW=N`rmBY- zls}&)>&14JoX%HCsqog+1lBjcdGpl2wKJ{Ae0(au^?d#S!opU#Ev#97@et4c-s|Yj ziTm%LH>g`F%f<=Jz)d-w369%k$lH*9*MeUUU<=N0n_d)=%QjnhH-19~BN`l4htKw$ zZy`T~wLy+ThYDj|LE9tskv>~y&Q(^b+oK+(L^l2rbi*G+Ti^${Qilsq9DBoBb86jq z;k&v6+Y0K*?YOU_H zOuVr8)8T8+Cyli|6X2dks{?@x@SzkM@4bxPn{-sE&T;xr-YxP#8H--$k>9J6GSB4r zO!s!C3;?R-i9SZ0bH%`Dy8M_{wpOQqU>0q}_^NEB6eAhHpbJQ?0_V@({9~X>)!;Ni zK%dfh!xrahT>n8MQz$L(!;sg=%o=Lf9clVeY7`)q4fS8_+VLv^q+hIa4Z#LzExaqC z$D8?%B{hpGdx1nU^-F@zwFm@3yrVicv}IDK%z6WL9Rh1`2PG)4(y7h2daSqr>Js+| z0pEYLD_o^ax}(E(Ez!FoU)Ku5004aWQaY*GTXUGBcG$aqZ4P=PG;rMKc+D2xuRf#i zw_xHe?FQN^3`9RsLU_|*9S75u<t({SDVRrs8 zYCA6Kd#*BE+?=@i_R;o<;)KUPgy_s&(EBFi;8&DKAlcAs1HD`MV}6wp4r34iU<)*n zQ1fYT$SyIVy7*ZiLX*N&_(BZ^vfx(3$bGA-QYNmlU3A*bdN2eUQ9pN*W_3_eje3@k z3;=F33z>#(gCsGSNcUI1(~#0>YjB_@t9)o*&Tj|Mte@|pk<9v>I z3h}Ny8(KB(6Ls@5v3tW=R9^F;GhAI6h6IbKC4hsN2s1=bZ4Hf#AXOzo1Z^HgLJhc% zmPT1Si+&$QGS#g7%#oc&fCy}$x|LB$^9Sl!&lp){CJf2nEql1FB94s004&2RTDkfD z>4Cj(9#7g^Q)4DO_eDD+WG_BA?NFBW7%Ei!I-imX!pFvS2z5VupYTZA368JhUOkUi zx+ex};{G~2b16CqV>=(CiX>fdxl?n?V z+TCELq67y4m`WPcuODf8rs8e6IcN@BLr&xm0C2;6yTrBuRU8TcE*aOev)|C$I4CjT zXjj}V>*Uq}C6e!u<|7&bz*3E6LuZcpOsL~>6?V$$k%<5SYnk6uS)%UhT1E3@qD`lC zz)gXMu3s^uom`5ipvd(_7L^_E{V!=d7e5ovRQU~uZ*j=Q1C%%ivJ|9EWN@pqV(4f0 zTvOby8TM?7>uC-E>_I=FQd`+CMNqb{O%=Czr_)xU93*`j^&UV#L|sd@Wip*k^{xt| zZyVAfVq$?dnAL22L!g z-?LL(^oJ&){3B@#0BGHIHRlpJbqRCH*D*H{r{q{4~ z{fj~dpp1DWsLC<%=+K8W;ne^2eJ&&cZFiOe(dk{_Q~%&zmgDRdsukt0YU;BaS&ZJah!RD4fxUFZ+X0icyNuN2 z7ltHv++({BD#_~?m8@OjYMbFzvId1h?#rFtW(L0y;FMHXxVSI9(&w=&3W>Vo9Csh+nW^M~w*am}59-DGSMRQ?f5nF9S>w1Yh^i(6!LqFdjp1vFaogmdKWiP*YLq?z&bmB4qU^Ia2vh0|^(VTH< z4JSolK}KMLec9$YbFG*5oHSZTB&0w=3K8{7a;^Ee?ikSXO>n>3VQO4yN~*LKm@X;G zl^K_+bX{WyKRD1xyzG2nWX-H5$9}(vCod6eG*@}f)dJ#q%m}e1*A(bWV-eZZa{w-F z)=6!;w;a}@M%l?PY%6DlSc`jj#Ub_d735B2APi^lo_Tqg-44?pjjxT*G1FE4)nbz} zdz%%bJA249+P@HQrcm!{GLKvQ_`;GVYYad>{85CJar;+$zPFw`d@rlN!tgDXnY)CIrrTckO_4>{$-AKD3?{)?IpLlx3I%@Ykr(ptx?-@iCWy(c=Hr2$sWIggqFKq%MjttqI9@2cq> zUQvZI+UG&0kS$@i@f%{x6}6VltY5-5Ac+hapY#c}-xhI#;55#|9L&c|slJTtdjDoC zZ5k6=X7!q2t9u)Z&LqqNU zO_{t_QyYNC-xbCIBkJ&=<+02$=taM-utK#V!BG;(4DS99l9xV04Nbm zE>q2H-Sr>|<9|zwN(ncsZW|1^nRgWgznSL;I_NKb9lBvVc`?}Z!O_<7l->p;0N95Z zn6_wyl^y0s^Lr1PklebFHjwU&kFemV84#R<03OIW2bMJb(B5&@5Te!Sp`Q|03jkq^ z3T=+;)aMLw6h5hWanHT!`b;2-NTCr~lQz`u;U=>k7-Hhn+ucidBMi~~VpYwXrbOCA zcuU62T5f6F^@hz-b?Y7+{Ya40!>qqvWK2E)41hgIy#L~Uj7hsVD!<$3)2{FuZVRX` z#j-Zh;ap1)alD^UfW{wP`mVJoC7cg zqoJj`V#VZLuRMtxp8KudYw_y8W+O-}4}NXICq1=_S8K)Y|Zn%Y6SVLMfH)5-p%5&VQ$%+b%w2!Yu z2iza(SIj2O&0Q$+x+Khst$5lwk3tP^LDSc@6ikUZG5+OzA_mp@3#J9^Nj85viE-VvA8!zqC2%O_u;{6Yn5?JHs@Mxc;H$YD0~h#e8fmW|4eq_{Wl5y zW(MjGmNcZ0cJ%EZU*Q(~hY8y)B5ONc&4cu}r)zxFkd*>xM~Y7~Rq(p`Qc zSAO3HW^u<6rvs(kN>!0x5F#4hP-2f(o7wp}rxo2iDMDjej zmUw*-&eUw00`rdhlwnNI#+o~uOjB<(-4$AqbXryaKRs?^+79FL4tt;-j-!%rc2HZ$D~Y`(NA;U-zF2%}byhfucK&@^ zZRJ@*Sx!n?GQ+D^xGVk~di^=GEf9<|(w#{kPLthu%<%nFk~fiS(T6CoQ{TzekJy>< zW;2T@t~a#8l`=^ zzH?DYv`Sg+BR@YlQOG0N)R@opT_I|eR5c%zI+8zQ8S>~PQ;znfiz0}ASPTuA3iuMD z(?!9wRTjzWM#<3_`-&_(t5KlTvv~=_dj29~vl=bnQ%Yo5=jU|i*T{iUCgc6dT~PC@cM%ngcY`H=i1v5 zVU%jU*2zcDZI^xKMBZ9D4m(wB3L~cqTiLl(s`Yf2>2P<{O$7F4*(8HtM|E zMZDIO?u03&#Y+s{_QY-4iNJIwa2p1yev8KsNIr8d>n%C)8|x!52*WU&Qmy7*dB32DT|U>#k#m~I(byA9Sjjsuv=5Xw1I zi)0=C-P_e!jJ#0x=T(Xot%P6~_xt?$1eHqB;nvC1ILJPyDg`=@#moRSL4jgRNSX-? z0CKrQ_wSxx{|Hn!cGr=y1Pm#Y!zmbM~3e?o3V2MMW-_8d`JfqJvN}ndUU!C~! zR`xWm`${be^X=1a^OwEvOvEbglO4n9{_%5}_jO;KrlvpqTmy)G{%xs;yLWuH(B(y+ zU8LJ3MdSD;f|~OV0Pv92IIii*g8%?vK^57wHovN8TfUII3YAYgD0>+F4>C3vyaab2 z+IQ9EGq5!!)%6C^@#zutEL!4TPTAb8a74;$VLta+^!ioS&xqydI_J8DfdFP$e4KXw zQbTy#JWqKF*M8?91_7LFGt)!v4OC}PD03#ywyv9@qVf6rMq035>$CRYrOs)}!nyp5 zi2;Asbl8PIX>I!%q|cNYFoUEOtDM=F_2XpGvWEpx5e11}&BjQFG6gE%>~-JBr~0P` zF&tP!=2uEm=jyU`<Y`7m>W}uF$S15m6&|{kx4S%8EX8pE6yD()^66reRKMo_it+<< ze>ycFha~`}?+}N+B3?0Qx{R@#u=@ zalIG?7PavUKkEs7!bkbkL$Xa>QMJ(FMyD(~{du;X_3F~xt~bhY)3|fgj9*$s=~8#8 z1HXKBkY9UH{BXiQD2S$bRww)P@ABda_7H@Pb@>Dh)?Amc2`$GGgI~QYxXqojxxcmi zT^#tVmpc-H0D79doS$+nHl%LDB`;t0iO<^QzaJFAbCKL@i5ER=S-DTGV-p?Qxp1fO z3bu^M#Z^bhQ;?JIK0f4fMsobi&K49R{PdDR0S)*Jnc0gU#$QVcgQ@j=i z7c=RQBh?3~_h|W}Dow>F+-kn^@I>?uZ)Sgod9{P6V!5YHg$pGHr~m=rJe*}!&CG|Z z-?!vi+VE6+oaXnR2@;q911mP*WhPUVm0&PT_vaY00dzbZeGj1|foDth)w+c`d z7iwl|bs5!Z#cBGVlg8>Rv#s&*A6xdNi9{1hz(1se(twGC#owUJCP3Xn7KUe&Dcgs? z>sIYjVaihA=jugWiEgaDTPBCG7zYAt0K}jWQ(;_5_KJN36{m#&cZ^B z2NM(rJ@_V30}GMh_kU~=me3RC;vD+>kJ#DG&aO={c^ns)k(orDyE^vfN z(gnYmup*NYrc1(3CX{ZH9sDkBh5wBJ0CupiajzZm(K0m8tWS@Pz2=l}i*^Zp+PaVk>LkSg$-H_R23lWw0$rtydRn`75_8J@E|0BIQXI!S$KtZXn=wM@6ZGBsHMFn zg0VodQ`}%*HQ&;1oP4|fw5oeAZ9~j+W*5u1#E2Bp3*(@V5=_QbNdq&#Ge_nx56{df_gnSkKOr?c5h zC%Q~Lr_oG z8$stZ2hXB_!=S(+K>>!)hc;MrEei`BkdL7U4G{PUiUNW`M+M4J0d2l!8pWd1t!2va z1@HqD0AeUx!UpA_K>C_#xsYtN>7x|Xe0nEUmgHERbSit;kSDz1`@mc`Th~s#}vhtMc@2Y)r?W~NUZAVX* zP}6#qzBA5pBv+tEd+3AXw(P@HcEtWc$)04=Uqh$Ainf3vn6k#?_Ej%N`t;FefXKrk zoaQVZG;qxI>!lHXvaMJ}_OA^+Te5uUrYarDt+=*Tp8kLZ2sJLsiH@TdXl+nTj(g2E$dm8)u4W(bKithDuxu8j7-H2gDyq z662tUtvG}oNQXP7vlKW5ChyENM)uY0sgwBO&Vk_{OWTHsR%7uuW@h{?Jc2q=%o*C# zb#rs+>0R4%rjpAL!yS7@bKcaY#z*_+&ZV;H_g(1jw2GKR+mlbrF8ozw`YU#QT_}JB z?hrc^_l-C5PP#iX!AHDvi2JCcH>zIwOFhvJDc-`F&{Ct%vUGh>81%A7QlRY7AKJhZ zD8^s}!IF3(|3p#NW3IQn4PS$v7N6>y_MxaxBPHH~RLp=DvcN|lIN}5C9qu6!S6G^A zPl*CrVBkbIV}edmN&-hQLkuZRP(Uc^tKSc;<0?TB@(jO0#Y$x%u3UM@Q_PyeeD-V; zm5L;S){0heQA}A{4jY>JVnfM-?vDBll1Z=#g+w$G3N#|7`To<&iU~wh^F{GA_)yJM zIsgSIp#--vAB!hJJvNjp@4kMGlp{dG_niN`o$ zX*$3)K)2}4^`ki{R4oYP;{pb#1S}#PbM`vsJn#{5O?VZ5J=Ln%7?6~#Q{{^S2`NL(h2GMTD9Dj>q^W}H5M`!;0Xk>|P4X~$T$(B@2|GCQ zbv{hz0zfp*;RUu~B#c1-ScN0Fj96TNIY*>)!eOvts;i+ZtCpe163u?>SKc#8SGo^V z;PI#QkQMUj+14d%tsF1zKk@jc^bSY>4?4g7WNG!2LVdHG0F z(AFC2N*AYFFJ_w7KW42sUAGay9&-e!d?M490$71#%xClcR%fTEy%RsQD&6;+excus zhp59soRzzvv)ebQTaAsnetsJxRV}4Y>J&b^q`&AVG+;g)f06CzLOe;=1b`g>N=dTE2|fwwFQ#_`1i%BfgbC@$BgAU3gdH5Ai!UYSDYW7a z_QMG0V2ABmA9QahhywHU+pTpu#wBWnx1*`!lqk zUwHfUk+>3*h+O418NaO@fE(tryhnH2-`@Bt^!&VqVe|OOvo|kAg7`db(c zfI_Iiu!K`G`hkVrVl%tIO3nOXMhIB)qgUJ6n<4XXQL>_A48zWNh-{&D)Xrk1*;_Y>z9pAOqHb@>13u z^IZ-Vs&sc~a|JpArS=&ib@jdKHWmOMa2F?FiwPJ3Yta8i=k->2@!(uS?w)i1LdCTT z;kbJQ4D`Lz#zo?XEPtHsjGPkCu47GfO$n`OkcAqK*4I>-;|a z4YMr(tie06ciz?WTI(jSTj^7v7W(GSBU2HOfmcd?BT)b3EXCgg%~uoCcX-%M?a_12 z2{Ns}FzokN{7;aAQ2;2!b9P$)(rl97ZQw1JS5F~tzmC@b^@4H9=-TiYQtuIxsR za;1&LB2_*+vOTbZ5;emNLD&r97gvTq2`orhO2dNtRv9Nhc6xbOdSpDFX4hgbVaEr_^49`Y;pMo)a`&CAVSQpV}e{1-OBHEQUXpF(Tx0n2q+0 z@}=xXe*-61nW#Ztl~ATpgrq6nH&%nPhbOEEy*j;otuGRAo<}3+hx->3^Y@Fy?HGX1 zZkR-sPN7W(Qc#E{=A)td))YYrg;j*E3Zoz|`JH~74ozFODDUT%IaE*K6iGbJpc-q@ z=T9Cc3ITA%PWo=k4SmFcuM1p50+I^^YD9vi%gS@L#b*QSZsRT(FjbFQtkbhqoRoU$ zr@JM$Fy&8e)xW~uG}{8e1>|9O>6IPw5hm+~EpO#*Pdh;wI8GcB`>-gdfYQefyuniB z$(&P$727qs4Ow>d>CgF52in$CL;vA`^p8asL2d(hE*0@esK3_$=s!l&INc#rNe{@> zP9-VEe*2WM01Y(IK$KDm?Hr0hM~8}%3WAtSn~6%76nHX4C;X^cRMrPwF5$|k%N<^m%s|p^U3d;=>&4d5% zcE|fVq@f)r&<<}nVi*E2llhJo0&^lpqe(X(xyVBUTA`xUdx}^?hv*Q&6M;@=c%ey< zPmvUuU;zk0y|gCeL#8IIU;Y-~#2pY*>nL4Bd!s z${AKZQ_On5y&-%eEiRS{p#%|Dp&zCyq|I96U3SDRbv9GeVe&d_^|oEtqn)G)*z~tj z=Wkvl0Kf=n(LShOn^NxPV5HhsHQ%o4CQ`7}EO`R2!tRMB_aZoQKFe&~e%!Lxmb2(J zkNq+>czfecOoPc^-qu7^A|7v%050-~*9b#LIBySPEt8;jOX|m|et&OKih|_tC(YluNa#W^K%(L5m5m~)L2}U> zr6PvBl&{zpIMky#?KpoINJe`%cXvT(S*~31ii|B|h=Fo?)1tR!Xf&R~{BM5l7C;l- zG2lDf>h<|Q<$v%%d`Ce9h){$qq#zaJX#@$0tH4*R4P$s=D7+zu0oVy34|(_r01$_` zZ>;~XfSHNbYZQ>Wb{24K>^_Y#Mii2`W2p~?BmdJ6 z`(I!VBW%#yD`&jE`Ul^M@V}6@^LxGDA7Rw{tFNc96gik|S+ZL8DEpF^Uw7q27=elA z^$%LF7U>=az{F7Hf~{?@5(B1a)r?8HpM7eWJ@1?6^ZzrTunsfX6+=@Ww#2@e`$&b2 z>sZ%I5Lw%gqW|(nj>UaY*sh&DH#)2E)#HV`{7X4K@O9cJDhfZX5S}tp{;G?A2crH$ z+8%M`hn<>k$2|2F*HXBNWb{?Z>Q{X7?d_sj$8FFVf}Y4o9KnB=I$;|#2*3hRdZI1j zGtD=o4|vlq{c%AOe-QrU2+MB+fvM;wGJJV$ZF}&5S=I|=%9Qb(SrHk>5+VBp;55$S z9Q-f_7qO*|pJ`c5Z!s9Q;K)rpR z&R1Tp$nG1w%WS1m-Sh3{*BQCHZ~_2OB=veh#F+J;tV2Kw4v41m9HwKPY2nSiw>1l2 z|AqJSHTbupE#QEq*ecywP;&jr&rNQR*ZA%+b>KX$;Sq2H8wxrsdzk`2U@oSrv<^_M zj9jg_G4Vye2_Xk7r+R6CwTGav>z|bU3>=m$&_*dM>(37y`R;sH-+?+&_#HE&gr1r7 zfBx8>KwtDEX44nyi#J;SR2TH-LCNU@IU}Sq;De8#08D_pIP5OVJl>zfC}nE8J>Ow8 zx8`O1{JGD2ONRe#wvPWWP;lq0^vrr7;U>I}wY|bPgcX>tR=hrEZAVU84I;xoH*DTm z3L;Ea$o09msrtF_Lfg^j9yKbCv}nxi+^c_yMDWxEcZ7$J{{>TF`d_$60HW1ef){T& zpzv#Q8We6I5EM+9S4?(JZhe&hGV+=ryl|W*tz*Utp+C~Nq0o`Ec_T->nSVdtA!?}b zb;^?y!_&1W9Q$i-;T!P{X(j$jj6;?5WXv2IHCtB9r#|KpoYXvPH0U=P&Q8a{N1zvrz4&cXK~ zc7}DMth1k20zf|n;W(k|%d8y9FkF;&li3Y5@YEh4d7pM}N%VlW*}wAm|2yE{z;63% zZ~)*-Hh-dJoqalQtic?I0gs~6yscl~O!B38cuY*R?$!OkMV)HE89+2Sns3FQRy`(u za__NI^-mRqB){67ST#6=ihyvT7lv(ZN$*F(4<9D^}>%jU;t(%HuuW|*chDHB^ zbDhf{3U!!|0a$=&trnAuc8tKqhBsfSgcF%r5PFZW=5ZcXg=9(2wd+{9t!y9e@b zocmw)00Ll^FOc1Axhi@Vd8BYD*B)#N1F!+LIE*kY$+e38`M*=F>FZFbK>dY_ga%YA z*6k(Fyy<**3b7sIL1DdSWnk4AUUcKBCo8u*q%tVH0zhFN$|poTJJr2oXER;%-66^4 z`(Cg6ib8nL#H*fbUqbR<)9~-czv*n-1vU0uTT*jOomGd&`val!f;Vd+zT&xVbmGd-2=c%9KyB4aWpa@JX+S%i}vA_`kDB zUxmN+B#Fc@{=(MJw`%ByZ?f5sREzpsv#jJhvWzQJxe%ihY zzE2Xf^@?Igy_-V4Z|= zlEI(y19J!dZXvgSKWJklsacRHw|ThHiA~a;CS`r@dgg28%3I}A5fV>E{F=Jq0JZ>F z4LTCwji{>p2%~A7jFOPe(kK&Mdof{Llzj78+|Akn82oqN&R5{yp0*t*!U2kzqh6R3 zivGsky>+y_qTq`S>{<#7kVjYyh)36HT*&sAJ^&((vl*BL{5OD8O2{ ze}6N+0#$$6+BO_LuowBXP^U+G1ugY&${wa}xalzO9uzIto(yk~On>-nL!Ots{GZ>_KN9~Tvuy`1;v&4nrfJW2^mNbcb7!ks?tG;r zUgX)*+7tlqb)2b1A} zX7rc6kM9*E8K{(kI$%D+nw%TvkDQ*`Uo^(*=x~|Ft0L|F3-ijj({biM%CqY~inaid zh=-7`SrXbWR_3WS*3Xy!u}sBY=}N0LGb7MSFJ!-wXbylLC?xV39Eld_01l(UtIm=W z68LUEn~{wzkM_i2!9xz~DbjzUj|Ae0++5C`TrI*r1Qlk=QZ( zHU^LacFW5r%w#`D;rLnun|wLU03Q#r4M0Ra_nq$a6|M&&K-uA1{jgWfGZn^m*PYp& z*A~dJW2G%h`rncinq9ItDPCuC&+`=sjn)m^Xri z)Ev`cj8gmn#oyU6^$MB~kbpge_;(fa859V-!$)}F1nmLih(>oU>0l2%z7j+2W_)hr z&@}Jdo&0^`RyWpe>du9m%Vn3rqe=7{1wS?|gHY?-{`!U^yA4}wm_BMU2l-_K9pqCh zo;ALzuN@?Hh7Ioj-2?i~_>Y@y0iYLvT^LFlHlBNBn)KLz{t(6eDh8xN`qM~8f#@K{ zqL!^S-Ndot#bW?~(6C+GH>09WAG6SlWC^m$ax40ToxVTe$C=|Lsk{-TnR{cpOXAYk zG*(f`jlq%z?1e2>V9vim_r#+S7vOyEY#ApVrDOYSu z_NH{u4W9WAK5F!R9flfBa5-3OU72$9mKgQtgDn?q_1&K_zjyrzXZ_}wsk`TwxisCD zjzI#v{v&6uzkgi56Pp111dx52+ny!8%MDsOQf6X1WU-dy+)k70FaCM-3lV&Cz?g?4c63D+SIF6FTHpN%ZFhdAub2iR*_S&fIKMk z#5kB^)Za3+&ryU}3`IQw23t{Lxz#eYyPhgTt-F$<-i~WVS8i9TQ#A;}3m9S^r1%8z zO-dSE1N7Z%hGM%^Cw;=mozG5YTEQ_sZ8)*2f0LTFPWyqgfp5#osxTNw@W)95{(pQ2 z9>EIF)i>Lw=9P-FCxzQ< zxk|tMvb%~JqY40! zYtweCZtYw-3cyv9xCgJ+uG9{3sGQ6Xu6^ISe?+&V`oOcld$|4p{Kw9=Ut$y*kkzEv zq>%F})OTQ+k7tmlCR@-2lT8omJB%Y<3e{#j8bM+5Xi}>#l ziXWfuUKJnmEU7D5D@_iP(rGK4MPD*_kEhL*vx$AjQ_&u3j;tkE51~!SI3! zpX5~81WRW2YJH(hss=8E5Y(fl%XzmNXP^mHsG|{L*)uX(_EvTrBv@c}8pNa!qZtPH zC81}wnNWd8G@_CME#3bomlJd`B^FBv*i{j^`Q8={BG0JNQG)i-%@c&mn23uw0$*ZU zx=eOa?HBJh2M-lZag?ffC3=hEGTjDQnt$LjG*gC)2R2h#aC@4O+C62fpdT*b(%(H$ ze-QplXbS+20DN&-ax&X4+e7J%d5cNb;IrE_+L)@6=1S=)WMP9mX9%-uTGyScYTQMRgmjnOx04MmT!BS zyD}LZg3VxNARe?Xdsk-`9vR-pD?94z`5G)~lXYe0A-XQ1s9&sOgjJBKc5m7Ox`@_R z6jL59GodV@->e%3aUJob>6v>UUqrJCY~T$WQ~&@}v5#u0J^6ZFw<+%ibf|OTeX`fI z1Y3OUPd=f!XFaT>EgH@5qs1)Ge6JF*ASJgZA9JzoKXU8!&+uPF+YZbEg`Y8yCzooS zvF?M9<8vFU{?6(fHr=?dTgWEmOhO}z(H+rPY~g7wyuF2=g_BBGda;`j0|+>~)b2h( zdmfH~!jIsAg)FgBMnRi-Nk)AA>(UqZQ3xfvn?aj-EfKF|Gs#->22HOwO=~Er0!=Ii z19XBxGVCEIuMagdc^L^1AUY{S(VziUlt2Q+p#o%#@MjL$sA@E65L$jJ&)F`p!en%p z2DJhVs9}%x{6&UF(fQH14xm+uU@@9Ow&0au7|&|Jwx1eA!8nT#SpCXvc({{uv7Xse zulOKBjo_rbM~>yEQ_aFwCvpaMU?%=LrSHE2|8=zOGDWLlw(M=yzG{Q0Q+F$DeELsZ zOA(v~sa9#^FvZ3EaK;`lR=G(@H!>3f*li)D?Tutx!u>iVa~0qS==eVGM!C65$YVhA9GDx{zwK|R?l?`Av^mm9uLJf{P}Ub9c9agw{c7nVE_fB!36*?ho;Oa`aD9Rj+6!e zG1~Xx0NFEJJg~Q?W`rN{kya?Tgu!W8-Jjtys3%dDo0$_cG&QPet&oyg!4Cs~|3c@X z|3cb!;0FNZh@$QY<%Clk(o#~Myfs}hiOHX`mtS!1nOw7c&xq`8m9bEwMHt$ZHO2tI zDfy}VzOC8RJrJ18iO`Vef_D*ROi=)#^q_q`fFzm%n<=T6{y@f}L7AZ-EZN69EiMDI zQ~j$08aN{FCPXXBlq6ra$%%QPQ6^kczPJ|Pp#f|dp#nomeTczDFbHf!H=JO)N;{Yy z*rL>!X3&EbB?f>+irGV=3f{#pM}lltGL1X6hjyleWw4yW5G5NKo!Po7%JT7$>bkP4 z;xRH+Ohg2>|5q&xzQlhmZ2`at9jnU4q%JS?LwRy#=u2I#VPnlFZ*MM_n3*fy_asV2 z@#_b9vQJel#USMPWu+>oDUt*L1JC^7X*ZEF2s)6;xXlL;1Rz68eS}iHaoQLPkhpv@ zwfHGhyahl7HbWKWpEp|<2?Bru@sG4ICkO&y5X<3>Ng!|l_uz{@(1#2iZwUff8hw1; zze5`Ua55A=a0btP9#sbbB7vQXgVFq?Pcjout9EgvjxVLJ;kqnaKKEWp(bL}5)%-Hb zj#8zZ5s4X?|A(b``gg>CHEn?oGMvU~fXbHD@#=W0hZ9sHtS%}(?qg?P_oGCx=8c0> zdo8pRWv;}M?kB3xh)B%GPw=v8cindjNF~g4^f{}4-bw+$6RoK;!As464B#{5XiTwg zXFYC&xq>}~U&$D}7A!EZ^@|pr03cx=wN|O}Yz7>JS|vjJ&4xQm0FqF!(3@~CvxByy zs9e&M(}T!^1*U_ZnNw`q|Foo({j$6tZRJ({?Lf!bmMMIZ>on=Wkh5J0<9QZO_*+B9< zG6=%i*e!p*2?YSb)JamE+5!M*gc8w*=rTiHl;e&`75|!Ya)S!XfLV>^uFoAS-7xmz z#m&*DA3_YCdUQ^Zz6VNx0?M{PBDU@sR&oz7;Dw(n=2_-Znd*ABAgXlb9GOZ*stjef zSn-=DHLqX!w9_Os5SaRRckN$}|3kFxLWef)A_={P^*|oW6)PXwDev*FS8OtsSGMVX zNGuR?Bt$vOnORTLDwG%Sek23vR#Xa%kO_hwoaI_>M*^48CNU5Mh`VUpjaA+!p8spK zU0_F_PhCCnu4}W{k%1(Hx@P>$F)4%+6QHE3gcE%$dZHBaf@a0GZf%c0%2iX1`lHNr z%rur9mGQf`h)N2K<5`s#J{I!q3b(c~VGC2FBDGVV+>j6B02VC38w0M}t zS1<P(Ww94RbdjHtkd{mBr-S(^PzIE_LJrCYF9+7LK5v;jO%do=t*& z$rnY+=${YAzVx^CP=Xbd0TOhIB0-VVbY#GhBxFU>$K-0rK$5!9B_}iey(H=@ax5gyEaSneuOk=nu@S(y8Gci`WO|Fg91K!=Png~!qZ zQr%*r7|>*_k9tBMrX1v2pbWdifL$F z3u_od832uxM=F}o1OW({nA%OIVh&mW8N`qogJ8ebDOV%e{q;z?l*pD7%8gXv`rGvd zlV$*0%q(ydI=O201tE)xAjDQxh7zZbr^^ohIoFk*rK?QzU*l z)`>0$7RBUOH82fX70dvpA)BJ8HWsNj#fcbOD`U!{oVsh=_XE4k!N0H2Ku-Ps1%`wK zN#~fGlgs!LU4j8wQB)SGQmhpsN2x;8KCJ{&P_uDK^aDjg4L_n6_ToASy!^Yn>fZ$a zt%kkd2@3fL#u?}!1lj-yVwI9NdmMm5%lvK`a>+6qrL9vW1|k8yBY%UCD56}2HFA8J z5k&zc!B!GT&j>&fa4na<+*Hh!S+g|dm7xRsz gF*-9fIyE;fFf=+aFfEa#JOBUy07*qoM6N<$f|P6<1poj5 literal 0 HcmV?d00001 diff --git a/images/KEC_Light_BK.png b/images/KEC_Light_BK.png new file mode 100644 index 0000000000000000000000000000000000000000..55347578b9e32bdaa12afbb16c222d237626b27f GIT binary patch literal 94162 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

F^5awxEL{~9|MqSLI0pjEqktX8t9Q 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

ktbezL&OQL;W{_F46_@@I|DPJKQ#2VB@d zaD;bfaf78Ej^S%XAg&tqwwVs59aaXr4F$IO&td5DE9{@_1`xP3Pi}06kd@p1CRqR= z&|eTf3EwcYVR|>Ki|~tbN_0C$a7RfvJhM#1kmlG_&;%}@jzfciccq8)q^MR<(kb(j zX#_rGdOQUH8_vXgbmbZXz)@;Kt4cLtHO`@=;0M7d8!dgEO7O$rCw`B&dJ+~>F};^2 zw-~OSq8sqFnxq=vXXQ!2M6usLYoZNL!QN?6ksa10%>bq@pzUiFoV;VZ14U zEg6#xO8;m{@$7^s0JMD<0fj0eRQ!aRj6r<}P#k%jLRbg;hEkdL93=YUYAy_?JZ2#( z@5gT2Dxr^De2p%O1~exu8t92XgPPG6SyRNFwmv6wOu5sstIgEPSIBqVs7oME>r# zv7Kzm81$KH9?#9}3t@ow~0dc#JAAVxp|8Zd$-Y>@>_6E63e zvLj|k%8vOfQk71#r{PCFO_@#La_!hL7=itCug~UB=?{Y*dUvT1Xp)?^iEHxLFoXu+-T+m}+mI1^B=fNN`=*yn)_mpF++m�PxL~+g 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 literal 0 HcmV?d00001 diff --git a/images/KEC_Light_BK_Small.png b/images/KEC_Light_BK_Small.png new file mode 100644 index 0000000000000000000000000000000000000000..49459e5762e6ea57b4a988b73cc5b069f317149a GIT binary patch literal 96313 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

GAmR{h0)4njJ1_bcE?_3()F;wqDy&<=jYY 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 literal 0 HcmV?d00001 diff --git a/init.el b/init.el new file mode 100644 index 0000000..6595ab7 --- /dev/null +++ b/init.el @@ -0,0 +1,232 @@ +;;; init.el --- -*- lexical-binding: t -*- +;; +;; Filename: init.el +;; Description: Initialize M-EMACS +;; Author: Mingde (Matthew) Zeng +;; Copyright (C) 2019 Mingde (Matthew) Zeng +;; Created: Thu Mar 14 10:15:28 2019 (-0400) +;; Version: 2.0.0 +;; Last-Updated: Sat Dec 28 18:41:54 2019 (+0100) +;; By: Mikaël Capelle +;; URL: https://github.com/MatthewZMD/.emacs.d +;; Keywords: M-EMACS .emacs.d init +;; Compatibility: emacs-version >= 26.1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; This is the init.el file for M-EMACS +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or (at +;; your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +;; CheckVer +(cond ((version< emacs-version "26.1") + (warn "M-EMACS requires Emacs 26.1 and above!")) + ((let* ((early-init-f (expand-file-name "early-init.el" user-emacs-directory)) + (early-init-do-not-edit-d (expand-file-name "early-init-do-not-edit/" user-emacs-directory)) + (early-init-do-not-edit-f (expand-file-name "early-init.el" early-init-do-not-edit-d))) + (and (version< emacs-version "27") + (or (not (file-exists-p early-init-do-not-edit-f)) + (file-newer-than-file-p early-init-f early-init-do-not-edit-f))) + (make-directory early-init-do-not-edit-d t) + (copy-file early-init-f early-init-do-not-edit-f t t t t) + (add-to-list 'load-path early-init-do-not-edit-d) + (require 'early-init)))) +;; -CheckVer + +;; BetterGC +(defvar better-gc-cons-threshold 67108864 ; 64mb + "The default value to use for `gc-cons-threshold'. + +If you experience freezing, decrease this. If you experience stuttering, +increase this.") + +(add-hook 'emacs-startup-hook + (lambda () + (setq gc-cons-threshold better-gc-cons-threshold) + (setq file-name-handler-alist file-name-handler-alist-original) + (makunbound 'file-name-handler-alist-original))) +;; -BetterGC + +;; AutoGC +(add-hook 'emacs-startup-hook + (lambda () + (if (boundp 'after-focus-change-function) + (add-function :after after-focus-change-function + (lambda () + (unless (frame-focus-state) + (garbage-collect)))) + (add-hook 'after-focus-change-function 'garbage-collect)) + ;; -AutoGC MinibufferGC + (defun gc-minibuffer-setup-hook () + (setq gc-cons-threshold (* better-gc-cons-threshold 2))) + + (defun gc-minibuffer-exit-hook () + (garbage-collect) + (setq gc-cons-threshold better-gc-cons-threshold)) + + (add-hook 'minibuffer-setup-hook #'gc-minibuffer-setup-hook) + (add-hook 'minibuffer-exit-hook #'gc-minibuffer-exit-hook))) +;; -MinibufferGC + +;; LoadPath +(defun update-to-load-path (folder) + "Update FOLDER and its subdirectories to `load-path'." + (let ((base folder)) + (unless (member base load-path) + (add-to-list 'load-path base)) + (dolist (f (directory-files base)) + (let ((name (concat base "/" f))) + (when (and (file-directory-p name) + (not (equal f "..")) + (not (equal f "."))) + (unless (member base load-path) + (add-to-list 'load-path name))))))) + +(update-to-load-path (expand-file-name "elisp" user-emacs-directory)) +(update-to-load-path (expand-file-name "one-file-mode" user-emacs-directory)) +;; -LoadPath + +;; Constants + +(require 'init-const) + +;; Packages + +;; Package Management +(require 'init-package) + +;; Global Functionalities +(require 'init-global-config) + +(require 'init-func) + +(require 'init-search) + +(require 'init-crux) + +(require 'init-avy) + +(require 'init-winner) + +(require 'init-which-key) + +(require 'init-popup-kill-ring) + +(require 'init-undo-tree) + +(require 'init-discover-my-major) + +(require 'init-ace-window) + +(require 'init-shell) + +(require 'init-dired) + +;; User Interface Enhancements +(require 'init-ui-config) + +(require 'init-all-the-icons) + +(require 'init-theme) + +(require 'init-dashboard) + +(require 'init-fonts) + +(require 'init-scroll) + +;; General Programming +(require 'init-magit) + +(require 'init-projectile) + +(require 'init-treemacs) + +(require 'init-yasnippet) + +(require 'init-flycheck) + +(require 'init-dumb-jump) + +(require 'init-parens) + +(require 'init-indent) + +(require 'init-quickrun) + +(require 'init-format) + +(require 'init-comment) + +(require 'init-edit) + +(require 'init-header) + +(require 'init-ein) + +;; (require 'init-lsp) + +(require 'init-company) + +;; Programming + +(require 'init-java) + +(require 'init-cc) + +(require 'init-python) + +(require 'init-latex) + +(require 'init-ess) + +;; Web Development +(require 'init-webdev) + +;; Miscellaneous +(require 'init-org) + +(require 'init-eaf) + +(require 'init-erc) + +(require 'init-eww) + +;; (require 'init-mu4e) + +(require 'init-tramp) + +(require 'init-pdf) + +(require 'init-leetcode) + +(require 'init-pyim) + +(require 'init-epaint) + +(require 'init-games) + +(require 'init-zone) + +(provide 'init) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; init.el ends here diff --git a/one-file-mode/bind-key.el b/one-file-mode/bind-key.el new file mode 100644 index 0000000..995e481 --- /dev/null +++ b/one-file-mode/bind-key.el @@ -0,0 +1,413 @@ +;;; bind-key.el --- A simple way to manage personal keybindings + +;; Copyright (c) 2012-2015 john wiegley + +;; Author: John Wiegley +;; Maintainer: John Wiegley +;; Created: 16 Jun 2012 +;; Version: 1.0 +;; Keywords: keys keybinding config dotemacs +;; URL: https://github.com/jwiegley/use-package + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the gnu general public license as +;; published by the free software foundation; either version 2, or (at +;; your option) any later version. + +;; This program is distributed in the hope that it will be useful, but +;; without any warranty; without even the implied warranty of +;; merchantability or fitness for a particular purpose. see the gnu +;; general public license for more details. + +;; You should have received a copy of the gnu general public license +;; along with gnu emacs; see the file copying. if not, write to the +;; free software foundation, inc., 59 temple place - suite 330, +;; boston, ma 02111-1307, usa. + +;;; Commentary: + +;; If you have lots of keybindings set in your .emacs file, it can be hard to +;; know which ones you haven't set yet, and which may now be overriding some +;; new default in a new emacs version. This module aims to solve that +;; problem. +;; +;; Bind keys as follows in your .emacs: +;; +;; (require 'bind-key) +;; +;; (bind-key "C-c x" 'my-ctrl-c-x-command) +;; +;; If you want the keybinding to override all minor modes that may also bind +;; the same key, use the `bind-key*' form: +;; +;; (bind-key* "" 'other-window) +;; +;; If you want to rebind a key only in a particular keymap, use: +;; +;; (bind-key "C-c x" 'my-ctrl-c-x-command some-other-mode-map) +;; +;; To unbind a key within a keymap (for example, to stop your favorite major +;; mode from changing a binding that you don't want to override everywhere), +;; use `unbind-key': +;; +;; (unbind-key "C-c x" some-other-mode-map) +;; +;; To bind multiple keys at once, or set up a prefix map, a `bind-keys' macro +;; is provided. It accepts keyword arguments, please see its documentation +;; for a detailed description. +;; +;; To add keys into a specific map, use :map argument +;; +;; (bind-keys :map dired-mode-map +;; ("o" . dired-omit-mode) +;; ("a" . some-custom-dired-function)) +;; +;; To set up a prefix map, use `:prefix-map' and `:prefix' arguments (both are +;; required) +;; +;; (bind-keys :prefix-map my-customize-prefix-map +;; :prefix "C-c c" +;; ("f" . customize-face) +;; ("v" . customize-variable)) +;; +;; You can combine all the keywords together. Additionally, +;; `:prefix-docstring' can be specified to set documentation of created +;; `:prefix-map' variable. +;; +;; To bind multiple keys in a `bind-key*' way (to be sure that your bindings +;; will not be overridden by other modes), you may use `bind-keys*' macro: +;; +;; (bind-keys* +;; ("C-o" . other-window) +;; ("C-M-n" . forward-page) +;; ("C-M-p" . backward-page)) +;; +;; After Emacs loads, you can see a summary of all your personal keybindings +;; currently in effect with this command: +;; +;; M-x describe-personal-keybindings +;; +;; This display will tell you if you've overriden a default keybinding, and +;; what the default was. Also, it will tell you if the key was rebound after +;; your binding it with `bind-key', and what it was rebound it to. + +(require 'cl-lib) +(require 'easy-mmode) + +(defgroup bind-key nil + "A simple way to manage personal keybindings" + :group 'emacs) + +(defcustom bind-key-column-widths '(18 . 40) + "Width of columns in `describe-personal-keybindings'." + :type '(cons integer integer) + :group 'bind-key) + +(defcustom bind-key-segregation-regexp + "\\`\\(\\(C-[chx] \\|M-[gso] \\)\\([CM]-\\)?\\|.+-\\)" + "Regular expression used to divide key sets in the output from +\\[describe-personal-keybindings]." + :type 'regexp + :group 'bind-key) + +(defcustom bind-key-describe-special-forms nil + "If non-nil, extract docstrings from lambdas, closures and keymaps if possible." + :type 'boolean + :group 'bind-key) + +;; Create override-global-mode to force key remappings + +(defvar override-global-map (make-keymap) + "override-global-mode keymap") + +(define-minor-mode override-global-mode + "A minor mode so that keymap settings override other modes." + t "") + +;; the keymaps in `emulation-mode-map-alists' take precedence over +;; `minor-mode-map-alist' +(add-to-list 'emulation-mode-map-alists + `((override-global-mode . ,override-global-map))) + +(defvar personal-keybindings nil + "List of bindings performed by `bind-key'. + +Elements have the form ((KEY . [MAP]) CMD ORIGINAL-CMD)") + +;;;###autoload +(defmacro bind-key (key-name command &optional keymap predicate) + "Bind KEY-NAME to COMMAND in KEYMAP (`global-map' if not passed). + +KEY-NAME may be a vector, in which case it is passed straight to +`define-key'. Or it may be a string to be interpreted as +spelled-out keystrokes, e.g., \"C-c C-z\". See documentation of +`edmacro-mode' for details. + +If PREDICATE is non-nil, it is a form evaluated to determine when +a key should be bound. It must return non-nil in such cases. +Emacs can evaluate this form at any time that it does redisplay +or operates on menu data structures, so you should write it so it +can safely be called at any time." + (let ((namevar (make-symbol "name")) + (keyvar (make-symbol "key")) + (kdescvar (make-symbol "kdesc")) + (bindingvar (make-symbol "binding"))) + `(let* ((,namevar ,key-name) + (,keyvar (if (vectorp ,namevar) ,namevar + (read-kbd-macro ,namevar))) + (,kdescvar (cons (if (stringp ,namevar) ,namevar + (key-description ,namevar)) + (quote ,keymap))) + (,bindingvar (lookup-key (or ,keymap global-map) ,keyvar))) + (add-to-list 'personal-keybindings + (list ,kdescvar ,command + (unless (numberp ,bindingvar) ,bindingvar))) + ,(if predicate + `(define-key (or ,keymap global-map) ,keyvar + '(menu-item "" nil :filter (lambda (&optional _) + (when ,predicate + ,command)))) + `(define-key (or ,keymap global-map) ,keyvar ,command))))) + +;;;###autoload +(defmacro unbind-key (key-name &optional keymap) + "Unbind the given KEY-NAME, within the KEYMAP (if specified). +See `bind-key' for more details." + `(progn + (bind-key ,key-name nil ,keymap) + (setq personal-keybindings + (cl-delete-if #'(lambda (k) + ,(if keymap + `(and (consp (car k)) + (string= (caar k) ,key-name) + (eq (cdar k) ',keymap)) + `(and (stringp (car k)) + (string= (car k) ,key-name)))) + personal-keybindings)))) + +;;;###autoload +(defmacro bind-key* (key-name command &optional predicate) + "Similar to `bind-key', but overrides any mode-specific bindings." + `(bind-key ,key-name ,command override-global-map ,predicate)) + +(defun bind-keys-form (args) + "Bind multiple keys at once. + +Accepts keyword arguments: +:map MAP - a keymap into which the keybindings should be + added +:prefix KEY - prefix key for these bindings +:prefix-map MAP - name of the prefix map that should be created + for these bindings +:prefix-docstring STR - docstring for the prefix-map variable +:menu-name NAME - optional menu string for prefix map +:filter FORM - optional form to determine when bindings apply + +The rest of the arguments are conses of keybinding string and a +function symbol (unquoted)." + ;; jww (2016-02-26): This is a hack; this whole function needs to be + ;; rewritten to normalize arguments the way that use-package.el does. + (if (and (eq (car args) :package) + (not (eq (car (cdr (cdr args))) :map))) + (setq args (cons :map (cons 'global-map args)))) + (let* ((map (plist-get args :map)) + (doc (plist-get args :prefix-docstring)) + (prefix-map (plist-get args :prefix-map)) + (prefix (plist-get args :prefix)) + (filter (plist-get args :filter)) + (menu-name (plist-get args :menu-name)) + (pkg (plist-get args :package)) + (key-bindings (progn + (while (keywordp (car args)) + (pop args) + (pop args)) + args))) + (when (or (and prefix-map (not prefix)) + (and prefix (not prefix-map))) + (error "Both :prefix-map and :prefix must be supplied")) + (when (and menu-name (not prefix)) + (error "If :menu-name is supplied, :prefix must be too")) + (let ((args key-bindings) + saw-map first next) + (while args + (if (keywordp (car args)) + (progn + (setq next args) + (setq args nil)) + (if first + (nconc first (list (car args))) + (setq first (list (car args)))) + (setq args (cdr args)))) + (cl-flet + ((wrap (map bindings) + (if (and map pkg (not (eq map 'global-map))) + (if (boundp map) + bindings + `((eval-after-load + ,(if (symbolp pkg) `',pkg pkg) + '(progn ,@bindings)))) + bindings))) + (append + (when prefix-map + `((defvar ,prefix-map) + ,@(when doc `((put ',prefix-map 'variable-documentation ,doc))) + ,@(if menu-name + `((define-prefix-command ',prefix-map nil ,menu-name)) + `((define-prefix-command ',prefix-map))) + ,@(if (and map (not (eq map 'global-map))) + (wrap map `((bind-key ,prefix ',prefix-map ,map ,filter))) + `((bind-key ,prefix ',prefix-map nil ,filter))))) + (wrap map + (cl-mapcan + (lambda (form) + (if prefix-map + `((bind-key ,(car form) ',(cdr form) ,prefix-map ,filter)) + (if (and map (not (eq map 'global-map))) + `((bind-key ,(car form) ',(cdr form) ,map ,filter)) + `((bind-key ,(car form) ',(cdr form) nil ,filter))))) + first)) + (when next + (bind-keys-form + (if pkg + (cons :package (cons pkg next)) + next)))))))) + +;;;###autoload +(defmacro bind-keys (&rest args) + "Bind multiple keys at once. + +Accepts keyword arguments: +:map MAP - a keymap into which the keybindings should be + added +:prefix KEY - prefix key for these bindings +:prefix-map MAP - name of the prefix map that should be created + for these bindings +:prefix-docstring STR - docstring for the prefix-map variable +:menu-name NAME - optional menu string for prefix map +:filter FORM - optional form to determine when bindings apply + +The rest of the arguments are conses of keybinding string and a +function symbol (unquoted)." + (macroexp-progn (bind-keys-form args))) + +;;;###autoload +(defmacro bind-keys* (&rest args) + (macroexp-progn + (bind-keys-form `(:map override-global-map ,@args)))) + +(defun get-binding-description (elem) + (cond + ((listp elem) + (cond + ((eq 'lambda (car elem)) + (if (and bind-key-describe-special-forms + (stringp (nth 2 elem))) + (nth 2 elem) + "#")) + ((eq 'closure (car elem)) + (if (and bind-key-describe-special-forms + (stringp (nth 3 elem))) + (nth 3 elem) + "#")) + ((eq 'keymap (car elem)) + "#") + (t + elem))) + ;; must be a symbol, non-symbol keymap case covered above + ((and bind-key-describe-special-forms (keymapp elem)) + (let ((doc (get elem 'variable-documentation))) + (if (stringp doc) doc elem))) + ((symbolp elem) + elem) + (t + "#"))) + +(defun compare-keybindings (l r) + (let* ((regex bind-key-segregation-regexp) + (lgroup (and (string-match regex (caar l)) + (match-string 0 (caar l)))) + (rgroup (and (string-match regex (caar r)) + (match-string 0 (caar r)))) + (lkeymap (cdar l)) + (rkeymap (cdar r))) + (cond + ((and (null lkeymap) rkeymap) + (cons t t)) + ((and lkeymap (null rkeymap)) + (cons nil t)) + ((and lkeymap rkeymap + (not (string= (symbol-name lkeymap) (symbol-name rkeymap)))) + (cons (string< (symbol-name lkeymap) (symbol-name rkeymap)) t)) + ((and (null lgroup) rgroup) + (cons t t)) + ((and lgroup (null rgroup)) + (cons nil t)) + ((and lgroup rgroup) + (if (string= lgroup rgroup) + (cons (string< (caar l) (caar r)) nil) + (cons (string< lgroup rgroup) t))) + (t + (cons (string< (caar l) (caar r)) nil))))) + +;;;###autoload +(defun describe-personal-keybindings () + "Display all the personal keybindings defined by `bind-key'." + (interactive) + (with-output-to-temp-buffer "*Personal Keybindings*" + (princ (format (concat "Key name%s Command%s Comments\n%s %s " + "---------------------\n") + (make-string (- (car bind-key-column-widths) 9) ? ) + (make-string (- (cdr bind-key-column-widths) 8) ? ) + (make-string (1- (car bind-key-column-widths)) ?-) + (make-string (1- (cdr bind-key-column-widths)) ?-))) + (let (last-binding) + (dolist (binding + (setq personal-keybindings + (sort personal-keybindings + (lambda (l r) + (car (compare-keybindings l r)))))) + + (if (not (eq (cdar last-binding) (cdar binding))) + (princ (format "\n\n%s\n%s\n\n" + (cdar binding) + (make-string (+ 21 (car bind-key-column-widths) + (cdr bind-key-column-widths)) ?-))) + (if (and last-binding + (cdr (compare-keybindings last-binding binding))) + (princ "\n"))) + + (let* ((key-name (caar binding)) + (at-present (lookup-key (or (symbol-value (cdar binding)) + (current-global-map)) + (read-kbd-macro key-name))) + (command (nth 1 binding)) + (was-command (nth 2 binding)) + (command-desc (get-binding-description command)) + (was-command-desc (and was-command + (get-binding-description was-command))) + (at-present-desc (get-binding-description at-present)) + ) + (let ((line + (format + (format "%%-%ds%%-%ds%%s\n" (car bind-key-column-widths) + (cdr bind-key-column-widths)) + key-name (format "`%s\'" command-desc) + (if (string= command-desc at-present-desc) + (if (or (null was-command) + (string= command-desc was-command-desc)) + "" + (format "was `%s\'" was-command-desc)) + (format "[now: `%s\']" at-present))))) + (princ (if (string-match "[ \t]+\n" line) + (replace-match "\n" t t line) + line)))) + + (setq last-binding binding))))) + +(provide 'bind-key) + +;; Local Variables: +;; indent-tabs-mode: nil +;; End: + +;;; bind-key.el ends here diff --git a/one-file-mode/c++1x-minor-mode.el b/one-file-mode/c++1x-minor-mode.el new file mode 100644 index 0000000..114b831 --- /dev/null +++ b/one-file-mode/c++1x-minor-mode.el @@ -0,0 +1,56 @@ +(require 'font-lock) +;;###autoload +(define-minor-mode c++1x-minor-mode + "Extra highlighting for c++-mode that includes c++11 and c++14 keywords and features" + :lighter "c++1x" + + (defun --copy-face (new-face face) + "Define NEW-FACE from existing FACE." + (copy-face face new-face) + (eval `(defvar ,new-face nil)) + (set new-face new-face)) + + (--copy-face 'font-lock-label-face ; labels, case, public, private, proteced, namespace-tags + 'font-lock-keyword-face) + (--copy-face 'font-lock-doc-markup-face ; comment markups such as Javadoc-tags + 'font-lock-doc-face) + (--copy-face 'font-lock-doc-string-face ; comment markups + 'font-lock-comment-face) + + (global-font-lock-mode t) + (setq font-lock-maximum-decoration t) + + + (font-lock-add-keywords + nil '(;; complete some fundamental keywords + ("\\<\\(void\\|unsigned\\|signed\\|char\\|short\\|bool\\|int\\|long\\|float\\|double\\)\\>" . font-lock-keyword-face) + ;; add the new C++11 keywords + ("\\<\\(alignof\\|alignas\\|constexpr\\|noexcept\\|\\|static_assert\\|thread_local\\|override\\|final\\)\\>" . font-lock-keyword-face) + ("\\<\\(decltype\\)\\>" . font-lock-builtin-face) + ("\\<\\(nullptr\\)\\>" . font-lock-constant-face) + ("\\<\\(char[0-9]+_t\\)\\>" . font-lock-keyword-face) + ;; PREPROCESSOR_CONSTANT + ("\\<[A-Z]+[A-Z_]+\\>" . font-lock-constant-face) + ;; hexadecimal numbers + ("\\<0[xX][0-9A-Fa-f]+\\>" . font-lock-constant-face) + ;; integer/float/scientific numbers + ("\\<[\\-+]*[0-9]*\\.?[0-9]+\\([ulUL]+\\|[eE][\\-+]?[0-9]+\\)?\\>" . font-lock-constant-face) + ;; c++11 string literals + ;; L"wide string" + ;; L"wide string with UNICODE codepoint: \u2018" + ;; u8"UTF-8 string", u"UTF-16 string", U"UTF-32 string" + ("\\<\\([LuU8]+\\)\".*?\"" 1 font-lock-keyword-face) + ;; R"(user-defined literal)" + ;; R"( a "quot'd" string )" + ;; R"delimiter(The String Data" )delimiter" + ;; R"delimiter((a-z))delimiter" is equivalent to "(a-z)" + ("\\(\\<[uU8]*R\"[^\\s-\\\\()]\\{0,16\\}(\\)" 1 font-lock-keyword-face t) ; start delimiter + ( "\\<[uU8]*R\"[^\\s-\\\\()]\\{0,16\\}(\\(.*?\\))[^\\s-\\\\()]\\{0,16\\}\"" 1 font-lock-string-face t) ; actual string + ( "\\<[uU8]*R\"[^\\s-\\\\()]\\{0,16\\}(.*?\\()[^\\s-\\\\()]\\{0,16\\}\"\\)" 1 font-lock-keyword-face t) ; end delimiter + + ))) + +;;###autoload +(add-hook 'c++-mode-hook 'c++1x-minor-mode) + +(provide 'c++1x-minor-mode) diff --git a/one-file-mode/doc-mode.el b/one-file-mode/doc-mode.el new file mode 100644 index 0000000..b06c9bf --- /dev/null +++ b/one-file-mode/doc-mode.el @@ -0,0 +1,928 @@ +;;; doc-mode.el --- convenient editing of in-code documentation +;; +;; Copyright (C) 2007, 2009 Nikolaj Schumacher +;; Author: Nikolaj Schumacher +;; Version: 0.2 +;; Keywords: convenience tools +;; URL: http://nschum.de/src/emacs/doc-mode/ +;; Compatibility: GNU Emacs 22.x, GNU Emacs 23.x +;; +;; This file is NOT part of GNU Emacs. +;; +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License +;; as published by the Free Software Foundation; either version 2 +;; of the License, or (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . +;; +;;; Commentary: +;; +;; This mode requires the Semantic package to be installed and running: +;; http://cedet.sourceforge.net/ +;; +;; doc-mode allows easy creation and editing of JavaDoc or Doxygen comment +;; blocks in your code. It also greatly improves readability of code by folding +;; the blocks, so they don't take up precious screen lines. +;; +;; Add the following to your .emacs file: +;; (require 'doc-mode) +;; (add-hook 'c-mode-common-hook 'doc-mode) +;; +;; The command `doc-mode-fix-tag-doc' or "C-cdd" adds or replaces the +;; documentation for the function, variable, or class at point. +;; `doc-mode-remove-tag-doc' or "C-cdr" removes it. +;; +;; You can fold the comments by using `doc-mode-toggle-tag-doc-folding' or +;; `doc-mode-fold-all'. +;; +;;; Change Log: +;; +;; 2009-03-22 (0.2) +;; Added `doc-mode-keywords-from-tag-func' as customizable option. +;; Improved parameter list change recognition. +;; `doc-mode-jump-to-template' now enables jumping to the latest comment. +;; `doc-mode-first-template' now jumps to the first template in this buffer. +;; +;; 2007-09-09 (0.1.1) +;; Fixed return value detection. +;; Actual keyword highlighting. +;; +;; 2007-09-07 (0.1) +;; Initial release. +;; +;;; Code: + +(eval-when-compile (require 'cl)) +(require 'semantic) +(require 'cc-mode) +(require 'newcomment) ;comment-fill-column + +(dolist (err `("^No tag found$" "^Semantic can't parse buffer$" + "^No template found$" "^doc-mode not enabled$")) + (add-to-list 'debug-ignored-errors err)) + +;; semantic-after-auto-parse-hooks + +(defgroup doc-mode nil + "Minor mode for editing in-code documentation." + :group 'convenience + :group 'tools) + +(defcustom doc-mode-auto-check-p t + "*Should the buffer documentation be checked after a Semantic reparse." + :group 'doc-mode + :type '(choice (const :tag "Off" nil) + (const :tag "On" t))) + +(defcustom doc-mode-jump-to-template t + "*Should the point be moved inside the template after inserting a doc." + :group 'doc-mode + :type '(choice (const :tag "Off" nil) + (const :tag "On" t))) + +(defcustom doc-mode-template-start "/**" + "*The string to insert at the beginning of a comment." + :group 'doc-mode + :type 'string) + +(defcustom doc-mode-template-end " */" + "*The string to insert at the end of a comment." + :group 'doc-mode + :type 'string) + +(defcustom doc-mode-template-continue " * " + "*The string to insert at the beginning of each line in a comment." + :group 'doc-mode + :type 'string) + +(defcustom doc-mode-template-single-line-start "/** " + "*The string to insert at the beginning of a single-line comment. +For using single-line comments, see `doc-mode-allow-single-line-comments'" + :group 'doc-mode + :type 'string) + +(defcustom doc-mode-template-single-line-end " */" + "*The string to insert at the end of a single-line comment. +For using single-line comments, see `doc-mode-allow-single-line-comments'" + :group 'doc-mode + :type 'string) + +(defcustom doc-mode-template-keyword-char "@" + "*The character used to begin keywords." + :group 'doc-mode + :type '(choice (const :tag "@" "@") + (const :tag "\\" "\\") + (string :tag "Other"))) + +(defcustom doc-mode-template-empty-line-after-summary nil + "*Whether to put an empty line after the first one in the comment." + :group 'doc-mode + :type '(choice (const :tag "Off" nil) + (const :tag "On" t))) + +(defcustom doc-mode-template-empty-line-before-keywords nil + "*Whether to put an empty line before the keyword list in a comment." + :group 'doc-mode + :type '(choice (const :tag "Off" nil) + (const :tag "On" t))) + +(defcustom doc-mode-template-keywords + '("deprecated" "param" "return" "author" "exception" "throws" "version" + "since" "see" "sa" "todo") + "*Keywords that should be listed in this order. +All other keywords will be considered regular text." + :group 'doc-mode + :type '(repeat string)) + +(defcustom doc-mode-allow-single-line-comments t + "*Whether to allow a more space-saving format for very short comments. +When this is enabled, `doc-mode-template-single-line-start' and +`doc-mode-template-single-line-end' will be used to format single-line +comments instead of `doc-mode-template-start', `doc-mode-template-end' and +`doc-mode-template-continue'." + :group 'doc-mode + :type '(choice (const :tag "Off" nil) + (const :tag "On" t))) + +(defcustom doc-mode-fold-single-line-comments nil + "*Whether to bother folding comments that are already a single line." + :group 'doc-mode + :type '(choice (const :tag "Off" nil) + (const :tag "On" t))) + +(defcustom doc-mode-align-keyword-arguments t + "*Whether to align the arguments to a keyword continued in the next line. +This may also be a number, describing how far to indent the argument list." + :group 'doc-mode + :type '(choice (const :tag "Off" nil) + (integer :tag "Indent" nil) + (const :tag "On" t))) + +(defcustom doc-mode-fill-column nil + "*The column at which to break text when formatting it. +If this is nil, `comment-fill-column' is used." + :group 'doc-mode + :type '(choice (const :tag "Default" nil) + (integer :tag "Fill Column"))) + +(defcustom doc-mode-keywords-from-tag-func 'doc-mode-keywords-from-tag + "*Function used to generate keywords for a tag. +This must be a function that takes two arguments. The first argument is the +Semantic tag for which to generate keywords, the second is a list of existing +keywords taken from the current doc comment. It should return the new list of +keywords. Each element in a keyword list can be either a string or a list with +a keyword, optional argument and optional description. Additional entries with +undetermined content should be created with `doc-mode-new-keyword'." + :group 'doc-mode + :type 'function) + +;;; keywords ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defconst doc-mode-font-lock-keywords + (eval-when-compile + `((,(concat "[\\@]" + (regexp-opt + '("addindex" "addtogroup" "anchor" "arg" "author" "brief" "callgraph" + "callergraph" "category" "code" "cond" "copydoc" "date" "defgroup" + "deprecated" "details" "dir" "dontinclude" "dot" "dotfile" "e" + "else" "elseif" "em" "endcode" "endcond" "enddot" "endhtmlonly" + "endif" "endlatexonly" "endlink" "endmanonly" "endmsc" "endverbatim" + "endxmlonly" "example" "f$" "f[" "f]" "file" "fn" "hideinitializer" + "htmlinclude" "htmlonly" "if" "ifnot" "image" "include" + "includelineno" "ingroup" "internal" "invariant" "latexonly" "li" + "line" "link" "mainpage" "manonly" "msc" "name" "nosubgrouping" + "note" "overload" "package" "page" "par" "paragraph" "post" "pre" + "private" "privatesection" "property" "protected" "protectedsection" + "public" "publicsection" "ref" "remarks" "return" "retval" "sa" + "section" "see" "serial" "serialData" "serialField" + "showinitializer" "since" "skip" "skipline" "subpage" "subsection" + "subsubsection" "test" "typedef" "until" "defvar" "verbatim" + "verbinclude" "version" "weakgroup" "xmlonly" "xrefitem" "$" "@" + "\\" "&" "~" "<" ">" "#" "%") t) + "\\>") + (0 font-lock-keyword-face prepend)) + ;; don't highlight \n, it's too common in code + ("@n" (0 font-lock-keyword-face prepend)) + (,(concat "\\([@\\]" + (regexp-opt '("class" "struct" "union" "exception" "enum" "throw" + "throws") t) + "\\)\\>\\(?:[ \t]+\\(\\sw+\\)\\)?") + (1 font-lock-keyword-face prepend) + (3 font-lock-type-face prepend)) + (,(concat "\\([@\\]" + (regexp-opt '("param" "param[in]" "param[out]" "param[in+out]" "a" + "namespace" "relates" "relatesalso" "def") t) + "\\)\\>\\(?:[ \t]+\\(\\sw+\\)\\)?") + (1 font-lock-keyword-face prepend) + (3 font-lock-variable-name-face prepend)) + (,(concat "\\([@\\]retval\\)\\>\\(?:[ \t]+\\(\\sw+\\)\\)?") + (1 font-lock-keyword-face prepend) + (2 font-lock-function-name-face prepend)) + (,(concat "[@\\]" (regexp-opt '("attention" "warning" "todo" "bug") t) + "\\>") + (0 font-lock-warning-face prepend)) + (,(concat "{@" + (regexp-opt '("docRoot" "inheritDoc" "link" "linkplain" "value") t) + "}") + (0 font-lock-keyword-face prepend)) + ("\\([@\\]b\\)[ \t\n]+\\([^ \t\n]+\\)" + (1 font-lock-keyword-face prepend) + (2 'bold prepend)) + ("\\([@\\]em?\\)[ \t\n]+\\([^ \t\n]+\\)" + (1 font-lock-keyword-face prepend) + (2 'italic prepend)) + ("\\([@\\][cp]\\)[ \t\n]+\\([^ \t\n]+\\)" + (1 font-lock-keyword-face prepend) + (2 'underline prepend))))) + +;;; templates ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defvar doc-mode-templates nil) +(make-variable-buffer-local 'doc-mode-templates) + +(defun doc-mode-add-template (beg end) + (let ((overlay (make-overlay beg (point)))) + (overlay-put overlay 'intangible t) + (overlay-put overlay 'face 'highlight) + (overlay-put overlay 'insert-in-front-hooks '(doc-mode-replace-overlay)) + (overlay-put overlay 'modification-hooks '(doc-mode-delete-overlay)) + (push overlay doc-mode-templates))) + +(defvar doc-mode-temp nil) + +(defun doc-mode-delete-overlay (ov after-p beg end &optional r) + (unless after-p + (mapc 'doc-mode-unfold-by-overlay + (overlays-in (1- (overlay-start ov)) (1+ (overlay-end ov)))) + (delete-overlay ov) + (setq doc-mode-templates (delq ov doc-mode-templates)))) + +(defun doc-mode-replace-overlay (ov after-p beg end &optional r) + (unless after-p + (let ((inhibit-modification-hooks nil)) + (delete-region (overlay-start ov) (overlay-end ov))))) + +;;;###autoload +(defun doc-mode-next-template (&optional pos limit) + "Jump to the next unfinished documentation template in this buffer." + (interactive) + (unless pos (setq pos (point))) + (unless limit (setq limit (point-max))) + (let ((min-start limit) + start) + (dolist (ov doc-mode-templates) + (setq start (overlay-start ov)) + (and (> start pos) + (< start min-start) + (setq min-start start))) + (when (= min-start limit) + (error "End of buffer")) + (push-mark) + (goto-char min-start))) + +;;;###autoload +(defun doc-mode-previous-template (&optional pos limit) + "Jump to the previous unfinished documentation template in this buffer." + (interactive) + (unless pos (setq pos (point))) + (unless limit (setq limit (point-min))) + (let ((max-start limit) + start) + (dolist (ov doc-mode-templates) + (setq start (overlay-start ov)) + (and (< start pos) + (> start max-start) + (setq max-start start))) + (when (= max-start limit) + (error "Beginning of buffer")) + (push-mark) + (goto-char max-start))) + +;;;###autoload +(defun doc-mode-first-template () + "Jump to the first unfinished documentation template in this buffer." + (interactive) + (condition-case err + (doc-mode-next-template (point-min)) + (error (error "No template found")))) + +;;; mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defvar doc-mode-lighter " doc") + +(defvar doc-mode-prefix-map + (let ((map (make-sparse-keymap))) + (define-key map "d" 'doc-mode-fix-tag-doc) + (define-key map "c" 'doc-mode-check-tag-doc) + (define-key map "t" 'doc-mode-toggle-tag-doc-folding) + (define-key map "f" 'doc-mode-fold-tag-doc) + (define-key map "u" 'doc-mode-unfold-tag-doc) + (define-key map "r" 'doc-mode-remove-tag-doc) + (define-key map "i" 'doc-mode-add-tag-doc) + (define-key map "e" 'doc-mode-next-faulty-doc) + (define-key map "n" 'doc-mode-next-template) + (define-key map "\C-c" 'doc-mode-check-buffer) + (define-key map "\C-f" 'doc-mode-fold-all) + (define-key map "\C-u" 'doc-mode-unfold-all) + map)) + +(defvar doc-mode-map + (let ((map (make-sparse-keymap))) + (define-key map "\C-c\C-d" doc-mode-prefix-map) + map) + "Keymap used for `doc-mode'.") + +;;;###autoload +(define-minor-mode doc-mode + "Minor mode for editing in-code documentation." + nil doc-mode-lighter doc-mode-map + (if doc-mode + (progn + (font-lock-add-keywords nil doc-mode-font-lock-keywords) + (when doc-mode-auto-check-p + (add-hook 'semantic-after-auto-parse-hooks 'doc-mode-check-buffer + nil t) + (add-hook 'semantic-after-idle-scheduler-reparse-hooks + 'doc-mode-check-buffer nil t))) + (dolist (ov doc-mode-templates) + (delete-overlay ov)) + (kill-local-variable 'doc-mode-templates) + (doc-mode-unfold-all) + (font-lock-remove-keywords nil doc-mode-font-lock-keywords) + (remove-hook 'semantic-after-auto-parse-hooks 'doc-mode-check-buffer t) + (remove-hook 'semantic-after-idle-scheduler-reparse-hooks + 'doc-mode-check-buffer t)) + + (when font-lock-mode + (font-lock-fontify-buffer))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun doc-mode-current-tag () + (when (semantic-parse-tree-unparseable-p) + (error "Semantic can't parse buffer")) + (when (or (semantic-parse-tree-needs-rebuild-p) + (semantic-parse-tree-needs-update-p)) + (condition-case nil + (semantic-fetch-tags) + (error (error "Semantic can't parse buffer")))) + (save-excursion + (or (semantic-current-tag-of-class 'function) + (semantic-current-tag-of-class 'variable) + (progn (beginning-of-line) (skip-chars-forward " \t\n") nil) + (semantic-current-tag-of-class 'function) + (semantic-current-tag-of-class 'variable) + (if (not (looking-at "/\\*\\*")) + (semantic-current-tag-of-class 'type) + (progn (search-forward "*/" nil t) + (skip-chars-forward " \t\n") + nil)) + (semantic-current-tag-of-class 'function) + (semantic-current-tag-of-class 'variable) + (semantic-current-tag-of-class 'type)))) + +(defun doc-mode-current-tag-or-bust () + (or (doc-mode-current-tag) (error "No tag found"))) + +;;; insertion ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun doc-mode-line-indent (keyword) + "Determine left side offset when indenting LINE." + (if (numberp doc-mode-align-keyword-arguments) + doc-mode-align-keyword-arguments + (+ 1 (length (car keyword)) + (if (equal (car keyword) "param") + (1+ (length (cdr keyword))) + 0)))) + +(defun doc-mode-insert (text) + "Insert TEXT if a string, or a template if 'prompt." + (if (stringp text) + (insert text) + (let ((beg (point))) + (insert (cadr text)) + (when doc-mode + (doc-mode-add-template beg (point)))))) + +(defun doc-mode-insert-markup (markup &optional argument description) + (insert doc-mode-template-keyword-char markup) + (when argument + (insert " ") + (doc-mode-insert argument)) + (when description + (insert " ") + (doc-mode-insert description))) + +(defun doc-mode-insert-line (line indent) + (indent-to-column indent) + (let ((beg (point))) + (insert doc-mode-template-continue) + (if (and (consp line) (not (eq (car line) 'prompt))) + (apply 'doc-mode-insert-markup line) + (doc-mode-insert line)) + (delete-char (- (skip-chars-backward " \t"))) + (when (> (point) (+ beg 2)) + (save-excursion (fill-region beg (point) 'left t))) + (insert "\n"))) + +(defun doc-mode-insert-keyword (keyword indent) + (indent-to-column indent) + (let ((fill-column (or doc-mode-fill-column comment-fill-column fill-column)) + (fill-prefix (when doc-mode-align-keyword-arguments + (concat (buffer-substring (point-at-bol) (point)) + doc-mode-template-continue + (make-string (doc-mode-line-indent keyword) + ? ))))) + (doc-mode-insert-line keyword indent))) + +(defun doc-mode-insert-doc (keywords &optional pos) + "Insert a documentation at POS. +LINES is a list of keywords." + (save-excursion + (if pos + (goto-char pos) + (setq pos (point))) + (let ((indent (current-column))) + + (if (and (not (cdr keywords)) doc-mode-allow-single-line-comments) + (progn (insert doc-mode-template-single-line-start) + (doc-mode-insert (car keywords)) + (insert doc-mode-template-single-line-end "\n")) + (insert doc-mode-template-start "\n") + + ;; first line + (when (or (stringp (car keywords)) + (eq 'prompt (caar keywords))) + (doc-mode-insert-line (pop keywords) indent)) + + (when (and doc-mode-template-empty-line-after-summary + (or (null doc-mode-template-empty-line-before-keywords) + (stringp (cadr keywords)))) + (doc-mode-insert-line "" indent)) + + ;; paragraphs + (if (cdr keywords) + (while (stringp (car keywords)) + (doc-mode-insert-line (pop keywords) indent) + (when (stringp (car keywords)) + (doc-mode-insert-line "" indent))) + (while (stringp (car keywords)) + (doc-mode-insert-line (pop keywords) indent))) + + (when doc-mode-template-empty-line-before-keywords + (doc-mode-insert-line "" indent)) + + ;; keywords + (while keywords + (doc-mode-insert-keyword (pop keywords) indent)) + (indent-to-column indent) + (insert doc-mode-template-end "\n")) + + ;; re-indent original line + (if (< (current-column) indent) + (indent-to-column indent) + (move-to-column indent t)))) + + (and doc-mode-jump-to-template doc-mode-templates + (ignore-errors (doc-mode-next-template pos (point))))) + +(defun doc-mode-remove-doc (point) + "Remove the documentation before POINT." + (let* ((bounds (doc-mode-find-doc-bounds point)) + (beg (plist-get bounds :beg)) + (end (plist-get bounds :end))) + (when bounds + (save-excursion + (goto-char beg) + (incf beg (skip-chars-backward " \t")) + (goto-char end) + (incf end (skip-chars-forward " \t")) + (when (eolp) (incf end)) + (delete-region beg end))))) + +;;;###autoload +(defun doc-mode-remove-tag-doc (tag) + "Remove the documentation for TAG. +If called interactively, use the tag given by `doc-mode-current-tag'." + (interactive (list (doc-mode-current-tag-or-bust))) + (doc-mode-remove-doc (semantic-tag-start tag))) + +;;; registering ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun doc-mode-find-doc-bounds (pos) + "Find the documentation right before POS. +If there is anything but whitespace between the documentation and POS, nil is +returned. Otherwise a cons of the doc's beginning and end is given." + (let (end) + (save-excursion + (goto-char pos) + (when (re-search-backward "[ \t]*\n[ \t]*\\=" nil t) + (setq end (point)) + (cond + ;; /// Doxygen comment */ + ((looking-back "[ \t]*//[/!]\\(.*\\)$") + (forward-line -1) + (while (looking-at "[ \t]*//[/!]\\(.*\\)$") + (forward-line -1)) + (forward-line 1) + (skip-chars-forward " \t") + `(:beg ,(point) :end ,end :column ,(current-indentation))) + ;; /** JavaDoc comment */ + ((looking-back "\\*/") + (goto-char (match-beginning 0)) + ;; search for /*, not allowing any */ in between + (when (and (re-search-backward "\\(/\\*\\)\\|\\*/" nil t) + (match-beginning 1) + (memq (char-after (1+ (match-beginning 1))) '(?! ?*))) + `(:beg ,(point) :end ,end :column ,(current-column))))))))) + +;;; formating ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun doc-mode-new-keyword (keyword &optional argument) + (if (equal keyword "param") + (list keyword argument '(prompt "")) + (list keyword '(prompt "")))) + +(defun doc-mode-has-return-value-p (tag) + "Test if TAG has a return value to format." + (and (eq (semantic-tag-class tag) 'function) + (not (equal (semantic-tag-type tag) "void")) + (not (semantic-tag-get-attribute tag :constructor-flag)) + (or (not (equal (semantic-tag-type tag) "int")) + ;; semantic bug, constructors sometimes appear to have int type + (save-excursion (goto-char (semantic-tag-start tag)) + (and (re-search-forward "\\(\\\\)\\|{\\|;" + (semantic-tag-end tag) t) + (match-beginning 1)))))) + +;;; extracting ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun doc-mode-extract-summary (beg end) + (let ((bounds (doc-mode-find-summary beg end))) + (buffer-substring-no-properties (car bounds) (cdr bounds)))) + +(defun doc-mode-find-summary (beg end) + (save-excursion + (goto-char beg) + (if (or (re-search-forward "^[@\\]brief \\([^\t ][^\n]*\n\\)" end t) + (re-search-forward "\\<\\(.*\\)\\(\\*+/\\|\n\\)" end t)) + (cons (match-beginning 1) (match-end 1)) + (cons beg beg)))) + +(defconst doc-mode-begin-regexp + (eval-when-compile (concat "[ \t\n]*" + "\\(" + "/\\*\\(\\*+\\|!\\)" + "\\|" + "//[!/]" + "\\)[ \t]*"))) + +(defun doc-mode-clean-doc (beg end) + "Remove the comment delimiters between BEG and END." + (save-excursion + (goto-char beg) + (when (looking-at doc-mode-begin-regexp) + (setq beg (match-end 0))) + (goto-char end) + (when (looking-back "[ \t\n\r]*\\*+/" nil t) + (setq end (match-beginning 0))) + (let ((lines (split-string (buffer-substring-no-properties beg end) + "[ \t]*\n[ \t]*\\(\\*/?\\|//[!/]\\)?[ \t]*"))) + (while (equal (car lines) "") + (pop lines)) + (mapconcat 'identity lines "\n")))) + +(defun doc-mode-extract-keywords (beg end) + "Extract documentation keywords between BEG and END. +Returns a alist of keywords, where each element is the list (keyword +argument value) or (keyword argument)." + (let* ((paragraphs (doc-mode-clean-doc beg end)) + (doc "") + (pos 0) + match results) + + (when (string-match + "[ \t\n]*\\(\\(.\\|\n\\)*?\\)\\([@\\]\\<\\(.\\|\n\\)*\\'\\)" + paragraphs) + (setq doc (match-string-no-properties 3 paragraphs) + paragraphs (match-string-no-properties 1 paragraphs))) + + ;; first line summary + (when (string-match "\\`[ \t\n]*\\(.+\\.\\)\\([ \n]+\\|\\'\\)" paragraphs) + (push (match-string 1 paragraphs) results) + (setq pos (match-end 0))) + + ;; other paragraphs + (dolist (paragraph (split-string (substring paragraphs pos) + "[ \t]*\n\\(\n+[ \t]*\\|$\\)" t)) + (push (replace-regexp-in-string "[\n\r]" " " paragraph) results)) + + ;; keywords + (dolist (keyword (cdr (split-string doc "[@\\]\\<"))) + (setq match (split-string keyword)) + (push (if (equal (car match) "param") + (list (car match) (cadr match) + (mapconcat 'identity (cddr match) " ")) + (list (car match) (mapconcat 'identity (cdr match) " "))) + results)) + (nreverse results))) + +(defun doc-mode-extract-keywords-for-tag (tag) + (let ((bounds (doc-mode-find-doc-bounds (semantic-tag-start tag)))) + (when bounds (doc-mode-extract-keywords (plist-get bounds :beg) + (plist-get bounds :end))))) + +(defun doc-mode-find-keyword (keyword keywords) + (when keywords + (if (and (consp (car keywords)) (string= (car (car keywords)) keyword)) + (cons (car keywords) (doc-mode-find-keyword keyword (cdr keywords))) + (doc-mode-find-keyword keyword (cdr keywords))))) + +(defun doc-mode-filter-keyword (keyword keywords) + (when keywords + (if (and (consp (car keywords)) (string= (car (car keywords)) keyword)) + (doc-mode-filter-keyword keyword (cdr keywords)) + (cons (car keywords) (doc-mode-filter-keyword keyword (cdr keywords)))))) + +(defun doc-mode-find-eligible-tags () + (when buffer-file-name + (unless (or (semantic-parse-tree-unparseable-p) + (semantic-parse-tree-needs-rebuild-p) + (semantic-parse-tree-needs-update-p)) + (ignore-errors + (let (tags) + (semantic-brute-find-tag-by-function + (lambda (tag) + (when (semantic-tag-start tag) + (case (semantic-tag-class tag) + ((function variable) (push tag tags)) + (type (setq tags + (nconc (semantic-tag-type-members tag) + tags)))))) + (semanticdb-file-stream buffer-file-name)) + tags))))) + +;;; checking ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defsubst doc-mode-position (element list) + "Return the first position of ELEMENT in LIST. +Returns (length LIST) if no occurrence was found." + (let ((pos 0)) + (while (and list (not (equal element (pop list)))) + (incf pos)) + pos)) + +(defun doc-mode-keyword< (a b tag) + (if (equal (car a) "param") + (let* ((args (mapcar 'semantic-tag-name + (semantic-tag-get-attribute tag :arguments))) + (a-param (cadr a)) + (b-param (cadr b)) + (a-pos (doc-mode-position a-param args)) + (b-pos (doc-mode-position b-param args))) + (if (= a-pos b-pos) + (string< a-param b-param) + (< a-pos b-pos))) + (string< (cadr a) (cadr b)))) + +(defun doc-mode-sort-keywords (keywords tag) + (let ((lists (make-vector (1+ (length doc-mode-template-keywords)) nil)) + description) + (dolist (k keywords) + (if (or (stringp k) (and (eq (car k) 'prompt))) + (push k description) + (push k (elt lists (doc-mode-position (car k) + doc-mode-template-keywords))))) + (let ((i (length lists)) result) + (while (> i 0) + (setq result (nconc (sort (elt lists (decf i)) + (lambda (a b) (doc-mode-keyword< a b tag))) + result))) + (nconc (nreverse description) result)))) + +(defun doc-mode-update-parameters (old new) + "Cleanse and sort NEW parameters according to OLD parameter list." + (let (params car-new) + (while (setq car-new (pop new)) + (push (or (dolist (p old) ;; search for match in old + (when (equal (cadr p) car-new) + (setq old (delete p old)) + (return p))) + ;; this parameter wasn't there before + (if (or (null old) (member (cadr (car old)) new)) + ;; insertion, new + (doc-mode-new-keyword "param" car-new) + ;; the old parameter at this pos isn't there anymore, rename + (list* "param" car-new (cddr (pop old))))) + params)) + (nreverse params))) + +(defun doc-mode-keywords-from-tag (tag keywords) + "Create keywords for a Semantic TAG, taking descriptions from old KEYWORDS" + (let ((old-params (doc-mode-find-keyword "param" keywords)) + (new-params (mapcar 'semantic-tag-name + (semantic-tag-get-attribute tag :arguments)))) + ;; fix return value + (if (doc-mode-has-return-value-p tag) + ;; add + (unless (doc-mode-find-keyword "return" keywords) + (push (doc-mode-new-keyword "return") keywords)) + ;; remove + (setq keywords (doc-mode-filter-keyword "return" keywords))) + (unless (stringp (car keywords)) + (push `(prompt ,(format "Description for %s." (semantic-tag-name tag))) + keywords)) + (doc-mode-sort-keywords (nconc (doc-mode-update-parameters old-params + new-params) + (doc-mode-filter-keyword "param" keywords)) + tag))) + +;;;###autoload +(defun doc-mode-fix-tag-doc (tag) + (interactive (list (doc-mode-current-tag-or-bust))) + (let ((keywords (funcall doc-mode-keywords-from-tag-func + tag (doc-mode-extract-keywords-for-tag tag)))) + (doc-mode-remove-tag-doc tag) + (doc-mode-insert-doc keywords (semantic-tag-start tag)) + ;; update lighter + (doc-mode-check-buffer))) + +;;;###autoload +(defalias 'doc-mode-add-tag-doc 'doc-mode-fix-tag-doc) + +(defun doc-mode-format-message (type parameters) + (when parameters + (concat (case type + ('missing "Missing") + ('invalid "Invalid")) + " parameter" (when (cdr parameters) "s") ": " + (mapconcat 'identity parameters ", ")))) + +;;;###autoload +(defun doc-mode-check-tag-doc (tag &optional print-message-p) + (interactive (list (doc-mode-current-tag-or-bust) t)) + (let* ((actual (doc-mode-extract-keywords-for-tag tag)) + (expected (mapcar 'semantic-tag-name + (semantic-tag-get-attribute tag :arguments)))) + (if actual + (let ((no-doc-p (not (stringp (car actual)))) + ;; we only report parameters + (actual (mapcar 'cadr (doc-mode-find-keyword "param" + actual))) + invalid) + (dolist (keyword actual) + (if (member keyword expected) + (setq expected (delete keyword expected)) + (push keyword invalid))) + (when print-message-p + (message "%s" (concat (and no-doc-p "Missing documentation") + (and no-doc-p expected "\n") + (doc-mode-format-message 'missing expected) + (and (or no-doc-p expected) invalid "\n") + (doc-mode-format-message 'invalid invalid)))) + (or no-doc-p expected invalid)) + (when print-message-p + (message "Missing comment")) + t))) + +;;;###autoload +(defun doc-mode-check-buffer () + (interactive) + (kill-local-variable 'doc-mode-lighter) + (dolist (tag (doc-mode-find-eligible-tags)) + (when (doc-mode-check-tag-doc tag) + (set (make-local-variable 'doc-mode-lighter) " doc!") + (return t)))) + +(defun doc-mode-first-faulty-tag-doc () + (dolist (tag (sort (doc-mode-find-eligible-tags) + (lambda (a b) (< (semantic-tag-start a) + (semantic-tag-start b))))) + (when (doc-mode-check-tag-doc tag) + (return tag)))) + +;;;###autoload +(defun doc-mode-next-faulty-doc () + "Jump to the next faulty documentation and print error." + (interactive) + (let ((tag (or (doc-mode-first-faulty-tag-doc) + (error "End of buffer")))) + (push-mark) + (goto-char (semantic-tag-start tag)) + ;; check again with message + (doc-mode-check-tag-doc tag t))) + +;;; folding ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defvar doc-mode-folds nil) +(make-variable-buffer-local 'doc-mode-folds) + +(defun doc-mode-fold-doc (point) + (let ((bounds (doc-mode-find-doc-bounds point))) + (when bounds + (let* ((beg (plist-get bounds :beg)) + (end (plist-get bounds :end)) + (summary-bounds (doc-mode-find-summary beg end)) + (before-overlay (make-overlay beg (car summary-bounds))) + (after-overlay (make-overlay (cdr summary-bounds) end)) + (siblings (list before-overlay after-overlay))) + (when (or doc-mode-fold-single-line-comments + (> (count-lines beg end) 1)) + (dolist (ov siblings) + (overlay-put ov 'invisible t) + (overlay-put ov 'isearch-open-invisible-temporary + 'doc-mode-unfold-by-overlay-temporary) + (overlay-put ov 'isearch-open-invisible 'doc-mode-unfold-by-overlay) + (overlay-put ov 'doc-mode-fold siblings)) + (setq doc-mode-folds (nconc doc-mode-folds siblings))))))) + +;;;###autoload +(defun doc-mode-fold-tag-doc (tag) + "Fold the documentation for TAG. +If called interactively, use the tag given by `doc-mode-current-tag'." + (interactive (list (doc-mode-current-tag-or-bust))) + (unless doc-mode + (error "doc-mode not enabled")) + (doc-mode-fold-doc (semantic-tag-start tag))) + +(defun doc-mode-unfold-by-overlay (overlay &rest foo) + "Unfold OVERLAY and its siblings permanently" + (dolist (ov (overlay-get overlay 'doc-mode-fold)) + ;; remove overlay + (setq doc-mode-folds (delq ov doc-mode-folds)) + (delete-overlay ov) + ;; don't let isearch do anything with it + (setq isearch-opened-overlays (delq ov isearch-opened-overlays)))) + +(defun doc-mode-unfold-by-overlay-temporary (overlay invisible) + "Unfold OVERLAY and its siblings temporarily." + (dolist (ov (overlay-get overlay 'doc-mode-fold)) + (overlay-put ov 'invisible invisible))) + +;;;###autoload +(defun doc-mode-unfold-doc (point) + "Unfold the comment before POINT." + (interactive "d") + (unless doc-mode + (error "doc-mode not enabled")) + (let ((bounds (doc-mode-find-doc-bounds point))) + (when bounds + (let* ((beg (plist-get bounds :beg)) + (end (plist-get bounds :end)) + (overlays (overlays-in beg end)) + anything-done) + (dolist (ov overlays) + (when (overlay-get ov 'doc-mode-fold) + (setq anything-done t) + (delete-overlay ov) + (setq doc-mode-folds (delq ov doc-mode-folds)))) + ;; return non-nil, if anything unfolded + ;; this is used to toggle + anything-done)))) + +;;;###autoload +(defun doc-mode-unfold-tag-doc (tag) + "Unfold the documentation for TAG. +If called interactively, use the tag given by `doc-mode-current-tag'." + (interactive (list (doc-mode-current-tag-or-bust))) + (unless doc-mode + (error "doc-mode not enabled")) + (doc-mode-unfold-doc (semantic-tag-start tag))) + +;;;###autoload +(defun doc-mode-fold-all (&optional arg) + (interactive "P") + (unless doc-mode + (error "doc-mode not enabled")) + (if arg + (doc-mode-unfold-all) + (dolist (tag (doc-mode-find-eligible-tags)) + (doc-mode-fold-tag-doc tag)))) + +;;;###autoload +(defun doc-mode-unfold-all () + (interactive) + (dolist (ov doc-mode-folds) + (delete-overlay ov)) + (kill-local-variable 'doc-mode-folds)) + +;;; toggle + +;;;###autoload +(defun doc-mode-toggle-tag-doc-folding (tag) + "Toggle folding of TAG's documentation. +If called interactively, use the tag given by `doc-mode-current-tag'." + (interactive (list (doc-mode-current-tag-or-bust))) + (or (doc-mode-unfold-tag-doc tag) + (doc-mode-fold-tag-doc tag))) + +(provide 'doc-mode) + +;;; doc-mode.el ends here diff --git a/one-file-mode/dockerfile-mode.el b/one-file-mode/dockerfile-mode.el new file mode 100644 index 0000000..0bd78ae --- /dev/null +++ b/one-file-mode/dockerfile-mode.el @@ -0,0 +1,168 @@ +;;; dockerfile-mode.el --- Major mode for editing Docker's Dockerfiles + +;; Copyright (c) 2013 Spotify AB +;; +;; Licensed under the Apache License, Version 2.0 (the "License"); you may not +;; use this file except in compliance with the License. You may obtain a copy of +;; the License at +;; +;; http://www.apache.org/licenses/LICENSE-2.0 +;; +;; Unless required by applicable law or agreed to in writing, software +;; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +;; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +;; License for the specific language governing permissions and limitations under +;; the License. + +;;; Code: + +(require 'sh-script) +(require 'rx) + +(declare-function cygwin-convert-file-name-to-windows "cygw32.c" (file &optional absolute-p)) + +(defvar docker-image-name nil) + +(defgroup dockerfile nil + "dockerfile code editing commands for Emacs." + :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) + :prefix "dockerfile-" + :group 'languages) + +(defcustom dockerfile-mode-hook nil + "*Hook called by `dockerfile-mode'." + :type 'hook + :group 'dockerfile) + +(defcustom dockerfile-use-sudo nil + "Runs docker builder command with sudo.") + +(defcustom dockerfile-build-args nil + "List of --build-arg to pass to docker build. + +Each element of the list will be passed as a separate + --build-arg to the docker build command." + :type '(repeat string) + :group 'dockerfile) + +(defvar dockerfile-font-lock-keywords + `(,(cons (rx (or line-start "onbuild ") + (group (or "from" "maintainer" "run" "cmd" "expose" "env" "arg" + "add" "copy" "entrypoint" "volume" "user" "workdir" "onbuild" + "label" "stopsignal")) + word-boundary) + font-lock-keyword-face) + ,@(sh-font-lock-keywords) + ,@(sh-font-lock-keywords-2) + ,@(sh-font-lock-keywords-1)) + "Default font-lock-keywords for `dockerfile mode'.") + +(defvar dockerfile-mode-map + (let ((map (make-sparse-keymap)) + (menu-map (make-sparse-keymap))) + (define-key map "\C-c\C-b" 'dockerfile-build-buffer) + (define-key map "\C-c\M-b" 'dockerfile-build-no-cache-buffer) + (define-key map "\C-c\C-z" 'dockerfile-test-function) + (define-key map "\C-c\C-c" 'comment-region) + (define-key map [menu-bar dockerfile-mode] (cons "Dockerfile" menu-map)) + (define-key menu-map [dfc] + '(menu-item "Comment Region" comment-region + :help "Comment Region")) + (define-key menu-map [dfb] + '(menu-item "Build" dockerfile-build-buffer + :help "Send the Dockerfile to docker build")) + (define-key menu-map [dfb] + '(menu-item "Build without cache" dockerfile-build-no-cache-buffer + :help "Send the Dockerfile to docker build without cache")) + map)) + +(defvar dockerfile-mode-syntax-table + (let ((table (make-syntax-table))) + (modify-syntax-entry ?# "<" table) + (modify-syntax-entry ?\n ">" table) + (modify-syntax-entry ?' "\"" table) + table) + "Syntax table for `dockerfile-mode'.") + +(define-abbrev-table 'dockerfile-mode-abbrev-table nil + "Abbrev table used while in `dockerfile-mode'.") + +(unless dockerfile-mode-abbrev-table + (define-abbrev-table 'dockerfile-mode-abbrev-table ())) + +(defun dockerfile-build-arg-string () + "Create a --build-arg string for each element in `dockerfile-build-args'." + (mapconcat (lambda (arg) (concat "--build-arg " "\"" arg "\"")) + dockerfile-build-args " ")) + +(defun standard-filename (file) + "Convert the file name to OS standard. +If in Cygwin environment, uses Cygwin specific function to convert the +file name. Otherwise, uses Emacs' standard conversion function." + (format "%s" (if (fboundp 'cygwin-convert-file-name-to-windows) + (s-replace "\\" "\\\\" (cygwin-convert-file-name-to-windows file)) + (convert-standard-filename file)))) + +;;;###autoload +(defun dockerfile-build-buffer (image-name) + "Build an image based upon the buffer" + (interactive + (if (null docker-image-name) + (list (read-string "image-name: " nil nil)) + (list docker-image-name))) + (save-buffer) + (if (stringp image-name) + (async-shell-command + (format "%sdocker build -t %s %s -f \"%s\" \"%s\"" + (if dockerfile-use-sudo "sudo " "") + image-name + (dockerfile-build-arg-string) + (standard-filename (buffer-file-name)) + (standard-filename (file-name-directory (buffer-file-name)))) + "*docker-build-output*") + (print "docker-image-name must be a string, consider surrounding it with double quotes"))) + +;;;###autoload +(defun dockerfile-build-no-cache-buffer (image-name) + "Build an image based upon the buffer without cache" + (interactive + (if (null docker-image-name) + (list (read-string "image-name: " nil nil)) + (list docker-image-name))) + (save-buffer) + (if (stringp image-name) + (async-shell-command + (format "%s docker build --no-cache -t %s %s -f \"%s\" \"%s\"" + (if dockerfile-use-sudo "sudo" "") + image-name + (dockerfile-build-arg-string) + (standard-filename (buffer-file-name)) + (standard-filename (file-name-directory (buffer-file-name)))) + "*docker-build-output*") + (print "docker-image-name must be a string, consider surrounding it with double quotes"))) + +;; Handle emacs < 24, which does not have prog-mode +(defalias 'dockerfile-parent-mode + (if (fboundp 'prog-mode) 'prog-mode 'fundamental-mode)) + +;;;###autoload +(define-derived-mode dockerfile-mode dockerfile-parent-mode "Dockerfile" + "A major mode to edit Dockerfiles. +\\{dockerfile-mode-map} +" + (set-syntax-table dockerfile-mode-syntax-table) + (set (make-local-variable 'require-final-newline) mode-require-final-newline) + (set (make-local-variable 'comment-start) "#") + (set (make-local-variable 'comment-end) "") + (set (make-local-variable 'comment-start-skip) "#+ *") + (set (make-local-variable 'parse-sexp-ignore-comments) t) + (set (make-local-variable 'font-lock-defaults) + '(dockerfile-font-lock-keywords nil t)) + (setq local-abbrev-table dockerfile-mode-abbrev-table)) + +;;;###autoload +(add-to-list 'auto-mode-alist '("Dockerfile.*\\'" . dockerfile-mode)) + +(provide 'dockerfile-mode) + +;;; dockerfile-mode.el ends here diff --git a/one-file-mode/go-template-mode.el b/one-file-mode/go-template-mode.el new file mode 100644 index 0000000..8083b8e --- /dev/null +++ b/one-file-mode/go-template-mode.el @@ -0,0 +1,267 @@ +;;; go-template-mode.el --- Major mode for Go template language + +;;; Commentary: + +;; 1) Copy this file somewhere in your Emacs `load-path'. To see what +;; your `load-path' is, run inside emacs: C-h v load-path +;; +;; 2) Add the following to your .emacs file: +;; +;; (require 'go-template-mode) + +;;; Known Bugs: + +;; 1) Highlights all strings in the source file, including HTML attributes, +;; and does not properly highlight template actions inside these strings. + +(defvar go-template-mode-syntax-table + (let ((st (make-syntax-table))) + ;; Add _ to :word: character class + (modify-syntax-entry ?_ "w" st) + + ;; Operators (punctuation) + (modify-syntax-entry ?: "." st) + (modify-syntax-entry ?= "." st) + (modify-syntax-entry ?| "." st) + + ;; Strings and comments are font-locked separately. + (modify-syntax-entry ?\" "." st) + (modify-syntax-entry ?\' "." st) + (modify-syntax-entry ?` "." st) + (modify-syntax-entry ?\\ "." st) + + st) + "Syntax table for Go template mode.") + +(defvar go-template-mode-keywords + '("define" "else" "end" "if" "range" "template" "with") + "All keywords in the Go template language. Used for font locking.") + +(defvar go-template-mode-builtins + '("and" "html" "index" "js" "len" "not" "or" "print" "printf" "println" "urlquery") + "All builtin functions in the Go template language. Used for font locking.") + + +(defconst go-template-mode-pair-tag + (regexp-opt + '("a" "abbr" "acronym" "address" "applet" "area" "b" "bdo" + "big" "blockquote" "body" "button" "caption" "center" "cite" + "code" "col" "colgroup" "dd" "del" "dfn" "dif" "div" "dl" + "dt" "em" "fieldset" "font" "form" "frame" "frameset" "h1" + "header" "nav" "footer" "section" + "h2" "h3" "h4" "h5" "h6" "head" "html" "i" "iframe" "ins" + "kbd" "label" "legend" "li" "link" "map" "menu" "noframes" + "noscript" "object" "ol" "optgroup" "option" "p" "pre" "q" + "s" "samp" "script" "select" "small" "span" "strike" + "strong" "style" "sub" "sup" "table" "tbody" "td" "textarea" + "tfoot" "th" "thead" "title" "tr" "tt" "u" "ul" "var") + t)) +(defconst go-template-mode-standalone-tag + (regexp-opt + '("base" "br" "hr" "img" "input" "meta" "param") + t)) + +(defconst go-template-mode-font-lock-keywords + `((go-template-mode-font-lock-cs-comment 0 font-lock-comment-face t) + (go-template-mode-font-lock-cs-string 0 font-lock-string-face t) + (,(regexp-opt '("{{" "}}")) (0 font-lock-preprocessor-face)) + ("$[a-zA-Z0-9]*" (0 font-lock-variable-name-face)) + (,(regexp-opt go-template-mode-keywords 'words) . font-lock-keyword-face) + (,(regexp-opt go-template-mode-builtins 'words) . font-lock-builtin-face) + (,(concat "?") (0 font-lock-function-name-face)) + (,(concat "<" go-template-mode-standalone-tag ">?") (0 font-lock-function-name-face)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Parser +;; + +(defvar go-template-mode-mark-cs-end 1 + "The point at which the comment/string cache ends. The buffer +will be marked from the beginning up to this point (that is, up +to and including character (1- go-template-mode-mark-cs-end)).") +(make-variable-buffer-local 'go-template-mode-mark-cs-end) + +(defvar go-template-mode-mark-nesting-end 1 + "The point at which the nesting cache ends. The buffer will be +marked from the beginning up to this point.") +(make-variable-buffer-local 'go-template-mode-mark-nesting-end) + +(defun go-template-mode-mark-clear-cache (b e) + "A before-change-function that clears the comment/string and +nesting caches from the modified point on." + + (save-restriction + (widen) + (when (<= b go-template-mode-mark-cs-end) + ;; Remove the property adjacent to the change position. + ;; It may contain positions pointing beyond the new end mark. + (let ((b (let ((cs (get-text-property (max 1 (1- b)) 'go-template-mode-cs))) + (if cs (car cs) b)))) + (remove-text-properties + b (min go-template-mode-mark-cs-end (point-max)) '(go-template-mode-cs nil)) + (setq go-template-mode-mark-cs-end b))) + (when (< b go-template-mode-mark-nesting-end) + (remove-text-properties b (min go-template-mode-mark-nesting-end (point-max)) '(go-template-mode-nesting nil)) + (setq go-template-mode-mark-nesting-end b)))) + +(defmacro go-template-mode-parser (&rest body) + "Evaluate BODY in an environment set up for parsers that use +text properties to mark text. This inhibits changes to the undo +list or the buffer's modification status and inhibits calls to +the modification hooks. It also saves the excursion and +restriction and widens the buffer, since most parsers are +context-sensitive." + + (let ((modified-var (make-symbol "modified"))) + `(let ((buffer-undo-list t) + (,modified-var (buffer-modified-p)) + (inhibit-modification-hooks t) + (inhibit-read-only t)) + (save-excursion + (save-restriction + (widen) + (unwind-protect + (progn ,@body) + (set-buffer-modified-p ,modified-var))))))) + +(defun go-template-mode-cs (&optional pos) + "Return the comment/string state at point POS. If point is +inside a comment or string (including the delimiters), this +returns a pair (START . END) indicating the extents of the +comment or string." + + (unless pos + (setq pos (point))) + (when (> pos go-template-mode-mark-cs-end) + (go-template-mode-mark-cs pos)) + (get-text-property pos 'go-template-mode-cs)) + +(defun go-template-mode-mark-cs (end) + "Mark comments and strings up to point END. Don't call this +directly; use `go-template-mode-cs'." + (setq end (min end (point-max))) + (go-template-mode-parser + (save-match-data + (let ((pos + ;; Back up to the last known state. + (let ((last-cs + (and (> go-template-mode-mark-cs-end 1) + (get-text-property (1- go-template-mode-mark-cs-end) + 'go-template-mode-cs)))) + (if last-cs + (car last-cs) + (max 1 (1- go-template-mode-mark-cs-end)))))) + (while (< pos end) + (goto-char pos) + (let ((cs-end ; end of the text property + (cond + ((looking-at "{{/\\*") + (goto-char (+ pos 4)) + (if (search-forward "*/}}" (1+ end) t) + (point) + end)) + ((looking-at "\"") + (goto-char (1+ pos)) + (if (looking-at "[^\"\n\\\\]*\\(\\\\.[^\"\n\\\\]*\\)*\"") + (match-end 0) + (end-of-line) + (point))) + ((looking-at "'") + (goto-char (1+ pos)) + (if (looking-at "[^'\n\\\\]*\\(\\\\.[^'\n\\\\]*\\)*'") + (match-end 0) + (end-of-line) + (point))) + ((looking-at "`") + (goto-char (1+ pos)) + (while (if (search-forward "`" end t) + (if (eq (char-after) ?`) + (goto-char (1+ (point)))) + (goto-char end) + nil)) + (point))))) + (cond + (cs-end + (put-text-property pos cs-end 'go-template-mode-cs (cons pos cs-end)) + (setq pos cs-end)) + ((re-search-forward "[\"'`]\\|{{/\\*" end t) + (setq pos (match-beginning 0))) + (t + (setq pos end))))) + (setq go-template-mode-mark-cs-end pos))))) + + + +(defun go-template-mode-font-lock-cs (limit comment) + "Helper function for highlighting comment/strings. If COMMENT is t, +set match data to the next comment after point, and advance point +after it. If COMMENT is nil, use the next string. Returns nil +if no further tokens of the type exist." + ;; Ensures that `next-single-property-change' below will work properly. + (go-template-mode-cs limit) + (let (cs next (result 'scan)) + (while (eq result 'scan) + (if (or (>= (point) limit) (eobp)) + (setq result nil) + (setq cs (go-template-mode-cs)) + (if cs + (if (eq (= (char-after (car cs)) ?/) comment) + ;; If inside the expected comment/string, highlight it. + (progn + ;; If the match includes a "\n", we have a + ;; multi-line construct. Mark it as such. + (goto-char (car cs)) + (when (search-forward "\n" (cdr cs) t) + (put-text-property + (car cs) (cdr cs) 'font-lock-multline t)) + (set-match-data (list (car cs) (cdr cs) (current-buffer))) + (goto-char (cdr cs)) + (setq result t)) + ;; Wrong type. Look for next comment/string after this one. + (goto-char (cdr cs))) + ;; Not inside comment/string. Search for next comment/string. + (setq next (next-single-property-change + (point) 'go-template-mode-cs nil limit)) + (if (and next (< next limit)) + (goto-char next) + (setq result nil))))) + result)) + +(defun go-template-mode-font-lock-cs-string (limit) + "Font-lock iterator for strings." + (go-template-mode-font-lock-cs limit nil)) + +(defun go-template-mode-font-lock-cs-comment (limit) + "Font-lock iterator for comments." + (go-template-mode-font-lock-cs limit t)) + +;;;###autoload +(define-derived-mode go-template-mode fundamental-mode "Go-Template" + "Major mode for editing Go template text. + +This provides basic syntax highlighting for keyword, built-ins, functions, +and some types. It does not provide indentation." + + ;; Font lock + (set (make-local-variable 'font-lock-defaults) + '(go-template-mode-font-lock-keywords nil nil nil nil)) + + ;; Remove stale text properties + (save-restriction + (widen) + (remove-text-properties 1 (point-max) + '(go-template-mode-cs nil go-template-mode-nesting nil))) + + ;; Reset the syntax mark caches + (setq go-template-mode-mark-cs-end 1 + go-template-mode-mark-nesting-end 1) + (add-hook 'before-change-functions #'go-template-mode-mark-clear-cache nil t) + + ;; Use tabs (Go style) + (setq indent-tabs-mode t)) + +(add-to-list 'auto-mode-alist '("\\.gotmpl$" . go-template-mode)) + +(provide 'go-template-mode) + +;;; go-template-mode.el ends here \ No newline at end of file diff --git a/one-file-mode/use-package.el b/one-file-mode/use-package.el new file mode 100644 index 0000000..9437c21 --- /dev/null +++ b/one-file-mode/use-package.el @@ -0,0 +1,1169 @@ +;;; use-package.el --- A use-package declaration for simplifying your .emacs + +;; Copyright (C) 2012 John Wiegley + +;; Author: John Wiegley +;; Maintainer: John Wiegley +;; Created: 17 Jun 2012 +;; Modified: 26 Sep 2015 +;; Version: 2.1 +;; Package-Requires: ((bind-key "1.0") (diminish "0.44")) +;; Keywords: dotemacs startup speed config package +;; URL: https://github.com/jwiegley/use-package + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as +;; published by the Free Software Foundation; either version 2, or (at +;; your option) any later version. + +;; This program is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; The `use-package' declaration macro allows you to isolate package +;; configuration in your ".emacs" in a way that is performance-oriented and, +;; well, just tidy. I created it because I have over 80 packages that I use +;; in Emacs, and things were getting difficult to manage. Yet with this +;; utility my total load time is just under 1 second, with no loss of +;; functionality! +;; +;; Please see README.md from the same repository for documentation. + +;;; Code: + +(require 'bind-key) +(require 'bytecomp) +(require 'diminish nil t) +(require 'bytecomp) +(eval-when-compile (require 'cl)) + +(declare-function package-installed-p 'package) + +(defgroup use-package nil + "A use-package declaration for simplifying your `.emacs'." + :group 'startup) + +(defcustom use-package-verbose nil + "Whether to report about loading and configuration details. + +If you customize this, then you should require the `use-package' +feature in files that use `use-package', even if these files only +contain compiled expansions of the macros. If you don't do so, +then the expanded macros do their job silently." + :type '(choice (const :tag "Quiet" nil) (const :tag "Verbose" t) + (const :tag "Debug" debug)) + :group 'use-package) + +(defcustom use-package-debug nil + "Whether to display use-package expansions in a *use-package* buffer." + :type 'boolean + :group 'use-package) + +(defcustom use-package-check-before-init nil + "If non-nil, check that package exists before executing its `:init' block. +The check is performed by looking for the module using `locate-library'." + :type 'boolean + :group 'use-package) + +(defcustom use-package-always-defer nil + "If non-nil, assume `:defer t` unless `:demand t` is given." + :type 'boolean + :group 'use-package) + +(defcustom use-package-always-ensure nil + "Treat every package as though it had specified `:ensure SEXP`." + :type 'sexp + :group 'use-package) + +(defcustom use-package-always-pin nil + "Treat every package as though it had specified `:pin SYM." + :type 'symbol + :group 'use-package) + +(defcustom use-package-minimum-reported-time 0.1 + "Minimal load time that will be reported. + +Note that `use-package-verbose' has to be set to t, for anything +to be reported at all. + +If you customize this, then you should require the `use-package' +feature in files that use `use-package', even if these files only +contain compiled expansions of the macros. If you don't do so, +then the expanded macros do their job silently." + :type 'number + :group 'use-package) + +(defcustom use-package-inject-hooks nil + "If non-nil, add hooks to the `:init' and `:config' sections. +In particular, for a given package `foo', the following hooks +become available: + + `use-package--foo--pre-init-hook' + `use-package--foo--post-init-hook' + `use-package--foo--pre-config-hook' + `use-package--foo--post-config-hook' + +This way, you can add to these hooks before evalaution of a +`use-package` declaration, and exercise some control over what +happens. + +Note that if either `pre-init' hooks returns a nil value, that +block's user-supplied configuration is not evaluated, so be +certain to return `t' if you only wish to add behavior to what +the user specified." + :type 'boolean + :group 'use-package) + +(defcustom use-package-keywords + '(:disabled + :pin + :ensure + :if + :when + :unless + :requires + :load-path + :preface + :no-require + :bind + :bind* + :bind-keymap + :bind-keymap* + :interpreter + :mode + :commands + :defines + :functions + :defer + :after + :demand + :init + :config + :diminish + :delight) + "Establish which keywords are valid, and the order they are processed in. + +Note that `:disabled' is special, in that it causes nothing at all to happen, +even if the rest of the use-package declaration is incorrect." + :type '(repeat symbol) + :group 'use-package) + +(defcustom use-package-expand-minimally nil + "If non-nil, make the expanded code as minimal as possible. +This disables: + - Printing to the *Messages* buffer of slowly-evaluating forms + - Capture of load errors (normally redisplayed as warnings) + - Conditional loading of packages (load failures become errors) +The only advantage is that, if you know your configuration works, +then your byte-compiled init file is as minimal as possible." + :type 'boolean + :group 'use-package) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Utility functions +;; + +(defun use-package-as-symbol (string-or-symbol) + "If STRING-OR-SYMBOL is already a symbol, return it. Otherwise +convert it to a symbol and return that." + (if (symbolp string-or-symbol) string-or-symbol + (intern string-or-symbol))) + +(defun use-package-as-string (string-or-symbol) + "If STRING-OR-SYMBOL is already a string, return it. Otherwise +convert it to a string and return that." + (if (stringp string-or-symbol) string-or-symbol + (symbol-name string-or-symbol))) + +(defun use-package-load-name (name &optional noerror) + "Return a form which will load or require NAME depending on +whether it's a string or symbol." + (if (stringp name) + `(load ,name 'noerror) + `(require ',name nil 'noerror))) + +(defun use-package-expand (name label form) + "FORM is a list of forms, so `((foo))' if only `foo' is being called." + (declare (indent 1)) + (when form + (if use-package-expand-minimally + form + (let ((err (make-symbol "err"))) + (list + `(condition-case-unless-debug ,err + ,(macroexp-progn form) + (error + (ignore + (display-warning 'use-package + (format "%s %s: %s" + ,name ,label (error-message-string ,err)) + :error))))))))) + +(put 'use-package-expand 'lisp-indent-function 'defun) + +(defun use-package-hook-injector (name-string keyword body) + "Wrap pre/post hook injections around a given keyword form. +ARGS is a list of forms, so `((foo))' if only `foo' is being called." + (if (not use-package-inject-hooks) + (use-package-expand name-string (format "%s" keyword) body) + (let ((keyword-name (substring (format "%s" keyword) 1))) + (when body + `((when ,(macroexp-progn + (use-package-expand name-string (format "pre-%s hook" keyword) + `((run-hook-with-args-until-failure + ',(intern (concat "use-package--" name-string + "--pre-" keyword-name "-hook")))))) + ,(macroexp-progn + (use-package-expand name-string (format "%s" keyword) body)) + ,(macroexp-progn + (use-package-expand name-string (format "post-%s hook" keyword) + `((run-hooks + ',(intern (concat "use-package--" name-string + "--post-" keyword-name "-hook")))))))))))) + +(defun use-package--with-elapsed-timer (text body) + "BODY is a list of forms, so `((foo))' if only `foo' is being called." + (declare (indent 1)) + (if use-package-expand-minimally + body + (let ((nowvar (make-symbol "now"))) + (if (bound-and-true-p use-package-verbose) + `((let ((,nowvar (current-time))) + (message "%s..." ,text) + (prog1 + ,(macroexp-progn body) + (let ((elapsed + (float-time (time-subtract (current-time) ,nowvar)))) + (if (> elapsed ,use-package-minimum-reported-time) + (message "%s...done (%.3fs)" ,text elapsed) + (message "%s...done" ,text)))))) + body)))) + +(put 'use-package--with-elapsed-timer 'lisp-indent-function 1) + +(defsubst use-package-error (msg) + "Report MSG as an error, so the user knows it came from this package." + (error "use-package: %s" msg)) + +(defsubst use-package-plist-maybe-put (plist property value) + "Add a VALUE for PROPERTY to PLIST, if it does not already exist." + (if (plist-member plist property) + plist + (plist-put plist property value))) + +(defsubst use-package-plist-cons (plist property value) + "Cons VALUE onto the head of the list at PROPERTY in PLIST." + (plist-put plist property (cons value (plist-get plist property)))) + +(defsubst use-package-plist-append (plist property value) + "Append VALUE onto the front of the list at PROPERTY in PLIST." + (plist-put plist property (append value (plist-get plist property)))) + +(defun use-package-plist-delete (plist property) + "Delete PROPERTY from PLIST. +This is in contrast to merely setting it to 0." + (let (p) + (while plist + (if (not (eq property (car plist))) + (setq p (plist-put p (car plist) (nth 1 plist)))) + (setq plist (cddr plist))) + p)) + +(defun use-package-split-list (pred xs) + (let ((ys (list nil)) (zs (list nil)) flip) + (dolist (x xs) + (if flip + (nconc zs (list x)) + (if (funcall pred x) + (progn + (setq flip t) + (nconc zs (list x))) + (nconc ys (list x))))) + (cons (cdr ys) (cdr zs)))) + +(defun use-package-keyword-index (keyword) + (loop named outer + with index = 0 + for k in use-package-keywords do + (if (eq k keyword) + (return-from outer index)) + (incf index))) + +(defun use-package-sort-keywords (plist) + (let (plist-grouped) + (while plist + (push (cons (car plist) (cadr plist)) + plist-grouped) + (setq plist (cddr plist))) + (let (result) + (dolist (x + (nreverse + (sort plist-grouped + #'(lambda (l r) (< (use-package-keyword-index (car l)) + (use-package-keyword-index (car r))))))) + (setq result (cons (car x) (cons (cdr x) result)))) + result))) + +(defsubst use-package-concat (&rest elems) + "Delete all empty lists from ELEMS (nil or (list nil)), and append them." + (apply #'nconc (delete nil (delete (list nil) elems)))) + +(defconst use-package-font-lock-keywords + '(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?" + (1 font-lock-keyword-face) + (2 font-lock-constant-face nil t)))) + +(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Keyword processing +;; + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Normalization functions +;; + +(defun use-package-normalize-plist (name input) + "Given a pseudo-plist, normalize it to a regular plist." + (unless (null input) + (let* ((keyword (car input)) + (xs (use-package-split-list #'keywordp (cdr input))) + (args (car xs)) + (tail (cdr xs)) + (normalizer (intern (concat "use-package-normalize/" + (symbol-name keyword)))) + (arg + (cond + ((eq keyword :disabled) + (use-package-normalize-plist name tail)) + ((functionp normalizer) + (funcall normalizer name keyword args)) + ((= (length args) 1) + (car args)) + (t + args)))) + (if (memq keyword use-package-keywords) + (cons keyword + (cons arg (use-package-normalize-plist name tail))) + (use-package-error (format "Unrecognized keyword: %s" keyword)))))) + +(defun use-package-process-keywords (name plist &optional state) + "Process the next keyword in the free-form property list PLIST. +The values in the PLIST have each been normalized by the function +use-package-normalize/KEYWORD (minus the colon). + +STATE is a property list that the function may modify and/or +query. This is useful if a package defines multiple keywords and +wishes them to have some kind of stateful interaction. + +Unless the KEYWORD being processed intends to ignore remaining +keywords, it must call this function recursively, passing in the +plist with its keyword and argument removed, and passing in the +next value for the STATE." + (declare (indent 1)) + (unless (null plist) + (let* ((keyword (car plist)) + (arg (cadr plist)) + (rest (cddr plist))) + (unless (keywordp keyword) + (use-package-error (format "%s is not a keyword" keyword))) + (let* ((handler (concat "use-package-handler/" (symbol-name keyword))) + (handler-sym (intern handler))) + (if (functionp handler-sym) + (funcall handler-sym name keyword arg rest state) + (use-package-error + (format "Keyword handler not defined: %s" handler))))))) + +(put 'use-package-process-keywords 'lisp-indent-function 'defun) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :pin +;; + +(defun use-package-only-one (label args f) + "Call F on the first member of ARGS if it has exactly one element." + (declare (indent 1)) + (cond + ((and (listp args) (listp (cdr args)) + (= (length args) 1)) + (funcall f label (car args))) + (t + (use-package-error + (concat label " wants exactly one argument"))))) + +(put 'use-package-only-one 'lisp-indent-function 'defun) + +(defun use-package-normalize/:pin (name keyword args) + (use-package-only-one (symbol-name keyword) args + (lambda (label arg) + (cond + ((stringp arg) arg) + ((symbolp arg) (symbol-name arg)) + (t + (use-package-error + ":pin wants an archive name (a string)")))))) + +(eval-when-compile + (defvar package-pinned-packages) + (defvar package-archives)) + +(defun use-package--archive-exists-p (archive) + "Check if a given ARCHIVE is enabled. + +ARCHIVE can be a string or a symbol or 'manual to indicate a +manually updated package." + (if (member archive '(manual "manual")) + 't + (let ((valid nil)) + (dolist (pa package-archives) + (when (member archive (list (car pa) (intern (car pa)))) + (setq valid 't))) + valid))) + +(defun use-package-pin-package (package archive) + "Pin PACKAGE to ARCHIVE." + (unless (boundp 'package-pinned-packages) + (setq package-pinned-packages ())) + (let ((archive-symbol (if (symbolp archive) archive (intern archive))) + (archive-name (if (stringp archive) archive (symbol-name archive)))) + (if (use-package--archive-exists-p archive-symbol) + (add-to-list 'package-pinned-packages (cons package archive-name)) + (error "Archive '%s' requested for package '%s' is not available." + archive-name package)) + (unless (bound-and-true-p package--initialized) + (package-initialize t)))) + +(defun use-package-handler/:pin (name keyword archive-name rest state) + (let ((body (use-package-process-keywords name rest state)) + (pin-form (if archive-name + `(use-package-pin-package ',(use-package-as-symbol name) + ,archive-name)))) + ;; Pinning should occur just before ensuring + ;; See `use-package-handler/:ensure'. + (if (bound-and-true-p byte-compile-current-file) + (eval pin-form) ; Eval when byte-compiling, + (push pin-form body)) ; or else wait until runtime. + body)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :ensure +;; +(defvar package-archive-contents) +(defun use-package-normalize/:ensure (name keyword args) + (if (null args) + t + (use-package-only-one (symbol-name keyword) args + (lambda (label arg) + (if (symbolp arg) + arg + (use-package-error + (concat ":ensure wants an optional package name " + "(an unquoted symbol name)"))))))) + +(defun use-package-ensure-elpa (package &optional no-refresh) + (if (package-installed-p package) + t + (if (or (assoc package package-archive-contents) no-refresh) + (if (boundp 'package-selected-packages) + (package-install package t) + (package-install package)) + (progn + (package-refresh-contents) + (use-package-ensure-elpa package t))))) + +(defun use-package-handler/:ensure (name keyword ensure rest state) + (let* ((body (use-package-process-keywords name rest state)) + (package-name (or (and (eq ensure t) (use-package-as-symbol name)) ensure)) + (ensure-form (if package-name + `(progn (require 'package) + (use-package-ensure-elpa ',package-name))))) + ;; We want to avoid installing packages when the `use-package' + ;; macro is being macro-expanded by elisp completion (see + ;; `lisp--local-variables'), but still do install packages when + ;; byte-compiling to avoid requiring `package' at runtime. + (if (bound-and-true-p byte-compile-current-file) + (eval ensure-form) ; Eval when byte-compiling, + (push ensure-form body)) ; or else wait until runtime. + body)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :if, :when and :unless +;; + +(defsubst use-package-normalize-value (label arg) + "Normalize a value." + (cond ((symbolp arg) + `(symbol-value ',arg)) + ((functionp arg) + `(funcall #',arg)) + (t arg))) + +(defun use-package-normalize-test (name keyword args) + (use-package-only-one (symbol-name keyword) args + #'use-package-normalize-value)) + +(defalias 'use-package-normalize/:if 'use-package-normalize-test) +(defalias 'use-package-normalize/:when 'use-package-normalize-test) +(defalias 'use-package-normalize/:unless 'use-package-normalize-test) + +(defun use-package-handler/:if (name keyword pred rest state) + (let ((body (use-package-process-keywords name rest state))) + `((when ,pred ,@body)))) + +(defalias 'use-package-handler/:when 'use-package-handler/:if) + +(defun use-package-handler/:unless (name keyword pred rest state) + (let ((body (use-package-process-keywords name rest state))) + `((unless ,pred ,@body)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :requires +;; + +(defun use-package-as-one (label args f) + "Call F on the first element of ARGS if it has one element, or all of ARGS." + (declare (indent 1)) + (if (and (listp args) (listp (cdr args))) + (if (= (length args) 1) + (funcall f label (car args)) + (funcall f label args)) + (use-package-error + (concat label " wants a list")))) + +(put 'use-package-as-one 'lisp-indent-function 'defun) + +(defun use-package-normalize-symbols (label arg &optional recursed) + "Normalize a list of symbols." + (cond + ((symbolp arg) + (list arg)) + ((and (not recursed) (listp arg) (listp (cdr arg))) + (mapcar #'(lambda (x) (car (use-package-normalize-symbols label x t))) arg)) + (t + (use-package-error + (concat label " wants a symbol, or list of symbols"))))) + +(defun use-package-normalize-symlist (name keyword args) + (use-package-as-one (symbol-name keyword) args + #'use-package-normalize-symbols)) + +(defalias 'use-package-normalize/:requires 'use-package-normalize-symlist) + +(defun use-package-handler/:requires (name keyword requires rest state) + (let ((body (use-package-process-keywords name rest state))) + (if (null requires) + body + `((when ,(if (listp requires) + `(not (member nil (mapcar #'featurep ',requires))) + `(featurep ',requires)) + ,@body))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :load-path +;; + +(defun use-package-normalize-paths (label arg &optional recursed) + "Normalize a list of filesystem paths." + (cond + ((and arg (or (symbolp arg) (functionp arg))) + (let ((value (use-package-normalize-value label arg))) + (use-package-normalize-paths label (eval value)))) + ((stringp arg) + (let ((path (if (file-name-absolute-p arg) + arg + (expand-file-name arg user-emacs-directory)))) + (list path))) + ((and (not recursed) (listp arg) (listp (cdr arg))) + (mapcar #'(lambda (x) + (car (use-package-normalize-paths label x t))) arg)) + (t + (use-package-error + (concat label " wants a directory path, or list of paths"))))) + +(defun use-package-normalize/:load-path (name keyword args) + (use-package-as-one (symbol-name keyword) args + #'use-package-normalize-paths)) + +(defun use-package-handler/:load-path (name keyword arg rest state) + (let ((body (use-package-process-keywords name rest state))) + (use-package-concat + (mapcar #'(lambda (path) + `(eval-and-compile (add-to-list 'load-path ,path))) arg) + body))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :no-require +;; + +(defun use-package-normalize-predicate (name keyword args) + (if (null args) + t + (use-package-only-one (symbol-name keyword) args + #'use-package-normalize-value))) + +(defalias 'use-package-normalize/:no-require 'use-package-normalize-predicate) + +(defun use-package-handler/:no-require (name keyword arg rest state) + ;; This keyword has no functional meaning. + (use-package-process-keywords name rest state)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :preface +;; + +(defun use-package-normalize-form (label args) + "Given a list of forms, return it wrapped in `progn'." + (unless (listp (car args)) + (use-package-error (concat label " wants a sexp or list of sexps"))) + (mapcar #'(lambda (form) + (if (and (consp form) + (eq (car form) 'use-package)) + (macroexpand form) + form)) args)) + +(defun use-package-normalize-forms (name keyword args) + (use-package-normalize-form (symbol-name keyword) args)) + +(defalias 'use-package-normalize/:preface 'use-package-normalize-forms) + +(defun use-package-handler/:preface (name keyword arg rest state) + (let ((body (use-package-process-keywords name rest state))) + (use-package-concat + (unless (null arg) + `((eval-and-compile ,@arg))) + body))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :bind, :bind* +;; + +(defsubst use-package-is-sympair (x &optional allow-vector) + "Return t if X has the type (STRING . SYMBOL)." + (and (consp x) + (or (stringp (car x)) + (and allow-vector (vectorp (car x)))) + (symbolp (cdr x)))) + +(defsubst use-package-is-string-pair (x) + "Return t if X has the type (STRING . STRING)." + (and (consp x) + (stringp (car x)) + (stringp (cdr x)))) + +(defun use-package-normalize-pairs + (name label arg &optional recursed allow-vector allow-string-cdrs) + "Normalize a list of string/symbol pairs. +If RECURSED is non-nil, recurse into sublists. +If ALLOW-VECTOR is non-nil, then the key to bind may specify a +vector of keys, as accepted by `define-key'. +If ALLOW-STRING-CDRS is non-nil, then the command name to bind to +may also be a string, as accepted by `define-key'." + (cond + ((or (stringp arg) (and allow-vector (vectorp arg))) + (list (cons arg (use-package-as-symbol name)))) + ((use-package-is-sympair arg allow-vector) + (list arg)) + ((and (not recursed) (listp arg) (listp (cdr arg))) + (mapcar #'(lambda (x) + (let ((ret (use-package-normalize-pairs + name label x t allow-vector allow-string-cdrs))) + (if (listp ret) + (car ret) + ret))) arg)) + ((and allow-string-cdrs (use-package-is-string-pair arg)) + (list arg)) + (t arg))) + +(defun use-package-normalize-binder (name keyword args) + (use-package-as-one (symbol-name keyword) args + (lambda (label arg) + (use-package-normalize-pairs name label arg nil t t)))) + +(defalias 'use-package-normalize/:bind 'use-package-normalize-binder) +(defalias 'use-package-normalize/:bind* 'use-package-normalize-binder) + +(defun use-package-handler/:bind + (name keyword arg rest state &optional bind-macro) + (let ((commands (remq nil (mapcar #'(lambda (arg) + (if (listp arg) + (cdr arg) + nil)) arg)))) + (use-package-concat + (use-package-process-keywords name + (use-package-sort-keywords + (use-package-plist-maybe-put rest :defer t)) + (use-package-plist-append state :commands commands)) + `((ignore + ,(macroexpand + `(,(if bind-macro bind-macro 'bind-keys) + :package ,name ,@arg))))))) + +(defun use-package-handler/:bind* (name keyword arg rest state) + (use-package-handler/:bind name keyword arg rest state 'bind-keys*)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :bind-keymap, :bind-keymap* +;; + +(defalias 'use-package-normalize/:bind-keymap 'use-package-normalize-binder) +(defalias 'use-package-normalize/:bind-keymap* 'use-package-normalize-binder) + +(defun use-package-autoload-keymap (keymap-symbol package override) + "Loads PACKAGE and then binds the key sequence used to invoke +this function to KEYMAP-SYMBOL. It then simulates pressing the +same key sequence a again, so that the next key pressed is routed +to the newly loaded keymap. + +This function supports use-package's :bind-keymap keyword. It +works by binding the given key sequence to an invocation of this +function for a particular keymap. The keymap is expected to be +defined by the package. In this way, loading the package is +deferred until the prefix key sequence is pressed." + (if (not (require package nil t)) + (use-package-error (format "Cannot load package.el: %s" package)) + (if (and (boundp keymap-symbol) + (keymapp (symbol-value keymap-symbol))) + (let* ((kv (this-command-keys-vector)) + (key (key-description kv)) + (keymap (symbol-value keymap-symbol))) + (if override + (bind-key* key keymap) + (bind-key key keymap)) + (setq unread-command-events + (listify-key-sequence kv))) + (use-package-error + (format "use-package: package.el %s failed to define keymap %s" + package keymap-symbol))))) + +(defun use-package-handler/:bind-keymap + (name keyword arg rest state &optional override) + (let ((form (mapcar + #'(lambda (binding) + `(,(if override + 'bind-key* + 'bind-key) + ,(car binding) + #'(lambda () + (interactive) + (use-package-autoload-keymap + ',(cdr binding) ',(use-package-as-symbol name) ,override)))) arg))) + (use-package-concat + (use-package-process-keywords name + (use-package-sort-keywords + (use-package-plist-maybe-put rest :defer t)) + state) + `((ignore ,@form))))) + +(defun use-package-handler/:bind-keymap* (name keyword arg rest state) + (use-package-handler/:bind-keymap name keyword arg rest state t)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :interpreter +;; + +(defun use-package-normalize-mode (name keyword args) + (use-package-as-one (symbol-name keyword) args + (apply-partially #'use-package-normalize-pairs name))) + +(defalias 'use-package-normalize/:interpreter 'use-package-normalize-mode) + +(defun use-package-handler/:interpreter (name keyword arg rest state) + (let* (commands + (form (mapcar #'(lambda (interpreter) + (push (cdr interpreter) commands) + `(add-to-list 'interpreter-mode-alist ',interpreter)) arg))) + (use-package-concat + (use-package-process-keywords name + (use-package-sort-keywords + (use-package-plist-maybe-put rest :defer t)) + (use-package-plist-append state :commands commands)) + `((ignore ,@form))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :mode +;; + +(defalias 'use-package-normalize/:mode 'use-package-normalize-mode) + +(defun use-package-handler/:mode (name keyword arg rest state) + (let* (commands + (form (mapcar #'(lambda (mode) + (push (cdr mode) commands) + `(add-to-list 'auto-mode-alist ',mode)) arg))) + (use-package-concat + (use-package-process-keywords name + (use-package-sort-keywords + (use-package-plist-maybe-put rest :defer t)) + (use-package-plist-append state :commands commands)) + `((ignore ,@form))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :commands +;; + +(defalias 'use-package-normalize/:commands 'use-package-normalize-symlist) + +(defun use-package-handler/:commands (name keyword arg rest state) + ;; The actual processing for commands is done in :defer + (use-package-process-keywords name + (use-package-sort-keywords + (use-package-plist-maybe-put rest :defer t)) + (use-package-plist-append state :commands arg))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :defines +;; + +(defalias 'use-package-normalize/:defines 'use-package-normalize-symlist) + +(defun use-package-handler/:defines (name keyword arg rest state) + (let ((body (use-package-process-keywords name rest state))) + body)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :functions +;; + +(defalias 'use-package-normalize/:functions 'use-package-normalize-symlist) + +(defun use-package-handler/:functions (name keyword arg rest state) + (let ((body (use-package-process-keywords name rest state))) + (if (not (bound-and-true-p byte-compile-current-file)) + body + (use-package-concat + (unless (null arg) + `((eval-when-compile + ,@(mapcar + #'(lambda (fn) + `(declare-function ,fn ,(use-package-as-string name))) arg)))) + body)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :defer +;; + +(defalias 'use-package-normalize/:defer 'use-package-normalize-predicate) + +(defun use-package-handler/:defer (name keyword arg rest state) + (let ((body (use-package-process-keywords name rest + (plist-put state :deferred t))) + (name-string (use-package-as-string name))) + (use-package-concat + ;; Load the package after a set amount of idle time, if the argument to + ;; `:defer' was a number. + (when (numberp arg) + `((run-with-idle-timer ,arg nil #'require ',(use-package-as-symbol name) nil t))) + + ;; Since we deferring load, establish any necessary autoloads, and also + ;; keep the byte-compiler happy. + (apply + #'nconc + (mapcar #'(lambda (command) + (when (not (stringp command)) + (append + `((unless (fboundp ',command) + (autoload #',command ,name-string nil t))) + (when (bound-and-true-p byte-compile-current-file) + `((eval-when-compile + (declare-function ,command ,name-string))))))) + (delete-dups (plist-get state :commands)))) + + body))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :after +;; + +(defalias 'use-package-normalize/:after 'use-package-normalize-symlist) + +(defun use-package-require-after-load (features name) + "Return form for after any of FEATURES require NAME." + `(progn + ,@(mapcar + (lambda (feat) + `(eval-after-load + (quote ,feat) + (quote (require (quote ,name))))) + features))) + +(defun use-package-handler/:after (name keyword arg rest state) + (let ((body (use-package-process-keywords name rest + (plist-put state :deferred t))) + (name-string (use-package-as-string name))) + (use-package-concat + (when arg + (list (use-package-require-after-load arg name))) + body))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :demand +;; + +(defalias 'use-package-normalize/:demand 'use-package-normalize-predicate) + +(defun use-package-handler/:demand (name keyword arg rest state) + (use-package-process-keywords name rest + (use-package-plist-delete state :deferred))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :init +;; + +(defalias 'use-package-normalize/:init 'use-package-normalize-forms) + +(defun use-package-handler/:init (name keyword arg rest state) + (let ((body (use-package-process-keywords name rest state))) + (use-package-concat + ;; The user's initializations + (let ((init-body + (use-package-hook-injector (use-package-as-string name) + :init arg))) + (if use-package-check-before-init + `((if (locate-library ,(use-package-as-string name)) + ,(macroexp-progn init-body))) + init-body)) + body))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :config +;; + +(defalias 'use-package-normalize/:config 'use-package-normalize-forms) + +(defun use-package-handler/:config (name keyword arg rest state) + (let* ((body (use-package-process-keywords name rest state)) + (name-symbol (use-package-as-symbol name)) + (config-body + (if (equal arg '(t)) + body + (use-package--with-elapsed-timer + (format "Configuring package %s" name-symbol) + (use-package-concat + (use-package-hook-injector (symbol-name name-symbol) + :config arg) + body + (list t)))))) + (if (plist-get state :deferred) + (unless (or (null config-body) (equal config-body '(t))) + `((eval-after-load ,(if (symbolp name) `',name name) + ',(macroexp-progn config-body)))) + (use-package--with-elapsed-timer + (format "Loading package %s" name) + (if use-package-expand-minimally + (use-package-concat + (list (use-package-load-name name)) + config-body) + `((if (not ,(use-package-load-name name t)) + (ignore + (message (format "Cannot load %s" ',name))) + ,@config-body))))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :diminish + +(defun use-package-normalize-diminish (name label arg &optional recursed) + "Normalize the arguments to diminish down to a list of one of two forms: + SYMBOL + (SYMBOL . STRING)" + (cond + ((symbolp arg) + (list arg)) + ((stringp arg) + (list (cons (intern (concat (use-package-as-string name) "-mode")) arg))) + ((and (consp arg) (stringp (cdr arg))) + (list arg)) + ((and (not recursed) (listp arg) (listp (cdr arg))) + (mapcar #'(lambda (x) (car (use-package-normalize-diminish + name label x t))) arg)) + (t + (use-package-error + (concat label " wants a string, symbol, " + "(symbol . string) or list of these"))))) + +(defun use-package-normalize/:diminish (name keyword args) + (use-package-as-one (symbol-name keyword) args + (apply-partially #'use-package-normalize-diminish name))) + +(defun use-package-handler/:diminish (name keyword arg rest state) + (let ((body (use-package-process-keywords name rest state))) + (use-package-concat + (mapcar #'(lambda (var) + `(if (fboundp 'diminish) + ,(if (consp var) + `(diminish ',(car var) ,(cdr var)) + `(diminish ',var)))) + arg) + body))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; :delight +;; + +(defun use-package-normalize/:delight (name keyword args) + "Normalize arguments to delight." + (cond + ((and (= (length args) 1) + (symbolp (car args))) + (list (car args) nil name)) + ((and (= (length args) 2) + (symbolp (car args))) + (list (car args) (cadr args) (use-package-as-symbol name))) + ((and (= (length args) 3) + (symbolp (car args))) + args) + (t + (use-package-error ":delight expects same args as delight function")))) + +(defun use-package-handler/:delight (name keyword args rest state) + (let ((body (use-package-process-keywords name rest state))) + (use-package-concat + body + `((delight (quote ,(nth 0 args)) ,(nth 1 args) (quote ,(nth 2 args))) t)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; The main macro +;; + +;;;###autoload +(defmacro use-package (name &rest args) + "Declare an Emacs package by specifying a group of configuration options. + +For full documentation, please see the README file that came with +this file. Usage: + + (use-package package-name + [:keyword [option]]...) + +:init Code to run before PACKAGE-NAME has been loaded. +:config Code to run after PACKAGE-NAME has been loaded. Note that if + loading is deferred for any reason, this code does not execute + until the lazy load has occurred. +:preface Code to be run before everything except `:disabled'; this can + be used to define functions for use in `:if', or that should be + seen by the byte-compiler. + +:mode Form to be added to `auto-mode-alist'. +:interpreter Form to be added to `interpreter-mode-alist'. + +:commands Define autoloads for commands that will be defined by the + package. This is useful if the package is being lazily loaded, + and you wish to conditionally call functions in your `:init' + block that are defined in the package. + +:bind Bind keys, and define autoloads for the bound commands. +:bind* Bind keys, and define autoloads for the bound commands, + *overriding all minor mode bindings*. +:bind-keymap Bind a key prefix to an auto-loaded keymap defined in the + package. This is like `:bind', but for keymaps. +:bind-keymap* Like `:bind-keymap', but overrides all minor mode bindings + +:defer Defer loading of a package -- this is implied when using + `:commands', `:bind', `:bind*', `:mode' or `:interpreter'. + This can be an integer, to force loading after N seconds of + idle time, if the package has not already been loaded. + +:after Defer loading of a package until after any of the named + features are loaded. + +:demand Prevent deferred loading in all cases. + +:if EXPR Initialize and load only if EXPR evaluates to a non-nil value. +:disabled The package is ignored completely if this keyword is present. +:defines Declare certain variables to silence the byte-compiler. +:functions Declare certain functions to silence the byte-compiler. +:load-path Add to the `load-path' before attempting to load the package. +:diminish Support for diminish.el (if installed). +:ensure Loads the package using package.el if necessary. +:pin Pin the package to an archive." + (declare (indent 1)) + (unless (member :disabled args) + (let* ((name-symbol (if (stringp name) (intern name) name)) + (args0 (use-package-plist-maybe-put + (use-package-normalize-plist name args) + :config '(t))) + (args* (use-package-sort-keywords + (if use-package-always-ensure + (use-package-plist-maybe-put + args0 :ensure use-package-always-ensure) + args0))) + (args* (use-package-sort-keywords + (if use-package-always-pin + (use-package-plist-maybe-put + args* :pin use-package-always-pin) + args*)))) + + ;; When byte-compiling, pre-load the package so all its symbols are in + ;; scope. + (if (bound-and-true-p byte-compile-current-file) + (setq args* + (use-package-plist-cons + args* :preface + `(eval-when-compile + ,@(mapcar #'(lambda (var) `(defvar ,var)) + (plist-get args* :defines)) + (with-demoted-errors + ,(format "Cannot load %s: %%S" name) + ,(if (eq use-package-verbose 'debug) + `(message "Compiling package %s" ',name-symbol)) + ,(unless (plist-get args* :no-require) + (use-package-load-name name))))))) + + (let ((body + (macroexp-progn + (use-package-process-keywords name args* + (and use-package-always-defer '(:deferred t)))))) + (if use-package-debug + (display-buffer + (save-current-buffer + (let ((buf (get-buffer-create "*use-package*"))) + (with-current-buffer buf + (delete-region (point-min) (point-max)) + (emacs-lisp-mode) + (insert (pp-to-string body))) + buf)))) + body)))) + + +(put 'use-package 'lisp-indent-function 'defun) + +(provide 'use-package) + +;; Local Variables: +;; indent-tabs-mode: nil +;; End: + +;;; use-package.el ends here diff --git a/one-file-mode/web-mode.el b/one-file-mode/web-mode.el new file mode 100644 index 0000000..97a1678 --- /dev/null +++ b/one-file-mode/web-mode.el @@ -0,0 +1,11830 @@ +;;; web-mode.el --- major mode for editing web templates +;;; -*- coding: utf-8 -*- + +;; Copyright 2011-2016 François-Xavier Bois + +;; Version: 13.1.8 +;; Author: François-Xavier Bois +;; Maintainer: François-Xavier Bois +;; Created: July 2011 +;; Keywords: languages +;; Homepage: http://web-mode.org +;; Repository: http://github.com/fxbois/web-mode +;; License: GNU General Public License >= 2 +;; Distribution: This file is not part of Emacs + +;;============================================================================== +;; WEB-MODE is sponsored by Kernix: ultimate Digital Factory & Data Lab in Paris +;;============================================================================== + +;; Code goes here + +;;---- CONSTS ------------------------------------------------------------------ + +(defconst web-mode-version "13.1.8" + "Web Mode version.") + +;;---- GROUPS ------------------------------------------------------------------ + +(defgroup web-mode nil + "Major mode for editing web templates" + :group 'languages + :prefix "web-" + :link '(url-link :tag "Site" "http://web-mode.org") + :link '(url-link :tag "Repository" "https://github.com/fxbois/web-mode")) + +(defgroup web-mode-faces nil + "Faces for syntax highlighting." + :group 'web-mode + :group 'faces) + +;;---- CUSTOMS ----------------------------------------------------------------- + +(defcustom web-mode-script-padding 1 + "Script element left padding." + :type 'integer + :group 'web-mode) + +(defcustom web-mode-style-padding 1 + "Style element left padding." + :type 'integer + :group 'web-mode) + +(defcustom web-mode-block-padding 0 + "Multi-line block (php, ruby, java, python, asp, etc.) left padding." + :type 'integer + :group 'web-mode) + +(defcustom web-mode-attr-indent-offset nil + "Html attribute indentation level." + :type 'integer + :safe #'integerp + :group 'web-mode) + +(defcustom web-mode-attr-value-indent-offset nil + "Html attribute value indentation level." + :type 'integer + :safe #'integerp + :group 'web-mode) + +(defcustom web-mode-markup-indent-offset + (if (and (boundp 'standard-indent) standard-indent) standard-indent 2) + "Html indentation level." + :type 'integer + :safe #'integerp + :group 'web-mode) + +(defcustom web-mode-css-indent-offset + (if (and (boundp 'standard-indent) standard-indent) standard-indent 2) + "CSS indentation level." + :type 'integer + :safe #'integerp + :group 'web-mode) + +(defcustom web-mode-code-indent-offset + (if (and (boundp 'standard-indent) standard-indent) standard-indent 2) + "Code (javascript, php, etc.) indentation level." + :type 'integer + :safe #'integerp + :group 'web-mode) + +(defcustom web-mode-sql-indent-offset 4 + "Sql (inside strings) indentation level." + :type 'integer + :safe #'integerp + :group 'web-mode) + +(defcustom web-mode-enable-css-colorization (display-graphic-p) + "In a CSS part, set background according to the color: #xxx, rgb(x,x,x)." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-auto-indentation (display-graphic-p) + "Auto-indentation." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-auto-closing (display-graphic-p) + "Auto-closing." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-auto-pairing (display-graphic-p) + "Auto-pairing." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-auto-opening (display-graphic-p) + "Html element auto-opening." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-auto-quoting (display-graphic-p) + "Add double quotes after the character = in a tag." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-auto-expanding nil + "e.g. s/ expands to |." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-control-block-indentation t + "Control blocks increase indentation." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-current-element-highlight nil + "Disable element highlight." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-current-column-highlight nil + "Show column for current element." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-whitespace-fontification nil + "Enable whitespaces." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-html-entities-fontification nil + "Enable html entities fontification." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-block-face nil + "Enable block face (useful for setting a background for example). +See web-mode-block-face." + :type 'boolean + :group 'web-mode) + +(defcustom web-mode-enable-part-face nil + "Enable part face (useful for setting background of ")) + ((string= tname "script") + (let (script) + (setq script (buffer-substring-no-properties tbeg tend) + part-close-tag "") + (cond + ((string-match-p " type[ ]*=[ ]*[\"']text/\\(jsx\\|babel\\)" script) + (setq element-content-type "jsx")) + ((string-match-p " type[ ]*=[ ]*[\"']text/\\(x-handlebars\\|x-jquery-tmpl\\|html\\|ng-template\\|template\\|mustache\\)" script) + (setq element-content-type "html" + part-close-tag nil)) + ((string-match-p " type[ ]*=[ ]*[\"']application/\\(ld\\+json\\|json\\)" script) + (setq element-content-type "json")) + (t + (setq element-content-type "javascript")) + ) ;cond + ) ;let + ) ;script + ) + + (add-text-properties tbeg tend props) + (put-text-property tbeg (1+ tbeg) 'tag-beg flags) + (put-text-property (1- tend) tend 'tag-end t) + + (when (and part-close-tag + (web-mode-dom-sf part-close-tag reg-end t) + (setq part-beg tend) + (setq part-end (match-beginning 0)) + (> part-end part-beg)) + (put-text-property part-beg part-end 'part-side + (intern element-content-type web-mode-obarray)) + (setq tend part-end) + ) ;when + + (goto-char tend) + + ) ;while + + ))) + +;; tag flags +;; (1)attrs (2)custom (4)slash-beg (8)slash-end (16)bracket-end +;; (32)prefix + +;; attr flags +;; (1)custom-attr (2)engine-attr (4)spread-attr[jsx] (8)code-value + +;; attr states +;; (0)nil (1)space (2)name (3)space-before (4)equal (5)space-after +;; (6)value-uq (7)value-sq (8)value-dq (9)value-bq : jsx attr={} + +(defun web-mode-attr-skip (limit) + + (let ((tag-flags 0) (attr-flags 0) (continue t) (attrs 0) (counter 0) (brace-depth 0) + (pos-ori (point)) (state 0) (equal-offset 0) (go-back nil) + (is-jsx (string= web-mode-content-type "jsx")) + name-beg name-end val-beg char pos escaped spaced quoted) + + (while continue + + (setq pos (point) + char (char-after) + spaced (eq char ?\s)) + + (when quoted (setq quoted (1+ quoted))) + + (cond + + ((>= pos limit) + (setq continue nil) + (setq go-back t) + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset))) + ) + + ((or (and (= state 8) (not (member char '(?\" ?\\)))) + (and (= state 7) (not (member char '(?\' ?\\)))) + (and (= state 9) (not (member char '(?} ?\\)))) + ) + (when (and (= state 9) (eq char ?\{)) + (setq brace-depth (1+ brace-depth))) + ) + + ((and (= state 9) (eq char ?\}) (> brace-depth 1)) + (setq brace-depth (1- brace-depth))) + + ((get-text-property pos 'block-side) + (when (= state 2) + (setq name-end pos)) + ) + + ((and (= state 2) is-jsx (eq char ?\}) (eq attr-flags 4)) + (setq name-end pos) + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset))) + (setq state 0 + attr-flags 0 + equal-offset 0 + name-beg nil + name-end nil + val-beg nil) + ) + + ((or (and (= state 8) (eq ?\" char) (not escaped)) + (and (= state 7) (eq ?\' char) (not escaped)) + (and (= state 9) (eq ?\} char) (= brace-depth 1)) + ) + + ;;(message "%S %S" (point) attr-flags) + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset))) + (setq state 0 + attr-flags 0 + equal-offset 0 + name-beg nil + name-end nil + val-beg nil) + ) + + ((and (member state '(4 5)) (member char '(?\' ?\" ?\{))) + (setq val-beg pos) + (setq quoted 1) + (setq state (cond ((eq ?\' char) 7) + ((eq ?\" char) 8) + (t 9))) + (when (= state 9) + (setq brace-depth 1)) + ) + + ((and (eq ?\= char) (member state '(2 3))) + (setq equal-offset (- pos name-beg)) + (setq state 4) + (setq attr (buffer-substring-no-properties name-beg (1+ name-end))) + (when (and web-mode-indentless-attributes (member (downcase attr) web-mode-indentless-attributes)) + ;;(message "onclick") + (setq attr-flags (logior attr-flags 8))) + ) + + ((and spaced (= state 0)) + (setq state 1) + ) + + ((and (eq char ?\<) (not (member state '(7 8 9)))) + (setq continue nil) + (setq go-back t) + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset))) + ) + + ((and (eq char ?\>) (not (member state '(7 8 9)))) + (setq tag-flags (logior tag-flags 16)) + (when (eq (char-before) ?\/) + (setq tag-flags (logior tag-flags 8)) + ) + (setq continue nil) + (when name-beg + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset)))) + ) + + ((and spaced (member state '(1 3 5))) + ) + + ((and spaced (= state 2)) + (setq state 3) + ) + + ((and (eq char ?\/) (member state '(4 5))) + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset))) + (setq state 1 + attr-flags 0 + equal-offset 0 + name-beg nil + name-end nil + val-beg nil) + ) + + ((and (eq char ?\/) (member state '(0 1))) + ) + + ((and spaced (= state 4)) + (setq state 5) + ) + + ((and (= state 3) + (or (and (>= char 97) (<= char 122)) ;a - z + (and (>= char 65) (<= char 90)) ;A - Z + (eq char ?\-))) + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset))) + (setq state 2 + attr-flags 0 + equal-offset 0 + name-beg pos + name-end pos + val-beg nil) + ) + + ((and (eq char ?\n) (not (member state '(7 8 9)))) + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset))) + (setq state 1 + attr-flags 0 + equal-offset 0 + name-beg nil + name-end nil + val-beg nil) + ) + + ((and (= state 6) (member char '(?\s ?\n ?\/))) + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset))) + (setq state 1 + attr-flags 0 + equal-offset 0 + name-beg nil + name-end nil + val-beg nil) + ) + + ((and quoted (= quoted 2) (member char '(?\s ?\n ?\>))) + (when (eq char ?\>) + (setq tag-flags (logior tag-flags 16)) + (setq continue nil)) + (setq state 6) + (setq attrs (+ attrs (web-mode-attr-scan state char name-beg name-end val-beg attr-flags equal-offset))) + (setq state 1 + attr-flags 0 + equal-offset 0 + name-beg nil + name-end nil + val-beg nil) + ) + + ((and (not spaced) (= state 1)) + (when (and is-jsx (eq char ?\{)) + (setq attr-flags 4)) + (setq state 2) + (setq name-beg pos + name-end pos) + ) + + ((member state '(4 5)) + (setq val-beg pos) + (setq state 6) + ) + + ((= state 1) + (setq state 2) + ) + + ((= state 2) + (setq name-end pos) + (when (and (= attr-flags 0) (member char '(?\- ?\:))) + (let (attr) + (setq attr (buffer-substring-no-properties name-beg (1+ name-end))) + (cond + ((member attr '("http-equiv")) + (setq attr-flags (1- attr-flags)) + ) + ((and web-mode-engine-attr-regexp + (string-match-p web-mode-engine-attr-regexp attr)) + ;;(message "%S: %S" pos web-mode-engine-attr-regexp) + (setq attr-flags (logior attr-flags 2)) + ;;(setq attr-flags (1- attr-flags)) + ) + ((and (eq char ?\-) (not (string= attr "http-"))) + (setq attr-flags (logior attr-flags 1))) + ) ;cond + ) ;let + ) ;when attr-flags = 1 + ) ;state=2 + + ) ;cond + + ;;(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) + + (when (and quoted (>= quoted 2)) + (setq quoted nil)) + + (setq escaped (eq ?\\ char)) + (when (null go-back) + (forward-char)) + + ) ;while + + (when (> attrs 0) (setq tag-flags (logior tag-flags 1))) + + tag-flags)) + +(defun web-mode-attr-scan (state char name-beg name-end val-beg flags equal-offset) +;; (message "point(%S) state(%S) c(%c) name-beg(%S) name-end(%S) val-beg(%S) flags(%S) equal-offset(%S)" +;; (point) state char name-beg name-end val-beg flags equal-offset) + (if (null flags) (setq flags 0)) + (cond + ((null name-beg) +;; (message "name-beg is null (%S)" (point)) + 0) + ((or (and (= state 8) (not (eq ?\" char))) + (and (= state 7) (not (eq ?\' char)))) + (put-text-property name-beg (1+ name-beg) 'tag-attr-beg flags) + (put-text-property name-beg val-beg 'tag-attr t) + (put-text-property (1- val-beg) val-beg 'tag-attr-end equal-offset) + 1) + ((and (member state '(4 5)) (null val-beg)) + (put-text-property name-beg (1+ name-beg) 'tag-attr-beg flags) + (put-text-property name-beg (+ name-beg equal-offset 1) 'tag-attr t) + (put-text-property (+ name-beg equal-offset) (+ name-beg equal-offset 1) 'tag-attr-end equal-offset) + 1) + (t + (let (val-end) + (if (null val-beg) + (setq val-end name-end) + (setq val-end (point)) + (when (or (null char) (member char '(?\s ?\n ?\> ?\/))) + (setq val-end (1- val-end)) + ) + ) ;if + (put-text-property name-beg (1+ name-beg) 'tag-attr-beg flags) + (put-text-property name-beg (1+ val-end) 'tag-attr t) + (put-text-property val-end (1+ val-end) 'tag-attr-end equal-offset) + ) ;let + 1) ;t + ) ;cond + ) + +(defun web-mode-part-scan (reg-beg reg-end &optional content-type depth) + (save-excursion + (let (token-re ch-before ch-at ch-next token-type beg continue) + ;;(message "%S %S" reg-beg reg-end) + (cond + (content-type + ) + ((member web-mode-content-type web-mode-part-content-types) + (setq content-type web-mode-content-type)) + (t + (setq content-type (symbol-name (get-text-property reg-beg 'part-side)))) + ) ;cond + + (goto-char reg-beg) + + (cond + ((member content-type '("javascript" "json")) + (setq token-re "/\\|\"\\|'\\|`")) + ((member content-type '("jsx")) + (setq token-re "/\\|\"\\|'\\|`\\|%S|%S] %S %c %c %c" reg-beg reg-end depth beg ch-before ch-at ch-next) + + (cond + + ((eq ?\' ch-at) + (while (and continue (search-forward "'" reg-end t)) + (cond + ((get-text-property (1- (point)) 'block-side) + (setq continue t)) + ((looking-back "\\\\+'" reg-beg t) + (setq continue (= (mod (- (point) (match-beginning 0)) 2) 0)) + ) + (t + (setq continue nil)) + ) + ) ;while + (setq token-type 'string)) + + ((eq ?\` ch-at) + (while (and continue (search-forward "`" reg-end t)) + (cond + ((get-text-property (1- (point)) 'block-side) + (setq continue t)) + ((looking-back "\\\\+`" reg-beg t) + (setq continue (= (mod (- (point) (match-beginning 0)) 2) 0))) + (t + (setq continue nil)) + ) + ) ;while + (setq token-type 'string)) + + ((eq ?\" ch-at) + (while (and continue (search-forward "\"" reg-end t)) + (cond + ((get-text-property (1- (point)) 'block-side) + (setq continue t)) + ((looking-back "\\\\+\"" reg-beg t) + (setq continue (= (mod (- (point) (match-beginning 0)) 2) 0))) + (t + (setq continue nil)) + ) ;cond + ) ;while + (cond + ((string= content-type "json") + (if (looking-at-p "[ ]*:") + (cond + ((eq ?\@ (char-after (1+ beg))) + (setq token-type 'context)) + (t + (setq token-type 'key)) + ) + (setq token-type 'string)) + ) ;json + (t + (setq token-type 'string)) + ) ;cond + ) + + ((eq ?\< ch-at) + ;;(message "before [%S>%S|%S] pt=%S" reg-beg reg-end depth (point)) + (if (web-mode-jsx-skip reg-end) + (web-mode-jsx-scan-element beg (point) depth) + (forward-char)) + ;;(message "after [%S>%S|%S] pt=%S" reg-beg reg-end depth (point)) + ) + + ((and (eq ?\/ ch-at) (member content-type '("javascript" "jsx"))) + (cond + ((eq ?\\ ch-before) + ) + ((eq ?\* ch-next) + ;;(message "--> %S %S" (point) reg-end) + (when (search-forward "*/" reg-end t) + (setq token-type 'comment)) + ) + ((eq ?\/ ch-next) + (setq token-type 'comment) + (goto-char (if (< reg-end (line-end-position)) reg-end (line-end-position))) + ) + ((and (looking-at-p ".*/") + (looking-back "[[(,=:!&|?{};][ ]*/")) + ;;(re-search-forward "/[gimyu]*" reg-end t)) + (let ((eol (line-end-position))) + (while (and continue (search-forward "/" eol t)) + (cond + ((get-text-property (1- (point)) 'block-side) + (setq continue t)) + ((looking-back "\\\\+/" reg-beg t) + (setq continue (= (mod (- (point) (match-beginning 0)) 2) 0))) + (t + (re-search-forward "[gimyu]*" eol t) + (setq token-type 'string) + (setq continue nil)) + ) + ) ;while + ) ;let + ) + ) ;cond + ) + + ((eq ?\/ ch-next) + (unless (eq ?\\ ch-before) + (setq token-type 'comment) + (goto-char (if (< reg-end (line-end-position)) reg-end (line-end-position))) + ) + ) + + ((eq ?\* ch-next) + (cond + ((search-forward "*/" reg-end t) + (setq token-type 'comment)) + ((not (eobp)) + (forward-char)) + ) ;cond + ) + + ) ;cond + + (when (and beg (>= reg-end (point)) token-type) + (put-text-property beg (point) 'part-token token-type) + (cond + ((eq token-type 'comment) + (put-text-property beg (1+ beg) 'syntax-table (string-to-syntax "<")) + (when (< (point) (point-max)) + (if (< (point) (line-end-position)) + (put-text-property (1- (point)) (point) 'syntax-table (string-to-syntax ">")) ;#445 + (put-text-property (point) (1+ (point)) 'syntax-table (string-to-syntax ">")) ;#377 + ) + ) ;when + ) ;comment + ((eq token-type 'string) + (put-text-property beg (1+ beg) 'syntax-table (string-to-syntax "|")) + (when (< (point) (point-max)) + (if (< (point) (line-end-position)) + (put-text-property (1- (point)) (point) 'syntax-table (string-to-syntax "|")) + (put-text-property (point) (1+ (point)) 'syntax-table (string-to-syntax "|")) + ) + ) ;when + ) ;string + ) ;cond + ) ;when + + (when (> (point) reg-end) + (message "reg-beg(%S) reg-end(%S) token-type(%S) point(%S)" reg-beg reg-end token-type (point))) + + ;;(message "#[%S>%S|%S] %S %c %c %c | (%S)" reg-beg reg-end depth beg ch-before ch-at ch-next (point)) + + ) ;while + + ))) + +(defun web-mode-jsx-skip (reg-end) + (let ((continue t) (pos nil) (i 0)) + (save-excursion + (while continue + (cond + ((> (setq i (1+ i)) 100) + (message "jsx-skip ** warning **") + (setq continue nil)) + ((not (web-mode-dom-rsf ">\\([ \t\n]*[\];,)':}]\\)\\|{" reg-end)) + (setq continue nil) + ) + ((eq (char-before) ?\{) + (backward-char) + (web-mode-closing-paren reg-end) + (forward-char) + ) + (t + (setq continue nil) + (setq pos (match-beginning 1)) + ) ;t + ) ;cond + ) ;while + ) ;save-excursion + (when pos (goto-char pos)) + ;;(message "jsx-skip: %S" pos) + pos)) + +;; http://facebook.github.io/jsx/ +;; https://github.com/facebook/jsx/blob/master/AST.md +(defun web-mode-jsx-scan-element (reg-beg reg-end depth) + (unless depth (setq depth 1)) + (save-excursion + (let (token-beg token-end regexp) + (goto-char reg-beg) + (put-text-property reg-beg (1+ reg-beg) 'jsx-beg depth) + (put-text-property (1- reg-end) reg-end 'jsx-end depth) + (put-text-property reg-beg reg-end 'jsx-depth depth) + (goto-char reg-beg) + (while (web-mode-part-sf "/*" reg-end t) + (goto-char (match-beginning 0)) + (if (looking-back "{") + (progn + (backward-char) + (setq regexp "*/}")) + (setq regexp "*/")) + (setq token-beg (point)) + (if (not (web-mode-part-sf regexp reg-end t)) + (goto-char reg-end) + (setq token-end (point)) + (put-text-property token-beg token-end 'part-token 'comment) + ) ;if + ) ;while + (web-mode-scan-elements reg-beg reg-end) + (web-mode-jsx-scan-expression reg-beg reg-end (1+ depth)) + ))) + +(defun web-mode-jsx-scan-expression (reg-beg reg-end depth) + (let ((continue t) beg end) + (save-excursion + (goto-char reg-beg) + ;;(message "reg-beg=%S reg-end=%S" reg-beg reg-end) + (while (and continue (search-forward "{" reg-end t)) + (backward-char) + (setq beg (point) + end (web-mode-closing-paren reg-end)) + (cond + ((eq (get-text-property beg 'part-token) 'comment) + (forward-char)) + ((not end) + (setq continue nil)) + (t + (setq end (1+ end)) + (put-text-property beg end 'jsx-depth depth) + (put-text-property beg (1+ beg) 'jsx-beg depth) + (put-text-property (1- end) end 'jsx-end depth) + (web-mode-part-scan beg end "jsx" (1+ depth)) + ) ;t + ) ;cond + ) + ) + )) + +(defun web-mode-jsx-is-html (&optional pos) + (interactive) + (unless pos (setq pos (point))) + (let ((depth (get-text-property pos 'jsx-depth))) + (cond + ((or (null depth) (<= pos 2)) + (setq pos nil)) + ((and (= depth 1) (get-text-property pos 'jsx-beg)) + (setq pos nil)) + ((get-text-property pos 'jsx-beg) + (setq pos (null (get-text-property pos 'tag-beg)))) + ((setq pos (web-mode-jsx-depth-beginning-position pos)) + (setq pos (not (null (get-text-property pos 'tag-beg))))) + (t + (setq pos nil)) + ) ;cond + ;;(message "is-html: %S (depth=%S)" pos depth) + pos)) + +(defun web-mode-jsx-depth-beginning-position (&optional pos target-depth) + (interactive) + (unless pos (setq pos (point))) + (unless target-depth (setq target-depth (get-text-property pos 'jsx-depth))) + (cond + ((or (null target-depth) (bobp)) + (setq pos nil)) + ((and (get-text-property pos 'jsx-beg) (= target-depth (get-text-property pos 'jsx-depth))) + ) + (t + (let ((continue t) depth) + (while continue + (setq pos (previous-single-property-change pos 'jsx-depth)) + (cond + ((or (null pos) + (null (setq depth (get-text-property pos 'jsx-depth)))) + (setq continue nil + pos nil)) + ((and (get-text-property pos 'jsx-beg) (= target-depth depth)) + (setq continue nil)) + ) ;cond + ) ;while + ) ;let + ) ;t + ) ;cond + ;;(message "beg: %S" pos) + pos) + +(defun web-mode-velocity-skip (pos) + (goto-char pos) + (let ((continue t) (i 0)) + (when (eq ?\# (char-after)) + (forward-char)) + (when (member (char-after) '(?\$ ?\@)) + (forward-char)) + (when (member (char-after) '(?\!)) + (forward-char)) + (if (member (char-after) '(?\{)) + (search-forward "}") + (setq continue t) + (while continue + (skip-chars-forward "a-zA-Z0-9_-") + (when (> (setq i (1+ i)) 500) + (message "velocity-skip ** warning (%S) **" pos) + (setq continue nil)) + (when (member (char-after) '(?\()) + (search-forward ")" nil t)) + (if (member (char-after) '(?\.)) + (forward-char) + (setq continue nil)) + ) ;while + ) ;if + )) + +(defun web-mode-razor-skip (pos) + (goto-char pos) + (let ((continue t) (i 0)) + (while continue + (skip-chars-forward " =@a-zA-Z0-9_-") + (cond + ((> (setq i (1+ i)) 500) + (message "razor-skip ** warning **") + (setq continue nil)) + ((and (eq (char-after) ?\*) + (eq (char-before) ?@)) + (when (not (search-forward "*@" nil t)) + (setq continue nil)) + ) + ((looking-at-p "@[({]") + (forward-char) + (when (setq pos (web-mode-closing-paren-position (point))) + (goto-char pos)) + (forward-char) + ) + ((and (not (eobp)) (eq ?\( (char-after))) + (if (looking-at-p "[ \n]*<") + (setq continue nil) + (when (setq pos (web-mode-closing-paren-position)) + (goto-char pos)) + (forward-char) + ) ;if + ) + ((and (not (eobp)) (eq ?\. (char-after))) + (forward-char)) + ((looking-at-p "[ \n]*{") + (search-forward "{") + (if (looking-at-p "[ \n]*<") + (setq continue nil) + (backward-char) + (when (setq pos (web-mode-closing-paren-position)) + (goto-char pos)) + (forward-char) + ) ;if + ) + ((looking-at-p "}") + (forward-char)) + (t + (setq continue nil)) + ) ;cond + ) ;while + )) + +;; css rule = selector(s) + declaration (properties) +(defun web-mode-css-rule-next (limit) + (let (at-rule sel-beg sel-end dec-beg dec-end chunk) + (skip-chars-forward "\n\t ") + (setq sel-beg (point)) + (when (and (< (point) limit) + (web-mode-part-rsf "[{;]" limit)) + (setq sel-end (1- (point))) + (cond + ((eq (char-before) ?\{) + (setq dec-beg (point)) + (setq dec-end (web-mode-closing-paren-position (1- dec-beg) limit)) + (if dec-end + (progn + (goto-char dec-end) + (forward-char)) + (setq dec-end limit) + (goto-char limit)) + ) + (t + ) + ) ;cond + (setq chunk (buffer-substring-no-properties sel-beg sel-end)) + (when (string-match "@\\([[:alpha:]-]+\\)" chunk) + (setq at-rule (match-string-no-properties 1 chunk))) + ) ;when + (if (not sel-end) + (progn (goto-char limit) nil) + (list :at-rule at-rule + :sel-beg sel-beg + :sel-end sel-end + :dec-beg dec-beg + :dec-end dec-end) + ) ;if + )) + +(defun web-mode-css-rule-current (&optional pos part-beg part-end) + "Current CSS rule boundaries." + (unless pos (setq pos (point))) + (unless part-beg (setq part-beg (web-mode-part-beginning-position pos))) + (unless part-end (setq part-end (web-mode-part-end-position pos))) + (save-excursion + (let (beg end) + (goto-char pos) + (if (not (web-mode-part-sb "{" part-beg)) + (progn + (setq beg part-beg) + (if (web-mode-part-sf ";" part-end) + (setq end (1+ (point))) + (setq end part-end)) + ) ;progn + (setq beg (point)) + (setq end (web-mode-closing-paren-position beg part-end)) + (if end + (setq end (1+ end)) + (setq end (line-end-position))) +;; (message "%S >>beg%S >>end%S" pos beg end) + (if (> pos end) + + ;;selectors + (progn + (goto-char pos) + (if (web-mode-part-rsb "[};]" part-beg) + (setq beg (1+ (point))) + (setq beg part-beg) + ) ;if + (goto-char pos) + (if (web-mode-part-rsf "[{;]" part-end) + (cond + ((eq (char-before) ?\;) + (setq end (point)) + ) + (t + (setq end (web-mode-closing-paren-position (1- (point)) part-end)) + (if end + (setq end (1+ end)) + (setq end part-end)) + ) + ) ;cond + (setq end part-end) + ) + ) ;progn selectors + + ;; declaration + (goto-char beg) + (if (web-mode-part-rsb "[}{;]" part-beg) + (setq beg (1+ (point))) + (setq beg part-beg) + ) ;if + ) ; if > pos end + ) +;; (message "beg(%S) end(%S)" beg end) + (when (eq (char-after beg) ?\n) + (setq beg (1+ beg))) + (cons beg end) + ))) + +(defun web-mode-scan-engine-comments (reg-beg reg-end tag-start tag-end) + "Scan engine comments (mako, django)." + (save-excursion + (let (beg end (continue t)) + (goto-char reg-beg) + (while (and continue + (< (point) reg-end) + (re-search-forward tag-start reg-end t)) + (goto-char (match-beginning 0)) + (setq beg (point)) + (if (not (re-search-forward tag-end reg-end t)) + (setq continue nil) + (setq end (point)) + (remove-list-of-text-properties beg end web-mode-scan-properties) + (add-text-properties beg end '(block-side t block-token comment)) + (put-text-property beg (1+ beg) 'block-beg 0) + (put-text-property (1- end) end 'block-end t) + ) ;if + ) ;while + ))) + +(defun web-mode-propertize (&optional beg end) + + (unless beg (setq beg web-mode-change-beg)) + (unless end (setq end web-mode-change-end)) + +;; (message "propertize: beg(%S) end(%S)" web-mode-change-beg web-mode-change-end) + + (when (and end (> end (point-max))) + (setq end (point-max))) + +;; (remove-text-properties beg end '(font-lock-face nil)) + + (setq web-mode-change-beg nil + web-mode-change-end nil) + (cond + + ((or (null beg) (null end)) + nil) + + ((and (member web-mode-engine '("php" "asp")) + (get-text-property beg 'block-side) + (get-text-property end 'block-side) + (> beg (point-min)) + (not (eq (get-text-property (1- beg) 'block-token) 'delimiter-beg)) + (not (eq (get-text-property end 'block-token) 'delimiter-end))) + ;;(message "invalidate block") + (web-mode-invalidate-block-region beg end)) + + ((and (or (member web-mode-content-type '("css" "jsx" "javascript")) + (and (get-text-property beg 'part-side) + (get-text-property end 'part-side) + (> beg (point-min)) + (get-text-property (1- beg) 'part-side) + (get-text-property end 'part-side)) + )) + ;;(message "invalidate part (%S > %S)" beg end) + (web-mode-invalidate-part-region beg end)) + + (t + ;;(message "%S %S" beg end) + (web-mode-invalidate-region beg end)) + + ) ;cond + + ) + +;; NOTE: il est important d'identifier des caractères en fin de ligne +;; web-mode-block-tokenize travaille en effet sur les fins de lignes pour +;; les commentaires de type // +(defun web-mode-invalidate-block-region (pos-beg pos-end) + ;; (message "pos-beg(%S) pos-end(%S)" pos-beg pos-end) + (save-excursion + (let (beg end code-beg code-end) + ;;(message "invalidate-block-region: pos-beg(%S)=%S" pos-beg (get-text-property pos 'block-side)) + ;;(message "code-beg(%S) code-end(%S) pos-beg(%S) pos-end(%S)" code-beg code-end pos-beg pos-end) + (cond + ((not (and (setq code-beg (web-mode-block-code-beginning-position pos-beg)) + (setq code-end (web-mode-block-code-end-position pos-beg)) + (>= pos-beg code-beg) + (<= pos-end code-end) + (> code-end code-beg))) + (web-mode-invalidate-region pos-beg pos-end)) + ((member web-mode-engine '("asp")) + (goto-char pos-beg) + (forward-line -1) + (setq beg (line-beginning-position)) + (when (> code-beg beg) + (setq beg code-beg)) + (goto-char pos-beg) + (forward-line) + (setq end (line-end-position)) + (when (< code-end end) + (setq end code-end)) + ;; ?? pas de (web-mode-block-tokenize beg end) ? + (cons beg end) + ) ; asp + (t + (goto-char pos-beg) + (when (string= web-mode-engine "php") + (cond + ((and (looking-back "\*") + (looking-at-p "/")) + (search-backward "/*" code-beg)) + ) ;cond + ) + (if (web-mode-block-rsb "[;{}(][ ]*\n" code-beg) + (setq beg (match-end 0)) + (setq beg code-beg)) + (goto-char pos-end) + (if (web-mode-block-rsf "[;{})][ ]*\n" code-end) + (setq end (1- (match-end 0))) + (setq end code-end)) + (web-mode-block-tokenize beg end) + ;;(message "beg(%S) end(%S)" beg end) + (cons beg end) + ) + ) ;cond + ))) + +(defun web-mode-invalidate-part-region (pos-beg pos-end) + (save-excursion + (let (beg end part-beg part-end language) + (if (member web-mode-content-type '("css" "javascript" "json" "jsx")) + (setq language web-mode-content-type) + (setq language (symbol-name (get-text-property pos-beg 'part-side)))) + (setq part-beg (web-mode-part-beginning-position pos-beg) + part-end (web-mode-part-end-position pos-beg)) + ;;(message "language(%S) pos-beg(%S) pos-end(%S) part-beg(%S) part-end(%S)" + ;; language pos-beg pos-end part-beg part-end) + (goto-char pos-beg) + (cond + ((not (and part-beg part-end + (>= pos-beg part-beg) + (<= pos-end part-end) + (> part-end part-beg))) + (web-mode-invalidate-region pos-beg pos-end)) + ((member language '("javascript" "json" "jsx")) + (if (web-mode-javascript-rsb "[;{}(][ ]*\n" part-beg) + (setq beg (match-end 0)) + (setq beg part-beg)) + (goto-char pos-end) + (if (web-mode-javascript-rsf "[;{})][ ]*\n" part-end) + (setq end (match-end 0)) + (setq end part-end)) + (web-mode-scan-region beg end language)) + ((string= language "css") + (let (rule1 rule2) + (setq rule1 (web-mode-css-rule-current pos-beg)) + (setq rule2 rule1) + (when (> pos-end (cdr rule1)) + (setq rule2 (web-mode-css-rule-current pos-end))) + (setq beg (car rule1) + end (cdr rule2)) + ) + (web-mode-scan-region beg end language)) + (t + (setq beg part-beg + end part-end) + (web-mode-scan-region beg end language)) + ) ;cond + ))) + +(defun web-mode-invalidate-region (reg-beg reg-end) + ;;(message "%S | reg-beg(%S) reg-end(%S)" (point) reg-beg reg-end) + (setq reg-beg (web-mode-invalidate-region-beginning-position reg-beg) + reg-end (web-mode-invalidate-region-end-position reg-end)) + ;;(message "invalidate-region: reg-beg(%S) reg-end(%S)" reg-beg reg-end) + (web-mode-scan-region reg-beg reg-end)) + +(defun web-mode-invalidate-region-beginning-position (pos) + (save-excursion + (goto-char pos) + (when (and (bolp) (not (bobp))) + (backward-char)) + (beginning-of-line) + ;;(message "pos=%S %S" (point) (text-properties-at (point))) + (setq pos (point-min)) + (let ((continue (not (bobp)))) + (while continue + (cond + ((bobp) + (setq continue nil)) + ;; NOTE: Going back to the previous start tag is necessary + ;; when inserting a part endtag (e.g. ). + ;; Indeed, parts must be identified asap. + ((and (progn (back-to-indentation) t) + (get-text-property (point) 'tag-beg) + (eq (get-text-property (point) 'tag-type) 'start)) + (setq pos (point) + continue nil)) + (t + (forward-line -1)) + ) ;cond + ) ;while + ;;(message "pos=%S" pos) + pos))) + +(defun web-mode-invalidate-region-end-position (pos) + (save-excursion + (goto-char pos) + ;;(message "pos=%S %S" pos (get-text-property pos 'block-token)) + (when (string= web-mode-engine "jsp") + (cond + ((and (looking-back "<%") + (looking-at-p "--")) + (search-forward "--%>")) + ((and (looking-back "-- %") + (looking-at-p ">")) + (search-forward "--%>")) + ) ;cond + ) ;when + + (setq pos (point-max)) + (let ((continue (not (eobp)))) + (while continue + (end-of-line) + ;;(message "%S %S" (point) (get-text-property (point) 'block-token)) + (cond + ((eobp) + (setq continue nil)) + ;;() + ((and (not (get-text-property (point) 'tag-type)) + (not (get-text-property (point) 'part-side)) + (not (get-text-property (point) 'block-side))) + (setq pos (point) + continue nil)) + (t + (forward-line)) + ) ;cond + ) ;while + pos))) + +(defun web-mode-buffer-scan () + "Scan entine buffer." + (interactive) + (web-mode-scan-region (point-min) (point-max))) + +;;---- FONTIFICATION ----------------------------------------------------------- + +(defun web-mode-font-lock-highlight (limit) + ;;(message "font-lock-highlight: point(%S) limit(%S) change-beg(%S) change-end(%S)" (point) limit web-mode-change-beg web-mode-change-end) + (cond + (web-mode-inhibit-fontification + nil) + (t + (web-mode-highlight-region (point) limit) + nil) + )) + +(defun web-mode-buffer-highlight () + (interactive) + (if (fboundp 'font-lock-flush) + (font-lock-flush) + (font-lock-fontify-buffer))) + +(defun web-mode-extend-region () + ;;(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) + ;; (setq font-lock-beg web-mode-change-beg + ;; font-lock-end web-mode-change-end) + (cond + (web-mode-inhibit-fontification + nil) + (t ;;(and web-mode-change-beg web-mode-change-end) + (when (or (null web-mode-change-beg) (< font-lock-beg web-mode-change-beg)) + ;;(message "font-lock-beg(%S) < web-mode-change-beg(%S)" font-lock-beg web-mode-change-beg) + (setq web-mode-change-beg font-lock-beg)) + (when (or (null web-mode-change-end) (> font-lock-end web-mode-change-end)) + ;;(message "font-lock-end(%S) > web-mode-change-end(%S)" font-lock-end web-mode-change-end) + (setq web-mode-change-end font-lock-end)) + (let ((region (web-mode-propertize web-mode-change-beg web-mode-change-end))) + (when region + ;;(message "region: %S" region) + (setq font-lock-beg (car region) + font-lock-end (cdr region) + ;;web-mode-change-beg (car region) + ;;web-mode-change-end (cdr region) + ) + ) ;when + ) ;let + nil) ;t + )) + +(defun web-mode-unfontify-region (beg end) + ;;(message "unfontify: %S %S" beg end) + ) + +(defun web-mode-highlight-region (&optional beg end) ;; content-type) + ;;(message "highlight-region: beg(%S) end(%S)" beg end) + (web-mode-with-silent-modifications + (save-excursion + (save-restriction + (save-match-data + (let ((buffer-undo-list t) + ;;(inhibit-modification-hooks t) + (inhibit-point-motion-hooks t) + (inhibit-quit t)) + (remove-list-of-text-properties beg end '(font-lock-face face)) + (cond + ((and (get-text-property beg 'block-side) + (not (get-text-property beg 'block-beg))) + (web-mode-block-highlight beg end)) + ((or (member web-mode-content-type web-mode-part-content-types) + ;;(member content-type web-mode-part-content-types) + (get-text-property beg 'part-side)) + (web-mode-part-highlight beg end) + (web-mode-process-blocks beg end 'web-mode-block-highlight)) + ((string= web-mode-engine "none") + (web-mode-highlight-tags beg end) + (web-mode-process-parts beg end 'web-mode-part-highlight)) + (t + (web-mode-highlight-tags beg end) + (web-mode-process-parts beg end 'web-mode-part-highlight) + (web-mode-process-blocks beg end 'web-mode-block-highlight)) + ) ;cond + (when web-mode-enable-element-content-fontification + (web-mode-highlight-elements beg end)) + (when web-mode-enable-whitespace-fontification + (web-mode-highlight-whitespaces beg end)) + ;;(message "%S %S" font-lock-keywords font-lock-keywords-alist) + )))))) + +(defun web-mode-highlight-tags (reg-beg reg-end &optional depth) + (let ((continue t)) + (goto-char reg-beg) + (when (and (not (get-text-property (point) 'tag-beg)) + (not (web-mode-tag-next))) + (setq continue nil)) + (when (and continue (>= (point) reg-end)) + (setq continue nil)) + (while continue + (cond + (depth + (when (eq depth (get-text-property (point) 'jsx-depth)) + (web-mode-tag-highlight) + ) + ;; BGJSX + ) + (t + (web-mode-tag-highlight)) + ) ;cond + (when (or (not (web-mode-tag-next)) + (>= (point) reg-end)) + (setq continue nil)) + ) ;while + (when web-mode-enable-inlays + (when (null web-mode-inlay-regexp) + (setq web-mode-inlay-regexp (regexp-opt '("\\[" "\\(" "\\begin{align}")))) + (let (beg end expr) + (goto-char reg-beg) + (while (web-mode-dom-rsf web-mode-inlay-regexp reg-end) + (setq beg (match-beginning 0) + end nil + expr (substring (match-string-no-properties 0) 0 2)) + (setq expr (cond + ((string= expr "\\[") "\\]") + ((string= expr "\\(") "\\)") + (t "\\end{align}"))) + (when (and (web-mode-dom-sf expr reg-end) + (setq end (match-end 0)) + (not (text-property-any beg end 'tag-end t))) + (font-lock-append-text-property beg end 'font-lock-face 'web-mode-inlay-face) + ) ;when + ) ;while + ) ;let + ) ;when + (when web-mode-enable-html-entities-fontification + (let (beg end) + (goto-char reg-beg) + (while (web-mode-dom-rsf "&\\([#]?[[:alnum:]]\\{2,8\\}\\);" reg-end) + (setq beg (match-beginning 0) + end (match-end 0)) + (when (not (text-property-any beg end 'tag-end t)) + (font-lock-append-text-property beg end 'font-lock-face 'web-mode-html-entity-face) + ) ;when + ) ;while + ) ;let + ) ;when + )) + +(defun web-mode-tag-highlight (&optional beg end) + (unless beg (setq beg (point))) + (unless end (setq end (1+ (web-mode-tag-end-position beg)))) + (let (name type face flags slash-beg slash-end bracket-end) + (setq flags (get-text-property beg 'tag-beg) + type (get-text-property beg 'tag-type) + name (get-text-property beg 'tag-name)) + (cond + ((eq type 'comment) + (put-text-property beg end 'font-lock-face 'web-mode-comment-face) + (when (and web-mode-enable-comment-interpolation (> (- end beg) 5)) + (web-mode-interpolate-comment beg end nil))) + ((eq type 'cdata) + (put-text-property beg end 'font-lock-face 'web-mode-doctype-face)) + ((eq type 'doctype) + (put-text-property beg end 'font-lock-face 'web-mode-doctype-face)) + ((eq type 'declaration) + (put-text-property beg end 'font-lock-face 'web-mode-doctype-face)) + (name + (setq face (cond + ((and web-mode-enable-element-tag-fontification + (setq face (cdr (assoc name web-mode-element-tag-faces)))) + face) + ((> (logand flags 2) 0) 'web-mode-html-tag-custom-face) + (t 'web-mode-html-tag-face)) + slash-beg (> (logand flags 4) 0) + slash-end (> (logand flags 8) 0) + bracket-end (> (logand flags 16) 0)) + (put-text-property beg (+ beg (if slash-beg 2 1)) + 'font-lock-face 'web-mode-html-tag-bracket-face) + (put-text-property (+ beg (if slash-beg 2 1)) (+ beg (if slash-beg 2 1) (length name)) + 'font-lock-face face) + (when (or slash-end bracket-end) + (put-text-property (- end (if slash-end 2 1)) end 'font-lock-face 'web-mode-html-tag-bracket-face) + ) ;when + (when (> (logand flags 1) 0) + ;;(message "%S>%S" beg end) + (web-mode-highlight-attrs beg end)) + ) ;case name + ) ;cond + )) + +(defun web-mode-highlight-attrs (reg-beg reg-end) + (let ((continue t) (pos reg-beg) beg end flags offset face) + ;;(message "highlight-attrs %S>%S" reg-beg reg-end) + (while continue + (setq beg (web-mode-attribute-next-position pos reg-end)) + (cond + ((or (null beg) (>= beg reg-end)) + (setq continue nil)) + (t + (setq flags (or (get-text-property beg 'tag-attr-beg) 0)) + (setq face (cond + ((= (logand flags 1) 1) 'web-mode-html-attr-custom-face) + ((= (logand flags 2) 2) 'web-mode-html-attr-engine-face) + ((= (logand flags 4) 4) nil) + (t 'web-mode-html-attr-name-face))) + ;;(setq end (if (get-text-property beg 'tag-attr-end) beg (web-mode-attribute-end-position beg))) + (setq end (web-mode-attribute-end-position beg)) + (cond + ((or (null end) (>= end reg-end)) + (setq continue nil)) + (t + (setq offset (get-text-property end 'tag-attr-end)) + (if (= offset 0) + (put-text-property beg (1+ end) 'font-lock-face face) + (put-text-property beg (+ beg offset) 'font-lock-face face) + (put-text-property (+ beg offset) (+ beg offset 1) + 'font-lock-face + 'web-mode-html-attr-equal-face) + (when (not (get-text-property (+ beg offset 1) 'jsx-beg)) + (put-text-property (+ beg offset 1) (1+ end) + 'font-lock-face + 'web-mode-html-attr-value-face) + ) + ) ;if offset + (setq pos (1+ end)) + ) ;t + ) ;cond + ) ;t + );cond + ) ;while + )) + +(defun web-mode-block-highlight (reg-beg reg-end) + (let (sub1 sub2 sub3 continue char keywords token-type face beg end (buffer (current-buffer))) + ;;(message "reg-beg=%S reg-end=%S" reg-beg reg-end) + + ;; NOTE: required for block inside tag attr + (remove-list-of-text-properties reg-beg reg-end '(font-lock-face)) + + (goto-char reg-beg) + + (when (null web-mode-engine-font-lock-keywords) + (setq sub1 (buffer-substring-no-properties + reg-beg (+ reg-beg 1)) + sub2 (buffer-substring-no-properties + reg-beg (+ reg-beg 2)) + sub3 (buffer-substring-no-properties + reg-beg (+ reg-beg (if (>= (point-max) (+ reg-beg 3)) 3 2)))) + ) + + (cond + + ((and (get-text-property reg-beg 'block-beg) + (eq (get-text-property reg-beg 'block-token) 'comment)) + (put-text-property reg-beg reg-end 'font-lock-face 'web-mode-comment-face) + ) ;comment block + + (web-mode-engine-font-lock-keywords + (setq keywords web-mode-engine-font-lock-keywords) + ) + + ((string= web-mode-engine "django") + (cond + ((string= sub2 "{{") + (setq keywords web-mode-django-expr-font-lock-keywords)) + ((string= sub2 "{%") + (setq keywords web-mode-django-code-font-lock-keywords)) + )) ;django + + ((string= web-mode-engine "mako") + (cond + ((member sub3 '("<% " "<%\n" "<%!")) + (setq keywords web-mode-mako-block-font-lock-keywords)) + ((eq (aref sub2 0) ?\%) + (setq keywords web-mode-mako-block-font-lock-keywords)) + ((member sub2 '("<%" " %S face(%S)" beg end face) + (remove-list-of-text-properties beg end '(face)) + (put-text-property beg end 'font-lock-face face) + ) + (setq continue nil + end nil) + ) ;if end + ) ;progn beg + (setq continue nil + end nil) + ) ;if beg + (when (and beg end) + (save-match-data + (when (and web-mode-enable-heredoc-fontification + (eq char ?\<) + (> (- end beg) 8) + ;;(progn (message "%S" (buffer-substring-no-properties beg end)) t) + (string-match-p "JS\\|JAVASCRIPT\\|HTM\\|CSS" (buffer-substring-no-properties beg end))) + (setq keywords + (cond + ((string-match-p "H" (buffer-substring-no-properties beg (+ beg 8))) + web-mode-html-font-lock-keywords) + (t + web-mode-javascript-font-lock-keywords) + )) + (web-mode-fontify-region beg end keywords) + )) +;; (message "%S %c %S beg=%S end=%S" web-mode-enable-string-interpolation char web-mode-engine beg end) + (when (and web-mode-enable-string-interpolation + (member char '(?\" ?\<)) + (member web-mode-engine '("php" "erb")) + (> (- end beg) 4)) + (web-mode-interpolate-block-string beg end) + ) ;when + (when (and web-mode-enable-comment-interpolation + (eq token-type 'comment) + (> (- end beg) 3)) + (web-mode-interpolate-comment beg end t) + ) ;when + (when (and web-mode-enable-sql-detection + (eq token-type 'string) + (> (- end beg) 6) + ;;(eq char ?\<) + ;;(web-mode-looking-at-p (concat "[ \n]*" web-mode-sql-queries) (1+ beg)) + (web-mode-looking-at-p (concat "\\(.\\|<<<[[:alnum:]]+\\)[ \n]*" web-mode-sql-queries) beg) + ) + (web-mode-interpolate-sql-string beg end) + ) ;when + ) ;when beg end + ) ;while continue + ) ;when keywords + + (when (and (member web-mode-engine '("jsp" "mako")) + (> (- reg-end reg-beg) 12) + (eq ?\< (char-after reg-beg))) + (web-mode-interpolate-block-tag reg-beg reg-end)) + + (when web-mode-enable-block-face +;; (message "block-face %S %S" reg-beg reg-end) + (font-lock-append-text-property reg-beg reg-end 'face 'web-mode-block-face)) + + )) + +(defun web-mode-part-highlight (reg-beg reg-end &optional depth) + (unless depth + (when (string= web-mode-content-type "jsx") (setq depth 0)) + ) + (save-excursion + (let (start continue token-type face pos beg end string-face comment-face content-type) + ;;(message "part-highlight: reg-beg(%S) reg-end(%S)" reg-beg reg-end) + (if (member web-mode-content-type web-mode-part-content-types) + (setq content-type web-mode-content-type) + (setq content-type (symbol-name (get-text-property reg-beg 'part-side)))) + (cond + ((member content-type '("javascript" "jsx")) + (setq string-face 'web-mode-javascript-string-face + comment-face 'web-mode-javascript-comment-face) + (web-mode-fontify-region reg-beg reg-end web-mode-javascript-font-lock-keywords)) + ((string= content-type "json") + (setq string-face 'web-mode-json-string-face + comment-face 'web-mode-json-comment-face) + (web-mode-fontify-region reg-beg reg-end web-mode-javascript-font-lock-keywords)) + ((string= content-type "css") + (setq string-face 'web-mode-css-string-face + comment-face 'web-mode-css-comment-face) + (web-mode-css-rules-highlight reg-beg reg-end)) + (t + (setq string-face 'web-mode-part-string-face + comment-face 'web-mode-part-comment-face)) + ) + + (goto-char reg-beg) + + ;;(when (string= content-type "jsx") (web-mode-highlight-tags reg-beg reg-end)) + ;;(setq continue (and pos (< pos reg-end))) + (setq continue t + pos reg-beg) + (while continue + (if (get-text-property pos 'part-token) + (setq beg pos) + (setq beg (next-single-property-change pos 'part-token))) + (cond + ((or (null beg) (>= beg reg-end)) + (setq continue nil + end nil)) + ((and (eq depth 0) (get-text-property beg 'jsx-depth)) + (setq pos (or (next-single-property-change beg 'jsx-depth) (point-max)))) + (t + (setq token-type (get-text-property beg 'part-token)) + (setq face (cond + ((eq token-type 'string) string-face) + ((eq token-type 'comment) comment-face) + ((eq token-type 'context) 'web-mode-json-context-face) + ((eq token-type 'key) 'web-mode-json-key-face) + (t nil))) + (setq end (or (next-single-property-change beg 'part-token) (point-max)) + pos end) + (cond + ((or (null end) (> end reg-end)) + (setq continue nil + end nil)) + (t + (when face + (remove-list-of-text-properties beg end '(face)) + (put-text-property beg end 'font-lock-face face)) + (cond + ((< (- end beg) 6) + ) + ((eq token-type 'string) + (when (and web-mode-enable-string-interpolation + (member content-type '("javascript" "jsx"))) + (web-mode-interpolate-javascript-string beg end))) + ((eq token-type 'comment) + (when web-mode-enable-comment-interpolation + (web-mode-interpolate-comment beg end t))) + ) ;cond + ) ;t + ) ;cond + ) ;t + ) ;cond + ) ;while + + (when (and (string= web-mode-content-type "html") web-mode-enable-part-face) + (font-lock-append-text-property reg-beg reg-end 'face + (if (string= content-type "javascript") + 'web-mode-script-face + 'web-mode-style-face)) + ) + + + + (when (and (eq depth 0) (string= content-type "jsx")) + (let (pair elt-beg elt-end exp-beg exp-end exp-depth) + (goto-char reg-beg) + (while (setq pair (web-mode-jsx-element-next reg-end)) + ;;(message "elt-pair=%S" pair) + (setq elt-beg (car pair) + elt-end (cdr pair)) + (remove-list-of-text-properties elt-beg (1+ elt-end) '(face)) + (web-mode-highlight-tags elt-beg elt-end 1) + (goto-char elt-beg) + (while (setq pair (web-mode-jsx-expression-next elt-end)) + ;;(message "exp-pair=%S elt-end=%S" pair elt-end) + (setq exp-beg (car pair) + exp-end (cdr pair)) + (when (eq (char-after exp-beg) ?\{) + (setq exp-depth (get-text-property exp-beg 'jsx-depth)) + (remove-list-of-text-properties exp-beg exp-end '(font-lock-face)) + (put-text-property exp-beg (1+ exp-beg) 'font-lock-face 'web-mode-block-delimiter-face) + (when (and (eq (get-text-property exp-beg 'tag-attr-beg) 4) (web-mode-looking-at-p "\.\.\." (1+ exp-beg))) + (put-text-property exp-beg (+ exp-beg 4) 'font-lock-face 'web-mode-block-delimiter-face)) + (put-text-property exp-end (1+ exp-end) 'font-lock-face 'web-mode-block-delimiter-face) + (web-mode-highlight-tags (1+ exp-beg) exp-end (1+ exp-depth)) + (web-mode-part-highlight (1+ exp-beg) exp-end exp-depth) + (web-mode-fontify-region (1+ exp-beg) exp-end web-mode-javascript-font-lock-keywords) + ) + (goto-char (1+ exp-beg)) + ) ;while exp + + (when (and elt-beg web-mode-jsx-depth-faces) + (let (depth-beg depth-end jsx-face) + (goto-char elt-beg) + (while (setq pair (web-mode-jsx-depth-next reg-end)) + ;;(message "depth-pair=%S" pair) + (setq depth-beg (car pair) + depth-end (cdr pair) + depth (get-text-property depth-beg 'jsx-depth) + jsx-face (elt web-mode-jsx-depth-faces (1- depth))) + ;;(message "%S" jsx-face) + (font-lock-prepend-text-property depth-beg (1+ depth-end) 'face jsx-face) + (goto-char (+ depth-beg 2)) + ) + ) ;let + ) + + (goto-char (1+ elt-end)) + ) ;while elt + ) ;let + ) ;when + + ))) + +(defun web-mode-jsx-element-next (reg-end) + (let (continue beg end) + (setq beg (point)) + (unless (get-text-property beg 'jsx-depth) + (setq beg (next-single-property-change beg 'jsx-beg))) + (setq continue (and beg (< beg reg-end)) + end beg) + (while continue + (setq end (next-single-property-change end 'jsx-end)) + (cond + ((or (null end) (> end reg-end)) + (setq continue nil + end nil)) + ((eq (get-text-property end 'jsx-depth) 1) + (setq continue nil)) + (t + (setq end (1+ end))) + ) ;cond + ) ;while + ;;(message "beg=%S end=%S" beg end) + (if (and beg end (< beg end)) (cons beg end) nil))) + +(defun web-mode-jsx-expression-next (reg-end) + (let (beg end depth continue pos) + (setq beg (point)) + ;;(message "pt=%S" beg) + (unless (and (get-text-property beg 'jsx-beg) (null (get-text-property beg 'tag-beg))) + ;;(setq beg (next-single-property-change beg 'jsx-beg)) + (setq continue t + pos (1+ beg)) + (while continue + (setq pos (next-single-property-change pos 'jsx-beg)) + (cond + ((null pos) + (setq continue nil + beg nil)) + ((> pos reg-end) + (setq continue nil + beg nil)) + ((null (get-text-property pos 'jsx-beg)) + ) + ((null (get-text-property pos 'tag-beg)) + (setq continue nil + beg pos)) + ;;(t + ;; (setq pos (1+ pos))) + ) ;cond + ) ;while + ) ;unless + ;;(message "beg=%S" beg) + (when (and beg (< beg reg-end)) + (setq depth (get-text-property beg 'jsx-beg) + continue (not (null depth)) + pos beg) + ;;(message "beg=%S" beg) + (while continue + (setq pos (next-single-property-change pos 'jsx-end)) + ;;(message "pos=%S" pos) + (cond + ((null pos) + (setq continue nil)) + ((> pos reg-end) + (setq continue nil)) + ((eq depth (get-text-property pos 'jsx-end)) + (setq continue nil + end pos)) + (t + ;;(setq pos (1+ pos)) + ) + ) ;cond + ) ;while + ) ;when + ;;(message "%S > %S" beg end) + (if (and beg end) (cons beg end) nil))) + +(defun web-mode-jsx-depth-next (reg-end) + (let (beg end depth continue pos) + (setq beg (point)) + ;;(message "pt=%S" beg) + (unless (get-text-property beg 'jsx-beg) + ;;(setq beg (next-single-property-change beg 'jsx-beg)) + ;;(setq pos (1+ beg)) + (setq pos (next-single-property-change (1+ beg) 'jsx-beg)) + (cond + ((null pos) + (setq beg nil)) + ((>= pos reg-end) + (setq beg nil)) + (t + (setq beg pos)) + ) ;cond + ) ;unless + ;;(message "beg=%S" beg) + (when beg + (setq depth (get-text-property beg 'jsx-beg) + continue (not (null depth)) + pos beg) + ;;(message "beg=%S" beg) + (while continue + (setq pos (next-single-property-change pos 'jsx-end)) + ;;(message "pos=%S" pos) + (cond + ((null pos) + (setq continue nil)) + ((> pos reg-end) + (setq continue nil)) + ((eq depth (get-text-property pos 'jsx-end)) + (setq continue nil + end pos)) + (t + ;;(setq pos (1+ pos)) + ) + ) ;cond + ) ;while + ) ;when + ;;(message "%S > %S" beg end) + (if (and beg end) (cons beg end) nil))) + + +(defun web-mode-css-rules-highlight (part-beg part-end) + (save-excursion + (goto-char part-beg) + (let (rule (continue t) (i 0) (at-rule nil)) + (while continue + (setq rule (web-mode-css-rule-next part-end)) + ;;(message "rule=%S" rule) + (cond + ((> (setq i (1+ i)) 1000) + (message "css-rules-highlight ** too much rules **") + (setq continue nil)) + ((null rule) + (setq continue nil)) + ((and (setq at-rule (plist-get rule :at-rule)) + (not (member at-rule '("charset" "font-face" "import"))) + (plist-get rule :dec-end)) + (web-mode-css-rule-highlight (plist-get rule :sel-beg) + (plist-get rule :sel-end) + nil nil) + (web-mode-css-rules-highlight (plist-get rule :dec-beg) + (plist-get rule :dec-end))) + (t + (web-mode-css-rule-highlight (plist-get rule :sel-beg) + (plist-get rule :sel-end) + (plist-get rule :dec-beg) + (plist-get rule :dec-end))) + ) ;cond + ) ;while + ) ;let + )) + +(defun web-mode-css-rule-highlight (sel-beg sel-end dec-beg dec-end) + (save-excursion +;; (message "sel-beg=%S sel-end=%S dec-beg=%S dec-end=%S" sel-beg sel-end dec-beg dec-end) + (web-mode-fontify-region sel-beg sel-end + web-mode-selector-font-lock-keywords) + (when (and dec-beg dec-end) + (web-mode-fontify-region dec-beg dec-end + web-mode-declaration-font-lock-keywords) + (goto-char dec-beg) + (while (and web-mode-enable-css-colorization + (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) + (< (point) dec-end)) + (web-mode-colorize (match-beginning 0) (match-end 0)) + ) + ))) + +(defun web-mode-fontify-region (beg end keywords) +;; (message "beg=%S end=%S" beg end);; (symbol-name keywords)) + (save-excursion + (let ((font-lock-keywords keywords) + (font-lock-multiline nil) + (font-lock-keywords-case-fold-search + (member web-mode-engine '("asp" "template-toolkit"))) + (font-lock-keywords-only t) + (font-lock-extend-region-functions nil)) + ;; (message "%S" keywords) + (when (listp font-lock-keywords) + (font-lock-fontify-region beg end) + ) + ) + )) + +(defun web-mode-colorize-foreground (color) + (let* ((values (x-color-values color)) + (r (car values)) + (g (cadr values)) + (b (car (cdr (cdr values))))) + (if (> 128.0 (floor (+ (* .3 r) (* .59 g) (* .11 b)) 256)) + "white" "black"))) + +(defun web-mode-colorize (beg end) + (let (str plist len) + (setq str (buffer-substring-no-properties beg end)) + (setq len (length str)) + (cond + ((string= (substring str 0 1) "#") + (setq plist (list :background str + :foreground (web-mode-colorize-foreground str))) + (put-text-property beg end 'face plist)) + ((string= (substring str 0 4) "rgb(") + (setq str (format "#%02X%02X%02X" + (string-to-number (match-string-no-properties 1)) + (string-to-number (match-string-no-properties 2)) + (string-to-number (match-string-no-properties 3)))) + (setq plist (list :background str + :foreground (web-mode-colorize-foreground str))) + (put-text-property beg end 'face plist)) + ) ;cond + )) + +(defun web-mode-interpolate-block-tag (beg end) + (save-excursion + (goto-char (+ 4 beg)) + (setq end (1- end)) + (while (re-search-forward "${.*?}" end t) + (remove-list-of-text-properties (match-beginning 0) (match-end 0) '(face)) + (web-mode-fontify-region (match-beginning 0) (match-end 0) + web-mode-uel-font-lock-keywords)) + )) + +(defun web-mode-interpolate-javascript-string (beg end) + (save-excursion + (goto-char (1+ beg)) + (setq end (1- end)) + (while (re-search-forward "${.*?}" end t) + (put-text-property (match-beginning 0) (match-end 0) + 'font-lock-face + 'web-mode-variable-name-face) + ) + )) + +;; todo : parsing plus compliqué: {$obj->values[3]->name} +(defun web-mode-interpolate-block-string (beg end) + (save-excursion + (goto-char (1+ beg)) + (setq end (1- end)) + (cond + ((string= web-mode-engine "php") + (while (re-search-forward "$[[:alnum:]_]+\\(->[[:alnum:]_]+\\)*\\|{[ ]*$.+?}" end t) +;; (message "%S > %S" (match-beginning 0) (match-end 0)) + (remove-list-of-text-properties (match-beginning 0) (match-end 0) '(font-lock-face)) + (web-mode-fontify-region (match-beginning 0) (match-end 0) + web-mode-php-var-interpolation-font-lock-keywords) + )) + ((string= web-mode-engine "erb") + (while (re-search-forward "#{.*?}" end t) + (remove-list-of-text-properties (match-beginning 0) (match-end 0) '(font-lock-face)) + (put-text-property (match-beginning 0) (match-end 0) + 'font-lock-face 'web-mode-variable-name-face) + )) + ) ;cond + )) + +(defun web-mode-interpolate-comment (beg end block-side) + (save-excursion + (let ((regexp (concat "\\_<\\(" web-mode-comment-keywords "\\)\\_>"))) + (goto-char beg) + (while (re-search-forward regexp end t) + (font-lock-prepend-text-property (match-beginning 1) (match-end 1) + 'font-lock-face + 'web-mode-comment-keyword-face) + ) ;while + ))) + +(defun web-mode-interpolate-sql-string (beg end) + (save-excursion + (let ((case-fold-search t) + (regexp (concat "\\_<\\(" web-mode-sql-keywords "\\)\\_>"))) + (goto-char beg) + (while (re-search-forward regexp end t) + (font-lock-prepend-text-property (match-beginning 1) (match-end 1) + 'font-lock-face + 'web-mode-sql-keyword-face) + ) ;while + ))) + +(defun web-mode-fill-paragraph (&optional justify) + (save-excursion + (let ((pos (point)) fill-coll + prop pair beg end delim-beg delim-end chunk fill-col) + (cond + ((or (eq (get-text-property pos 'part-token) 'comment) + (eq (get-text-property pos 'block-token) 'comment)) + (setq prop + (if (get-text-property pos 'part-token) 'part-token 'block-token)) + (setq pair (web-mode-property-boundaries prop pos)) + (when (and pair (> (- (cdr pair) (car pair)) 6)) + (setq fill-coll (if (< fill-column 10) 70 fill-column)) + (setq beg (car pair) + end (cdr pair)) + (goto-char beg) + (setq chunk (buffer-substring-no-properties beg (+ beg 2))) + (cond + ((string= chunk "//") + (setq delim-beg "//" + delim-end "EOL")) + ((string= chunk "/*") + (setq delim-beg "/*" + delim-end "*/")) + ((string= chunk "{#") + (setq delim-beg "{#" + delim-end "#}")) + ((string= chunk "")) + ) + ) + ) ;comment - case + + ((web-mode-is-content) + (setq pair (web-mode-content-boundaries pos)) + (setq beg (car pair) + end (cdr pair)) + ) + + ) ;cond +;; (message "beg(%S) end(%S)" beg end) + (when (and beg end) + (fill-region beg end)) + t))) + +(defun web-mode-property-boundaries (prop &optional pos) + "property boundaries (cdr is 1+)" + (unless pos (setq pos (point))) + (let (beg end val) + (setq val (get-text-property pos prop)) + (if (null val) + val + (if (or (bobp) + (not (eq (get-text-property (1- pos) prop) val))) + (setq beg pos) + (setq beg (previous-single-property-change pos prop)) + (when (null beg) (setq beg (point-min)))) + (if (or (eobp) + (not (eq (get-text-property (1+ pos) prop) val))) + (setq end pos) + (setq end (next-single-property-change pos prop)) + (when (null end) (setq end (point-min)))) + (cons beg end)))) + +(defun web-mode-content-boundaries (&optional pos) + (unless pos (setq pos (point))) + (let (beg end) + (setq beg (or (previous-property-change pos (current-buffer)) + (point-max))) + (setq end (or (next-property-change pos (current-buffer)) + (point-min))) + (while (and (< beg end) (member (char-after beg) '(?\s ?\n))) + (setq beg (1+ beg))) + (while (and (> end beg) (member (char-after (1- end)) '(?\s ?\n))) + (setq end (1- end))) +;; (message "beg(%S) end(%S)" beg end) + (cons beg end) + )) + +(defun web-mode-engine-syntax-check () + (interactive) + (let ((proc nil) + (errors nil) + (file (concat temporary-file-directory "emacs-web-mode-tmp"))) + (write-region (point-min) (point-max) file) + (cond + ;; ((null (buffer-file-name)) + ;; ) + ((string= web-mode-engine "php") + (setq proc (start-process "php-proc" nil "php" "-l" file)) + (set-process-filter proc + (lambda (proc output) + (cond + ((string-match-p "No syntax errors" output) + (message "No syntax errors") + ) + (t +;; (setq output (replace-regexp-in-string temporary-file-directory "" output)) +;; (message output) + (message "Syntax error") + (setq errors t)) + ) ;cond +;; (delete-file file) + ) ;lambda + ) + ) ;php + (t + (message "no syntax checker found") + ) ;t + ) ;cond + errors)) + +(defun web-mode-jshint () + "Run JSHint on all the JavaScript parts." + (interactive) + (let (proc lines) + (when (buffer-file-name) + (setq proc (start-process + "jshint-proc" + nil + (or (executable-find "jshint") "/usr/local/bin/jshint") + "--extract=auto" + (buffer-file-name))) + (setq web-mode-jshint-errors 0) + (set-process-filter proc + (lambda (proc output) + (let ((offset 0) overlay pos (old 0) msg) + (remove-overlays (point-min) (point-max) 'font-lock-face 'web-mode-error-face) + (while (string-match + "line \\([[:digit:]]+\\), col \\([[:digit:]]+\\), \\(.+\\)\\.$" + output offset) + (setq web-mode-jshint-errors (1+ web-mode-jshint-errors)) + (setq offset (match-end 0)) + (setq pos (web-mode-coord-position + (match-string-no-properties 1 output) + (match-string-no-properties 2 output))) + (when (get-text-property pos 'tag-beg) + (setq pos (1- pos))) + (when (not (= pos old)) + (setq old pos) + (setq overlay (make-overlay pos (1+ pos))) + (overlay-put overlay 'font-lock-face 'web-mode-error-face) + ) + (setq msg (or (overlay-get overlay 'help-echo) + (concat "line=" + (match-string-no-properties 1 output) + " column=" + (match-string-no-properties 2 output) + ))) + (overlay-put overlay 'help-echo + (concat msg " ## " (match-string-no-properties 3 output))) + ) ;while + )) + ) + ) ;when + )) + +(defun web-mode-dom-errors-show () + "Show unclosed tags." + (interactive) + (let (beg end tag pos l n tags i cont cell overlay overlays first + (ori (point)) + (errors 0) + (continue t) + ) + (setq overlays (overlays-in (point-min) (point-max))) + (when overlays + (dolist (overlay overlays) + (when (eq (overlay-get overlay 'face) 'web-mode-warning-face) + (delete-overlay overlay) + ) + ) + ) + (goto-char (point-min)) + (when (not (or (get-text-property (point) 'tag-beg) + (web-mode-tag-next))) + (setq continue nil)) + (while continue + (setq pos (point)) + (setq tag (get-text-property pos 'tag-name)) + (cond + ((eq (get-text-property (point) 'tag-type) 'start) + (setq tags (add-to-list 'tags (list tag pos))) +;; (message "(%S) opening %S" pos tag) + ) + ((eq (get-text-property (point) 'tag-type) 'end) + (setq i 0 + l (length tags) + cont t) + (while (and (< i l) cont) + (setq cell (nth i tags)) +;; (message "cell=%S" cell) + (setq i (1+ i)) + (cond + ((string= tag (nth 0 cell)) + (setq cont nil) + ) + (t + (setq errors (1+ errors)) + (setq beg (nth 1 cell)) + (setq end (web-mode-tag-end-position beg)) + (unless first + (setq first beg)) + (setq overlay (make-overlay beg (1+ end))) + (overlay-put overlay 'font-lock-face 'web-mode-warning-face) +;; (message "invalid <%S> at %S" (nth 0 cell) (nth 1 cell)) + ) + ) ;cond + ) ;while + + (dotimes (i i) + (setq tags (cdr tags))) + + ) + ) ;cond + (when (not (web-mode-tag-next)) + (setq continue nil)) + ) ;while + (message "%S error(s) detected" errors) + (if (< errors 1) + (goto-char ori) + (goto-char first) + (recenter)) + ;; (message "%S" tags) + )) + +(defun web-mode-highlight-elements (beg end) + (save-excursion + (goto-char beg) + (let ((continue (or (get-text-property (point) 'tag-beg) (web-mode-tag-next))) + (i 0) (ctx nil) (face nil)) + (while continue + (cond + ((> (setq i (1+ i)) 1000) + (message "highlight-elements ** too much tags **") + (setq continue nil)) + ((> (point) end) + (setq continue nil)) + ((not (get-text-property (point) 'tag-beg)) + (setq continue nil)) + ((eq (get-text-property (point) 'tag-type) 'start) + (when (and (setq ctx (web-mode-element-boundaries (point))) + (<= (car (cdr ctx)) end) + (setq face (cdr (assoc (get-text-property (point) 'tag-name) web-mode-element-content-faces)))) + (font-lock-prepend-text-property (1+ (cdr (car ctx))) (car (cdr ctx)) + 'font-lock-face face)) + ) + ) ;cond + (when (not (web-mode-tag-next)) + (setq continue nil)) + ) ;while + ))) + +(defun web-mode-enable (feature) + "Enable one feature." + (interactive + (list (completing-read + "Feature: " + (let (features) + (dolist (elt web-mode-features) + (setq features (append features (list (car elt))))) + features)))) + (when (and (or (not feature) (< (length feature) 1)) web-mode-last-enabled-feature) + (setq feature web-mode-last-enabled-feature)) + (when feature + (setq web-mode-last-enabled-feature feature) + (setq feature (cdr (assoc feature web-mode-features))) + (cond + ((eq feature 'web-mode-enable-current-column-highlight) + (web-mode-column-show)) + ((eq feature 'web-mode-enable-current-element-highlight) + (when (not web-mode-enable-current-element-highlight) + (web-mode-toggle-current-element-highlight)) + ) + ((eq feature 'web-mode-enable-whitespace-fontification) + (web-mode-whitespaces-on)) + (t + (set feature t) + (web-mode-buffer-highlight)) + ) + ) ;when + ) + +(defun web-mode-disable (feature) + "Disable one feature." + (interactive + (list (completing-read + "Feature: " + (let (features) + (dolist (elt web-mode-features) + (setq features (append features (list (car elt))))) + features)))) + (when (and (or (not feature) (< (length feature) 1)) web-mode-last-enabled-feature) + (setq feature web-mode-last-enabled-feature)) + (when feature + (setq feature (cdr (assoc feature web-mode-features))) + (cond + ((eq feature 'web-mode-enable-current-column-highlight) + (web-mode-column-hide)) + ((eq feature 'web-mode-enable-current-element-highlight) + (when web-mode-enable-current-element-highlight + (web-mode-toggle-current-element-highlight)) + ) + ((eq feature 'web-mode-enable-whitespace-fontification) + (web-mode-whitespaces-off)) + (t + (set feature nil) + (web-mode-buffer-highlight)) + ) + ) ;when + ) + +(defun web-mode-make-tag-overlays () + (unless web-mode-overlay-tag-start + (setq web-mode-overlay-tag-start (make-overlay 1 1) + web-mode-overlay-tag-end (make-overlay 1 1)) + (overlay-put web-mode-overlay-tag-start + 'font-lock-face + 'web-mode-current-element-highlight-face) + (overlay-put web-mode-overlay-tag-end + 'font-lock-face + 'web-mode-current-element-highlight-face))) + +(defun web-mode-delete-tag-overlays () + (when web-mode-overlay-tag-start + (delete-overlay web-mode-overlay-tag-start) + (delete-overlay web-mode-overlay-tag-end))) + +(defun web-mode-column-overlay-factory (index) + (let (overlay) + (when (null web-mode-column-overlays) + (dotimes (i 100) + (setq overlay (make-overlay 1 1)) + (overlay-put overlay 'font-lock-face 'web-mode-current-column-highlight-face) + (setq web-mode-column-overlays (append web-mode-column-overlays (list overlay))) + ) + ) ;when + (setq overlay (nth index web-mode-column-overlays)) + (when (null overlay) + (setq overlay (make-overlay 1 1)) + (overlay-put overlay 'font-lock-face 'web-mode-current-column-highlight-face) + (setq web-mode-column-overlays (append web-mode-column-overlays (list overlay))) + ) ;when + overlay)) + +(defun web-mode-column-hide () + (setq web-mode-enable-current-column-highlight nil) + (remove-overlays (point-min) (point-max) + 'font-lock-face + 'web-mode-current-column-highlight-face)) + +(defun web-mode-column-show () + (let ((index 0) overlay diff column line-to line-from) + (web-mode-column-hide) + (setq web-mode-enable-current-column-highlight t) + (save-excursion + (back-to-indentation) + (setq column (current-column) + line-to (web-mode-line-number)) + (when (and (get-text-property (point) 'tag-beg) + (member (get-text-property (point) 'tag-type) '(start end)) + (web-mode-tag-match) + (setq line-from (web-mode-line-number)) + (not (= line-from line-to))) + (when (> line-from line-to) + (let (tmp) + (setq tmp line-from) + (setq line-from line-to) + (setq line-to tmp)) + ) ;when + ;;(message "column(%S) line-from(%S) line-to(%S)" column line-from line-to) + (goto-char (point-min)) + (when (> line-from 1) + (forward-line (1- line-from))) + (while (<= line-from line-to) + (setq overlay (web-mode-column-overlay-factory index)) + (setq diff (- (line-end-position) (point))) + (cond + ((or (and (= column 0) (= diff 0)) + (> column diff)) + (end-of-line) + (move-overlay overlay (point) (point)) + (overlay-put overlay + 'after-string + (concat + (if (> column diff) (make-string (- column diff) ?\s) "") + (propertize " " + 'font-lock-face + 'web-mode-current-column-highlight-face) + ) ;concat + ) + ) + (t + (move-to-column column) + (overlay-put overlay 'after-string nil) + (move-overlay overlay (point) (1+ (point))) + ) + ) ;cond + (setq line-from (1+ line-from)) + (forward-line) + (setq index (1+ index)) + ) ;while + ) ;when + ) ;save-excursion + ) ;let + ) + +(defun web-mode-highlight-current-element () + (let ((ctx (web-mode-element-boundaries)) len) + (cond + ((null ctx) + (web-mode-delete-tag-overlays)) + (t + (web-mode-make-tag-overlays) + (setq len (length (get-text-property (caar ctx) 'tag-name))) + (move-overlay web-mode-overlay-tag-start (+ (caar ctx) 1) (+ (caar ctx) 1 len)) + (move-overlay web-mode-overlay-tag-end (+ (cadr ctx) 2) (+ (cadr ctx) 2 len)) + ) ;t + ) ;cond + )) + +(defun web-mode-highlight-whitespaces (beg end) + (save-excursion + (goto-char beg) + (while (re-search-forward web-mode-whitespaces-regexp end t) + (add-text-properties (match-beginning 0) (match-end 0) + '(face web-mode-whitespace-face)) + ) ;while + )) + +(defun web-mode-whitespaces-show () + "Toggle whitespaces." + (interactive) + (if web-mode-enable-whitespace-fontification + (web-mode-whitespaces-off) + (web-mode-whitespaces-on))) + +(defun web-mode-whitespaces-on () + "Show whitespaces." + (interactive) + (when web-mode-display-table + (setq buffer-display-table web-mode-display-table)) + (setq web-mode-enable-whitespace-fontification t)) + +(defun web-mode-whitespaces-off () + (setq buffer-display-table nil) + (setq web-mode-enable-whitespace-fontification nil)) + +(defun web-mode-use-tabs () + "Tweaks vars to be compatible with TAB indentation." + (let (offset) + (setq web-mode-block-padding 0) + (setq web-mode-script-padding 0) + (setq web-mode-style-padding 0) + (setq offset + (cond + ((and (boundp 'tab-width) tab-width) tab-width) + ((and (boundp 'standard-indent) standard-indent) standard-indent) + (t 4))) + ;; (message "offset(%S)" offset) + (setq web-mode-attr-indent-offset offset) + (setq web-mode-code-indent-offset offset) + (setq web-mode-css-indent-offset offset) + (setq web-mode-markup-indent-offset offset) + (setq web-mode-sql-indent-offset offset) + (add-to-list 'web-mode-indentation-params '("lineup-args" . nil)) + (add-to-list 'web-mode-indentation-params '("lineup-calls" . nil)) + (add-to-list 'web-mode-indentation-params '("lineup-concats" . nil)) + (add-to-list 'web-mode-indentation-params '("lineup-ternary" . nil)) + )) + +(defun web-mode-buffer-indent () + "Indent all buffer." + (interactive) + (indent-region (point-min) (point-max)) + (delete-trailing-whitespace)) + +(defun web-mode-buffer-change-tag-case (&optional type) + "Change html tag case." + (interactive) + (save-excursion + (goto-char (point-min)) + (let ((continue t) f) + (setq f (if (member type '("upper" "uppercase" "upper-case")) 'uppercase 'downcase)) + (when (and (not (get-text-property (point) 'tag-beg)) + (not (web-mode-tag-next))) + (setq continue nil)) + (while continue + (skip-chars-forward " depth 1)) + (when (get-text-property pos 'jsx-beg) + (setq depth (1- depth))) + (setq reg-beg (web-mode-jsx-depth-beginning-position pos depth)) + (setq reg-beg (1+ reg-beg)) + (save-excursion + (goto-char reg-beg) + (cond + ((and (not (looking-at-p "[ ]*$")) + (looking-back "^[[:space:]]*{")) + (setq reg-col (+ (current-indentation) 1 + (cond + ((looking-at "[ ]+") (length (match-string-no-properties 0))) + (t 0)) + )) + ) + ((looking-at-p "[ ]*\\[[ ]*$") ;; #0659 + (setq reg-col (current-indentation)) + ) + (t + ;;(message "%S %S : %S %S" (point) (current-indentation) web-mode-code-indent-offset) + ;;(setq reg-col (+ (current-indentation) web-mode-code-indent-offset web-mode-jsx-expression-padding))) + (setq reg-col (+ (current-indentation) web-mode-code-indent-offset))) + ) + + ;;(message "%S %S %S" (point) (current-indentation) reg-col) + ) ;save-excursion + ) + ((string= web-mode-content-type "jsx") + (setq reg-beg (point-min))) + (t + (setq reg-beg (or (web-mode-part-beginning-position pos) (point-min))) + (save-excursion + (goto-char reg-beg) + (search-backward "<" nil t) + (setq reg-col (current-column)) + ) ;save-excursion + ) + ) ;cond + ;;(message "jsx reg-beg=%S" reg-beg) + ) ;jsx + + ((string= web-mode-content-type "php") + (setq language "php" + curr-indentation web-mode-code-indent-offset)) + + ((or (string= web-mode-content-type "xml")) + (setq language "xml" + curr-indentation web-mode-markup-indent-offset)) + + ;; TODO: est ce util ? + ((and (get-text-property pos 'tag-beg) + (get-text-property pos 'tag-name) + ;;(not (get-text-property pos 'part-side)) + ) + (setq language "html" + curr-indentation web-mode-markup-indent-offset)) + + ((and (get-text-property pos 'block-side) + (not (get-text-property pos 'block-beg))) + + (setq reg-beg (or (web-mode-block-beginning-position pos) (point-min))) + (goto-char reg-beg) + (setq reg-col (current-column)) + (setq language web-mode-engine) + (setq curr-indentation web-mode-code-indent-offset) + + (cond + ((string= web-mode-engine "blade") + (save-excursion + (when (web-mode-rsf "{[{!]+[ ]*") + (setq reg-col (current-column)))) + (setq reg-beg (+ reg-beg 2)) + ) + ((string= web-mode-engine "razor") + (setq reg-beg (+ reg-beg 2)) + ) + ;; tests/demo.chtml + ((string= web-mode-engine "ctemplate") + (save-excursion + (when (web-mode-rsf "{{#?") + (setq reg-col (current-column)))) + ) + ((string= web-mode-engine "dust") + (save-excursion + (when (web-mode-rsf "{@") + (setq reg-col (current-column)))) + ) + ((string= web-mode-engine "template-toolkit") + (setq reg-beg (+ reg-beg 3) + reg-col (+ reg-col 3)) + ) + ((and (string= web-mode-engine "jsp") + (web-mode-looking-at "<%@\\|<[[:alpha:]]" reg-beg)) + (save-excursion + (goto-char reg-beg) + (looking-at "<%@[ ]*[[:alpha:]]+[ ]+\\| pos (point-min)) + (eq (get-text-property pos 'part-token) 'comment) + (eq (get-text-property (1- pos) 'part-token) 'comment) + (progn + (setq reg-beg (previous-single-property-change pos 'part-token)) + t)) + (and (> pos (point-min)) + (eq (get-text-property pos 'block-token) 'comment) + (eq (get-text-property (1- pos) 'block-token) 'comment) + (progn + (setq reg-beg (previous-single-property-change pos 'block-token)) + t)) + (and (> pos (point-min)) + (eq (get-text-property pos 'tag-type) 'comment) + (not (get-text-property pos 'tag-beg)) + (progn + (setq reg-beg (web-mode-tag-beginning-position pos)) + t)) + ) + (setq token "comment")) + ((or (and (> pos (point-min)) + (member (get-text-property pos 'part-token) + '(string context key)) + (member (get-text-property (1- pos) 'part-token) + '(string context key))) + (and (eq (get-text-property pos 'block-token) 'string) + (eq (get-text-property (1- pos) 'block-token) 'string))) + (setq token "string")) + ) + + (goto-char pos) + (setq curr-line (web-mode-trim + (buffer-substring-no-properties + (line-beginning-position) + (line-end-position)))) + (setq curr-char (if (string= curr-line "") 0 (aref curr-line 0))) + + (when (or (member language '("php" "blade" "javascript" "jsx" "razor")) + (and (member language '("html" "xml")) + (not (eq ?\< curr-char)))) + (let (prev) + (cond + ((member language '("html" "xml" "javascript" "jsx")) + (when (setq prev (web-mode-part-previous-live-line reg-beg)) + (setq prev-line (car prev) + prev-indentation (cdr prev)) + (setq prev-line (web-mode-clean-part-line prev-line))) + ) + ((setq prev (web-mode-block-previous-live-line)) + (setq prev-line (car prev) + prev-indentation (cdr prev)) + (setq prev-line (web-mode-clean-block-line prev-line))) + ) ;cond + ) ;let + (when (>= (length prev-line) 1) + (setq prev-char (aref prev-line (1- (length prev-line)))) + (setq prev-line (substring-no-properties prev-line)) + ) + ) + + (cond + ((not (member web-mode-content-type '("html" "xml"))) + ) + ((member language '("javascript" "jsx")) + (setq reg-col (+ reg-col web-mode-script-padding))) + ((member language '("css")) + (setq reg-col (+ reg-col web-mode-style-padding))) + ((not (member language '("html" "xml" "razor"))) + (setq reg-col (+ reg-col web-mode-block-padding))) + ) + + (list :curr-char curr-char + :curr-indentation curr-indentation + :curr-line curr-line + :language language + :options options + :prev-char prev-char + :prev-indentation prev-indentation + :prev-line prev-line + :reg-beg reg-beg + :reg-col reg-col + :token token) + ))) + +(defun web-mode-indent-line () + + (web-mode-propertize) + + (let ((offset nil) + (char nil) + (inhibit-modification-hooks t) + (adjust t)) + + (save-excursion + (back-to-indentation) + (setq char (char-after)) + (let* ((pos (point)) + (ctx (web-mode-point-context pos)) + (curr-char (plist-get ctx :curr-char)) + (curr-indentation (plist-get ctx :curr-indentation)) + (curr-line (plist-get ctx :curr-line)) + (language (plist-get ctx :language)) + (prev-char (plist-get ctx :prev-char)) + (prev-indentation (plist-get ctx :prev-indentation)) + (prev-line (plist-get ctx :prev-line)) + (reg-beg (plist-get ctx :reg-beg)) + (reg-col (plist-get ctx :reg-col)) + (token (plist-get ctx :token)) + (options (plist-get ctx :options)) + (chars (list curr-char prev-char))) + + ;;(message "curr-char=[%c] prev-char=[%c]\n%S" curr-char prev-char ctx) + + (cond + + ((or (bobp) (= (line-number-at-pos pos) 1)) + (setq offset 0)) + + ((string= token "string") + (cond + ((and web-mode-enable-sql-detection + (web-mode-block-token-starts-with (concat "[ \n]*" web-mode-sql-queries))) + (save-excursion + (let (col) + (web-mode-block-string-beginning) + (skip-chars-forward "[ \"'\n]") + (setq col (current-column)) + (goto-char pos) + (if (looking-at-p "\\(SELECT\\|INSERT\\|DELETE\\|UPDATE\\|FROM\\|LEFT\\|JOIN\\|WHERE\\|GROUP BY\\|LIMIT\\|HAVING\\|\)\\)") + (setq offset col) + (setq offset (+ col web-mode-sql-indent-offset))) + ) + ) ;save-excursion + ) + (t + (setq offset nil)) + ) ;cond + ) ;case string + + ((string= token "comment") + (if (eq (get-text-property pos 'tag-type) 'comment) + (web-mode-tag-beginning) + (goto-char (car + (web-mode-property-boundaries + (if (eq (get-text-property pos 'part-token) 'comment) + 'part-token + 'block-token) + pos)))) + (setq offset (current-column)) + ;;(message "%S %S" (point) offset) + (cond + ((member (buffer-substring-no-properties (point) (+ (point) 2)) '("/*" "{*" "@*")) + (cond + ((eq ?\* curr-char) + (setq offset (+ offset 1))) + (t + (setq offset (+ offset 3))) + ) ;cond + ) + ((string= (buffer-substring-no-properties (point) (+ (point) 4)) "" (point)) + (web-mode-insert-text-at-pos "" (point)) + (web-mode-insert-text-at-pos "") + (search-backward " -->")) + ) + ) + +(defun web-mode-comment (pos) + (let (ctx language sel beg end tmp block-side single-line-block pos-after content) + + (setq pos-after pos) + + (setq block-side (get-text-property pos 'block-side)) + (setq single-line-block (web-mode-is-single-line-block pos)) + + (cond + + ((and block-side (string= web-mode-engine "erb")) + (web-mode-comment-erb-block pos) + ) + + ((and single-line-block block-side + (intern-soft (concat "web-mode-comment-" web-mode-engine "-block"))) + (funcall (intern (concat "web-mode-comment-" web-mode-engine "-block")) pos) + ) + + (t + (setq ctx (web-mode-point-context + (if mark-active (region-beginning) (line-beginning-position)))) + (setq language (plist-get ctx :language)) + (cond + (mark-active + ) + ((and (member language '("html" "xml")) + (get-text-property (progn (back-to-indentation) (point)) 'tag-beg)) + (web-mode-element-select)) + (t + (end-of-line) + (set-mark (line-beginning-position))) + ) ;cond + + (setq beg (region-beginning) + end (region-end)) + + (when (> (point) (mark)) + (exchange-point-and-mark)) + + (if (and (eq (char-before end) ?\n) + (not (eq (char-after end) ?\n))) + (setq end (1- end))) + + (setq sel (buffer-substring-no-properties beg end)) + + (cond + + ((member language '("html" "xml")) + (cond + ((and (= web-mode-comment-style 2) (string= web-mode-engine "django")) + (setq content (concat "{# " sel " #}"))) + ((and (= web-mode-comment-style 2) (member web-mode-engine '("ejs" "erb"))) + (setq content (concat "<%# " sel " %>"))) + ((and (= web-mode-comment-style 2) (string= web-mode-engine "aspx")) + (setq content (concat "<%-- " sel " --%>"))) + ((and (= web-mode-comment-style 2) (string= web-mode-engine "smarty")) + (setq content (concat "{* " sel " *}"))) + ((and (= web-mode-comment-style 2) (string= web-mode-engine "blade")) + (setq content (concat "{{-- " sel " --}}"))) + ((and (= web-mode-comment-style 2) (string= web-mode-engine "ctemplate")) + (setq content (concat "{{!-- " sel " --}}"))) + ((and (= web-mode-comment-style 2) (string= web-mode-engine "razor")) + (setq content (concat "@* " sel " *@"))) + (t + (setq content (concat "")) + (when (< (length sel) 1) + (search-backward " -->") + (setq pos-after nil)) + )) + ) ;case html + + ((member language '("php" "javascript" "java" "jsx")) + (let (alt) + (cond + ((get-text-property pos 'jsx-depth) + (setq content (concat "{/* " sel " */}")) + ;;(message "%S" pos) + ) + ((and (setq alt (cdr (assoc language web-mode-comment-formats))) + (string= alt "//")) + (setq content (replace-regexp-in-string "^[ ]*" alt sel))) + (t + (setq content (concat "/* " sel " */"))) + ) ;cond + ) + ) + + ((member language '("erb")) + (setq content (replace-regexp-in-string "^[ ]*" "#" sel))) + + ((member language '("asp")) + (setq content (replace-regexp-in-string "^[ ]*" "''" sel))) + + (t + (setq content (concat "/* " sel " */"))) + + ) ;cond + + (when content + (delete-region beg end) + (deactivate-mark) + (let (beg end) + (setq beg (point-at-bol)) + (insert content) + (setq end (point-at-eol)) + (indent-region beg end) + ) + ) ;when + + ) ;t + ) ;cond + + (when pos-after (goto-char pos-after)) + + )) + +(defun web-mode-comment-ejs-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-insert-text-at-pos "//" (+ beg 2)))) + +(defun web-mode-comment-erb-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-insert-text-at-pos "#" (+ beg 2)))) + +(defun web-mode-comment-django-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-insert-text-at-pos "#" end) + (web-mode-insert-text-at-pos "#" (1+ beg)))) + +(defun web-mode-comment-dust-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-insert-text-at-pos "!" end) + (web-mode-insert-text-at-pos "!" (1+ beg)))) + +(defun web-mode-comment-aspx-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-insert-text-at-pos "#" end) + (web-mode-insert-text-at-pos "#" (1+ beg)))) + +(defun web-mode-comment-jsp-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-insert-text-at-pos "--" (+ beg 2)))) + +(defun web-mode-comment-go-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-insert-text-at-pos "/" (+ beg 2)))) + +(defun web-mode-comment-php-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-insert-text-at-pos "*/" (- end 1)) + (web-mode-insert-text-at-pos "/*" (+ beg (if (web-mode-looking-at "<\\?php" beg) 5 3))))) + +(defun web-mode-comment-boundaries (&optional pos) + (interactive) + (unless pos (setq pos (point))) + (let ((beg pos) (end pos) prop) + (save-excursion + (goto-char pos) + (setq prop + (cond + ((eq (get-text-property pos 'block-token) 'comment) 'block-token) + ((eq (get-text-property pos 'tag-type) 'comment) 'tag-type) + ((eq (get-text-property pos 'part-token) 'comment) 'part-token) + (t nil) + )) + (if (null prop) + (setq beg nil + end nil) + (when (and (not (bobp)) + (eq (get-text-property pos prop) (get-text-property (1- pos) prop))) + (setq beg (or (previous-single-property-change pos prop) (point-min)))) + (when (and (not (eobp)) + (eq (get-text-property pos prop) (get-text-property (1+ pos) prop))) + (setq end (or (next-single-property-change pos prop) (point-max))))) + (when (and beg (string= (buffer-substring-no-properties beg (+ beg 2)) "//")) + (goto-char end) + (while (and (looking-at-p "\n[ ]*//") + (not (eobp))) + (search-forward "//") + (backward-char 2) + ;;(message "%S" (point)) + (setq end (next-single-property-change (point) prop)) + (goto-char end) + ;;(message "%S" (point)) + ) ;while + ) ;when + (when end (setq end (1- end))) + ) ; save-excursion + ;;(message "beg=%S end=%S" beg end) + (if (and beg end) (cons beg end) nil) + )) + +(defun web-mode-uncomment (pos) + (let ((beg pos) (end pos) (sub2 "") comment boundaries) + (save-excursion + (cond + ((and (get-text-property pos 'block-side) + (intern-soft (concat "web-mode-uncomment-" web-mode-engine "-block"))) + (funcall (intern (concat "web-mode-uncomment-" web-mode-engine "-block")) pos)) + ((and (setq boundaries (web-mode-comment-boundaries pos)) + (setq beg (car boundaries)) + (setq end (1+ (cdr boundaries))) + (> (- end beg) 4)) + ;;(message "beg(%S) end(%S)" beg end) + (setq comment (buffer-substring-no-properties beg end)) + (setq sub2 (substring comment 0 2)) + (cond + ((member sub2 '("$\\)" "" comment))) + ((string= sub2 "{#") + (setq comment (replace-regexp-in-string "\\(^{#[ ]?\\|[ ]?#}$\\)" "" comment))) + ((string= sub2 "{/") ;;jsx comments + (setq comment (replace-regexp-in-string "\\(^{/\\*[ ]?\\|[ ]?\\*/}$\\)" "" comment))) + ((string= sub2 "/*") + (setq comment (replace-regexp-in-string "\\(^/\\*[ ]?\\|[ ]?\\*/$\\)" "" comment))) + ((string= sub2 "//") + (setq comment (replace-regexp-in-string "\\(//\\)" "" comment))) + ) ;cond + (delete-region beg end) + (web-mode-insert-and-indent comment) + (goto-char beg) + ) + ) ;cond + (indent-according-to-mode)))) + +(defun web-mode-uncomment-erb-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (if (string-match-p "<[%[:alpha:]]" (buffer-substring-no-properties (+ beg 2) (- end 2))) + (progn + (web-mode-remove-text-at-pos 2 (1- end)) + (web-mode-remove-text-at-pos 3 beg)) + (web-mode-remove-text-at-pos 1 (+ beg 2)) + ) ;if + ) + ) + +(defun web-mode-uncomment-ejs-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-remove-text-at-pos 1 (+ beg 2)))) + +(defun web-mode-uncomment-django-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-remove-text-at-pos 2 (1- end)) + (web-mode-remove-text-at-pos 2 beg))) + +(defun web-mode-uncomment-ctemplate-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-remove-text-at-pos 5 (- end 4)) + (web-mode-remove-text-at-pos 5 beg))) + +(defun web-mode-uncomment-dust-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-remove-text-at-pos 1 (1- end)) + (web-mode-remove-text-at-pos 1 (1+ beg)))) + +(defun web-mode-uncomment-aspx-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-remove-text-at-pos 1 (1- end)) + (web-mode-remove-text-at-pos 1 (1+ beg)))) + +(defun web-mode-uncomment-jsp-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-remove-text-at-pos 2 (+ beg 2)))) + +(defun web-mode-uncomment-go-block (pos) + (let (beg end) + (setq beg (web-mode-block-beginning-position pos) + end (web-mode-block-end-position pos)) + (web-mode-remove-text-at-pos 1 (+ beg 2)))) + +(defun web-mode-snippet-names () + (let (codes) + (dolist (snippet web-mode-snippets) + (add-to-list 'codes (car snippet) t)) + codes)) + +(defun web-mode-snippet-insert (code) + "Insert a snippet." + (interactive + (list (completing-read "Snippet: " (web-mode-snippet-names)))) + (let (beg + (continue t) + (counter 0) + end + sel + snippet + (l (length web-mode-snippets)) + pos) + (when mark-active + (setq sel (web-mode-trim (buffer-substring-no-properties + (region-beginning) (region-end)))) + (delete-region (region-beginning) (region-end))) + (while (and continue (< counter l)) + (setq snippet (nth counter web-mode-snippets)) + (when (string= (car snippet) code) + (setq continue nil)) + (setq counter (1+ counter))) + (when snippet + (setq snippet (cdr snippet)) + (setq beg (point-at-bol)) + (insert snippet) + (setq pos (point) + end (point)) + (when (string-match-p "|" snippet) + (search-backward "|") + (delete-char 1) + (setq pos (point) + end (1- end))) + (when sel + (insert sel) + (setq pos (point) + end (+ end (length sel)))) + (goto-char end) + (setq end (point-at-eol)) + (unless sel (goto-char pos)) + (indent-region beg end)) + )) + +(defun web-mode-looking-at (regexp pos) + (save-excursion + (goto-char pos) + (looking-at regexp))) + +(defun web-mode-looking-at-p (regexp pos) + (save-excursion + (goto-char pos) + (looking-at-p regexp))) + +(defun web-mode-looking-back (regexp pos &optional limit greedy) + (save-excursion + (goto-char pos) + (if limit + (looking-back regexp limit greedy) + (looking-back regexp)))) + +(defun web-mode-insert-text-at-pos (text pos) + (let ((mem web-mode-enable-auto-pairing)) + (setq web-mode-enable-auto-pairing nil) + (save-excursion + (goto-char pos) + (insert text) + (setq web-mode-enable-auto-pairing mem) + ))) + +(defun web-mode-remove-text-at-pos (n &optional pos) + (unless pos (setq pos (point))) + (delete-region pos (+ pos n))) + +(defun web-mode-insert-and-indent (text) + (let (beg end) + (setq beg (point-at-bol)) + (insert text) + (setq end (point-at-eol)) + (indent-region beg end) + )) + +(defun web-mode-indentation-at-pos (pos) + (save-excursion + (goto-char pos) + (current-indentation))) + +(defun web-mode-navigate (&optional pos) + "Move point to the matching opening/closing tag/block." + (interactive) + (unless pos (setq pos (point))) + (let (init) + (goto-char pos) + (setq init (point)) + (when (> (current-indentation) (current-column)) + (back-to-indentation)) + (setq pos (point)) + (cond + ((and (get-text-property pos 'block-side) + (web-mode-block-beginning) + (web-mode-block-controls-get (point))) + (web-mode-block-match)) + ((member (get-text-property pos 'tag-type) '(start end)) + (web-mode-tag-beginning) + (web-mode-tag-match)) + (t + (goto-char init)) + ) + )) + +(defun web-mode-block-match (&optional pos) + (unless pos (setq pos (point))) + (let (pos-ori controls control (counter 1) type (continue t) pair) + (setq pos-ori pos) + (goto-char pos) + (setq controls (web-mode-block-controls-get pos)) +;; (message "controls=%S" controls) + (cond + (controls + (setq pair (car controls)) + (setq control (cdr pair)) + (setq type (car pair)) + (when (eq type 'inside) (setq type 'close)) + (while continue + (cond + ((and (> pos-ori 1) (bobp)) + (setq continue nil)) + ((or (and (eq type 'open) (not (web-mode-block-next))) + (and (eq type 'close) (not (web-mode-block-previous)))) + (setq continue nil) + ) + ((null (setq controls (web-mode-block-controls-get (point)))) + ) + (t + ;; TODO : est il nécessaire de faire un reverse sur controls si on doit matcher backward + (dolist (pair controls) + (cond + ((not (string= (cdr pair) control)) + ) + ((eq (car pair) 'inside) + ) + ((eq (car pair) type) + (setq counter (1+ counter))) + (t + (setq counter (1- counter))) + ) + ) ;dolist + (when (= counter 0) + (setq continue nil)) + ) ;t + ) ;cond + ) ;while + (if (= counter 0) (point) nil) + ) ;controls + (t + (goto-char pos-ori) + nil + ) ;controls = nul + ) ;conf + )) + +(defun web-mode-tag-match (&optional pos) + "Move point to the matching opening/closing tag." + (interactive) + (unless pos (setq pos (point))) + (let (regexp) + (setq regexp (concat " counter 0) (re-search-backward regexp nil t)) + (when (and (get-text-property (point) 'tag-beg) + (member (get-text-property (point) 'tag-type) '(start end))) + (setq n (1+ n)) + (cond + ((eq (get-text-property (point) 'tag-type) 'end) + (setq counter (1+ counter))) + (t + (setq counter (1- counter)) + ) + ) + ) + ) + (if (= n 0) (goto-char pos)) + )) + +(defun web-mode-tag-fetch-closing (regexp pos) + (let ((counter 1) (n 0)) + (goto-char pos) + (web-mode-tag-end) + (while (and (> counter 0) (re-search-forward regexp nil t)) + (when (get-text-property (match-beginning 0) 'tag-beg) + (setq n (1+ n)) + (if (eq (get-text-property (point) 'tag-type) 'end) + (setq counter (1- counter)) + (setq counter (1+ counter)))) + ) + (if (> n 0) + (web-mode-tag-beginning) + (goto-char pos)) + )) + +(defun web-mode-element-tag-name (&optional pos) + (unless pos (setq pos (point))) + (save-excursion + (goto-char pos) + (if (and (web-mode-tag-beginning) + (looking-at "<\\(/?[[:alpha:]][[:alnum:]:-]*\\)")) + (match-string-no-properties 1) + nil))) + +(defun web-mode-element-close () + "Close html element." + (interactive) + (let (jump epp ins tag) + + (if (and (eq (char-before) ?\>) + (web-mode-element-is-void (get-text-property (1- (point)) 'tag-name))) + (unless (eq (char-before (1- (point))) ?\/) + (backward-char) + (insert "/") + (forward-char)) + (setq epp (web-mode-element-parent-position))) + + ;;(message "epp=%S" epp) + (when epp + (setq tag (get-text-property epp 'tag-name)) + (setq tag (web-mode-element-tag-name epp)) + ;;(message "tag=%S %c" tag (char-before)) + (cond + ((or (null tag) (web-mode-element-is-void tag)) + (setq epp nil)) + ((looking-back " (length tag) 4)) + (dolist (elt '("div" "span" "strong" "pre" "li")) + (when (and (string-match-p (concat "^" elt) tag) (not (string= tag elt))) + (setq tag elt) + (put-text-property epp (point) 'tag-name tag)) + ) + ) ;when + (if (web-mode-element-is-void (get-text-property (point) 'tag-name)) + (setq ins nil + epp nil) + (setq ins (concat "") + (setq ins (concat ins ">"))) + (insert ins) + (save-excursion + (search-backward "<") + (setq jump (and (eq (char-before) ?\>) + (string= (get-text-property (1- (point)) 'tag-name) tag))) + (if jump (setq jump (point))) + ) ;save-excursion + (if jump (goto-char jump)) + ) ;when not ins + ) ;when epp + epp)) + +(defun web-mode-detect-content-type () + (cond + ((and (string= web-mode-engine "none") + (< (point) 16) + (eq (char-after 1) ?\#) + (string-match-p "php" (buffer-substring-no-properties + (line-beginning-position) + (line-end-position)))) + (web-mode-set-engine "php")) + ((and (string= web-mode-content-type "javascript") + (< (point) web-mode-chunk-length) + (eq (char-after (point-min)) ?\/) + (string-match-p "@jsx" (buffer-substring-no-properties + (line-beginning-position) + (line-end-position)))) + (web-mode-set-content-type "jsx")) + )) + +(defun web-mode-on-after-change (beg end len) +;; (message "after-change: pos=%d, beg=%d, end=%d, len=%d, ocmd=%S, cmd=%S" (point) beg end len this-original-command this-command) + ;; (backtrace) +;; (message "this-command=%S" this-command) + (when (eq this-original-command 'yank) + (setq web-mode-inhibit-fontification t)) + (when (or (null web-mode-change-beg) (< beg web-mode-change-beg)) + (setq web-mode-change-beg beg)) + (when (or (null web-mode-change-end) (> end web-mode-change-end)) + (setq web-mode-change-end end)) + ) + +(defun web-mode-complete () + "Autocomple at point." + (interactive) + (let ((pos (point)) + (char (char-before)) + (chunk (buffer-substring-no-properties (- (point) 2) (point))) + (auto-closed nil) + (auto-expanded nil) + (auto-paired nil) + (auto-quoted nil) + expanders) + + ;;-- auto-closing + (when (and web-mode-enable-auto-closing + (>= pos 4) + (or (string= "" chunk))) + (not (get-text-property (- pos 2) 'block-side)) + (web-mode-element-close)) + (setq auto-closed t)) + + ;;-- auto-pairing + (when (and web-mode-enable-auto-pairing + (>= pos 4) + (not auto-closed)) + (let ((i 0) expr after pos-end (l (length web-mode-auto-pairs))) + (setq pos-end (if (> (+ pos 32) (line-end-position)) + (line-end-position) + (+ pos 10))) + (setq chunk (buffer-substring-no-properties (- pos 3) pos) + after (buffer-substring-no-properties pos pos-end)) + (while (and (< i l) (not auto-paired)) + (setq expr (elt web-mode-auto-pairs i) + i (1+ i)) + ;;(message "chunk=%S expr=%S after=%S" chunk expr after) + (when (and (string= (car expr) chunk) + (not (string-match-p (regexp-quote (cdr expr)) after))) + (setq auto-paired t) + (insert (cdr expr)) + (if (string-match-p "|" (cdr expr)) + (progn + (search-backward "|") + (delete-char 1)) + (goto-char pos)) + ) ;when + ) ;while + ) ;let + ) + + ;;-- auto-expanding + (when (and web-mode-enable-auto-expanding + (not auto-closed) + (not auto-paired) + (eq char ?\/) + (not (get-text-property (1- pos) 'tag-type)) + (not (get-text-property (1- pos) 'part-side)) + (not (get-text-property (1- pos) 'block-side)) + (looking-back "\\(^\\|[[:punct:][:space:]>]\\)./")) + (setq expanders (append web-mode-expanders web-mode-extra-expanders)) + (let ((i 0) pair (l (length expanders))) + (setq chunk (buffer-substring-no-properties (- pos 2) pos)) + ;;(message "%S" chunk) + (while (and (< i l) (not auto-expanded)) + (setq pair (elt expanders i) + i (1+ i)) + (when (string= (car pair) chunk) + (setq auto-expanded t) + (delete-char -2) + (insert (cdr pair)) + (when (string-match-p "|" (cdr pair)) + (search-backward "|") + (delete-char 1)) + ) ;when + ) ;while + ) ; let + ) + + ;;-- auto-quoting + (when (and web-mode-enable-auto-quoting + (>= pos 4) + (not (get-text-property pos 'block-side)) + (not auto-closed) + (not auto-paired) + (not auto-expanded) + (get-text-property (- pos 2) 'tag-attr) + ) + (cond + ((and (eq char ?\=) + (not (looking-at-p "[ ]*[\"']"))) + (insert "\"\"") + (backward-char) + (setq auto-quoted t)) + ((and (eq char ?\") + (looking-back "=[ ]*\"") + (not (looking-at-p "[ ]*[\"]"))) + (insert "\"") + (backward-char) + (setq auto-quoted t)) + ((and (eq char ?\') + (looking-back "=[ ]*'") + (not (looking-at-p "[ ]*[']"))) + (insert "'") + (backward-char) + (setq auto-quoted t)) + ((and (eq char ?\") + (eq (char-after) ?\")) + (delete-char 1) + (cond + ((looking-back "=\"\"") + (backward-char)) + ((eq (char-after) ?\s) + (forward-char)) + (t + (insert " ")) + ) ;cond + ) + ) ;cond + ) ;when + + ;;-- + (cond + ((or auto-closed auto-paired auto-expanded auto-quoted) + (when (and web-mode-change-end + (>= (line-end-position) web-mode-change-end)) + (setq web-mode-change-end (line-end-position))) + (list :auto-closed auto-closed + :auto-paired auto-paired + :auto-expanded auto-expanded + :auto-quoted auto-quoted)) + (t + nil) + ) + + )) + +(defun web-mode-on-post-command () + (let (ctx n char) + + ;;(message "this-command=%S (%S)" this-command web-mode-expand-previous-state) + ;;(message "%S: %S %S" this-command web-mode-change-beg web-mode-change-end) + + (when (and web-mode-expand-previous-state + (not (member this-command '(web-mode-mark-and-expand + er/expand-region + mc/mark-next-like-this)))) + (when (eq this-command 'keyboard-quit) + (goto-char web-mode-expand-initial-pos)) + (deactivate-mark) + (when web-mode-expand-initial-scroll + (set-window-start (selected-window) web-mode-expand-initial-scroll) + ) + (setq web-mode-expand-previous-state nil + web-mode-expand-initial-pos nil + web-mode-expand-initial-scroll nil)) + + (when (member this-command '(yank)) + (let ((beg web-mode-change-beg) (end web-mode-change-end)) + (setq web-mode-inhibit-fontification nil) + (when (and web-mode-change-beg web-mode-change-end) + (save-excursion + (font-lock-fontify-region web-mode-change-beg web-mode-change-end)) + (when web-mode-enable-auto-indentation + (indent-region beg end)) + ) ; and + ) + ) + + (when (< (point) 16) + (web-mode-detect-content-type)) + + (when (and web-mode-enable-engine-detection + (or (null web-mode-engine) (string= web-mode-engine "none")) + (< (point) web-mode-chunk-length) + (web-mode-detect-engine)) + (web-mode-on-engine-setted) + (web-mode-buffer-highlight)) + + (when (> (point) 1) + (setq char (char-before))) + + (cond + + ((null char) + ) + + ((and (>= (point) 3) + (member this-command '(self-insert-command)) + (not (member (get-text-property (point) 'part-token) '(comment string)))) + (setq ctx (web-mode-complete))) + + ((and web-mode-enable-auto-opening + (member this-command '(newline electric-newline-and-maybe-indent)) + (or (and (not (eobp)) + (eq (char-after) ?\<) + (eq (get-text-property (point) 'tag-type) 'end) + (looking-back ">\n[ \t]*") + (setq n (length (match-string-no-properties 0))) + (eq (get-text-property (- (point) n) 'tag-type) 'start) + (string= (get-text-property (- (point) n) 'tag-name) + (get-text-property (point) 'tag-name)) + ) + (and (get-text-property (1- (point)) 'block-side) + (string= web-mode-engine "php") + (looking-back "<\\?php[ ]*\n") + (looking-at-p "[ ]*\\?>")))) + (newline-and-indent) + (forward-line -1) + (indent-according-to-mode) + ) + ) ;cond + + (when (and web-mode-enable-auto-indentation + (member this-command '(self-insert-command)) + (or (and ctx + (or (plist-get ctx :auto-closed) + (plist-get ctx :auto-expanded))) + (and (> (point) (point-min)) + (get-text-property (1- (point)) 'tag-end) + (get-text-property (line-beginning-position) 'tag-beg)))) + (indent-according-to-mode) + (when (and web-mode-change-end (> web-mode-change-end (point-max))) + (message "post-command: enlarge web-mode-change-end") + (setq web-mode-change-end (point-max)) + ) + ) ; when auto-indent + + (when web-mode-enable-current-element-highlight + (web-mode-highlight-current-element)) + + (when (and web-mode-enable-current-column-highlight + (not (web-mode-buffer-narrowed-p))) + (web-mode-column-show)) + + ;;(message "post-command (%S) (%S)" web-mode-change-end web-mode-change-end) + + )) + +(defun web-mode-dom-apostrophes-replace () + "Replace char(') with char(’) in the html contents of the buffer." + (interactive) + (save-excursion + (let ((min (point-min)) (max (point-max))) + (when mark-active + (setq min (region-beginning) + max (region-end)) + (deactivate-mark)) + (goto-char min) + (while (web-mode-content-rsf "\\([[:alpha:]]\\)'\\([[:alpha:]]\\)" max) + (replace-match "\\1’\\2")) + ))) + +(defun web-mode-dom-entities-encode () + (save-excursion + (let (regexp ms elt (min (point-min)) (max (point-max))) + (when mark-active + (setq min (region-beginning) + max (region-end)) + (deactivate-mark)) + (goto-char min) + (setq regexp "[") + (dolist (pair web-mode-html-entities) + (setq regexp (concat regexp (char-to-string (cdr pair)))) + ) + (setq regexp (concat regexp "]")) + (while (web-mode-content-rsf regexp max) + (setq elt (match-string-no-properties 0)) + (setq elt (aref elt 0)) + (setq elt (car (rassoc elt web-mode-html-entities))) + (replace-match (concat "&" elt ";")) + ) ;while + ))) + +(defun web-mode-dom-entities-replace () + "Replace html entities (e.g. é é or é become é)" + (interactive) + (save-excursion + (let (ms pair elt (min (point-min)) (max (point-max))) + (when mark-active + (setq min (region-beginning) + max (region-end)) + (deactivate-mark)) + (goto-char min) + (while (web-mode-content-rsf "&\\([#]?[[:alnum:]]\\{2,8\\}\\);" max) + (setq elt nil) + (setq ms (match-string-no-properties 1)) + (cond + ((not (eq (aref ms 0) ?\#)) + (and (setq pair (assoc ms web-mode-html-entities)) + (setq elt (cdr pair)) + (setq elt (char-to-string elt)))) + ((eq (aref ms 1) ?x) + (setq elt (substring ms 2)) + (setq elt (downcase elt)) + (setq elt (string-to-number elt 16)) + (setq elt (char-to-string elt))) + (t + (setq elt (substring ms 1)) + (setq elt (char-to-string (string-to-number elt)))) + ) ;cond + (when elt (replace-match elt)) + ) ;while + ))) + +(defun web-mode-dom-xml-replace () + "Replace &, > and < in html content." + (interactive) + (save-excursion + (let (expr (min (point-min)) (max (point-max))) + (when mark-active + (setq min (region-beginning) + max (region-end)) + (deactivate-mark)) + (goto-char min) + (while (web-mode-content-rsf "[&<>]" max) + (replace-match (cdr (assq (char-before) web-mode-xml-chars)) t t)) + ))) + +(defun web-mode-dom-quotes-replace () + "Replace dumb quotes." + (interactive) + (save-excursion + (let (expr (min (point-min)) (max (point-max))) + (when mark-active + (setq min (region-beginning) + max (region-end)) + (deactivate-mark)) + (goto-char min) + (setq expr (concat (car web-mode-smart-quotes) "\\2" (cdr web-mode-smart-quotes))) + (while (web-mode-content-rsf "\\(\"\\)\\(.\\{1,200\\}\\)\\(\"\\)" max) + (replace-match expr) + ) ;while + ))) + +(defun web-mode-dom-xpath (&optional pos) + "Display html path." + (interactive) + (unless pos (setq pos (point))) + (save-excursion + (goto-char pos) + (let (path) + (while (web-mode-element-parent) + (setq path (cons (get-text-property (point) 'tag-name) path)) + ) + (message "/%s" (mapconcat 'identity path "/")) + ))) + +(defun web-mode-block-ends-with (regexp &optional pos) + (unless pos (setq pos (point))) + (save-excursion + (goto-char pos) + (save-match-data + (if (stringp regexp) + (and (web-mode-block-end) + (progn (backward-char) t) + (web-mode-block-skip-blank-backward) + (progn (forward-char) t) + (looking-back regexp)) + (let ((pair regexp) + (block-beg (web-mode-block-beginning-position pos)) + (block-end (web-mode-block-end-position pos))) + (and (web-mode-block-end) + (web-mode-block-sb (car pair) block-beg) + (not (web-mode-sf (cdr pair) block-end))) + ) ;let + ) ;if + ))) + +(defun web-mode-block-token-starts-with (regexp &optional pos) + (unless pos (setq pos (point))) + (save-excursion + (and (goto-char pos) + (web-mode-block-token-beginning) + (skip-chars-forward "[\"']") + (looking-at regexp)) + )) + +(defun web-mode-block-starts-with (regexp &optional pos) + (unless pos (setq pos (point))) + (save-excursion + (and (web-mode-block-beginning) + (web-mode-block-skip-blank-forward) + (looking-at regexp)) + )) + +(defun web-mode-block-skip-blank-backward (&optional pos) + (unless pos (setq pos (point))) + (let ((continue t)) + (goto-char pos) + (while continue + (if (and (get-text-property (point) 'block-side) + (not (bobp)) + (or (member (char-after) '(?\s ?\n)) + (member (get-text-property (point) 'block-token) + '(delimiter-beg delimiter-end comment)))) + (backward-char) + (setq continue nil)) + ) ;while + (point))) + +(defun web-mode-block-skip-blank-forward (&optional pos) + (unless pos (setq pos (point))) + (let ((continue t)) + (goto-char pos) + (while continue + (if (and (get-text-property (point) 'block-side) + (or (member (char-after) '(?\s ?\n ?\t)) + (member (get-text-property (point) 'block-token) + '(delimiter-beg delimiter-end comment)))) + (forward-char) + (setq continue nil)) + ) ;while +;; (message "pt=%S" (point)) + (point))) + +(defun web-mode-tag-attributes-sort (&optional pos) + "Sort the attributes inside the current html tag." + (interactive) + (unless pos (setq pos (point))) + (save-excursion + (let (attrs (continue t) min max tag-beg tag-end attr attr-name attr-beg attr-end indent indentation sorter ins) + (if (not (member (get-text-property pos 'tag-type) '(start void))) + nil + (setq tag-beg (web-mode-tag-beginning-position pos) + tag-end (web-mode-tag-end-position)) +;; (message "%S %S" tag-beg tag-end) + (goto-char tag-beg) + (while continue + (if (or (not (web-mode-attribute-next)) + (>= (point) tag-end)) + (setq continue nil) + ;;(message "attr=%S" (point)) + (setq attr-beg (web-mode-attribute-beginning-position) + attr-end (1+ (web-mode-attribute-end-position))) + (when (null min) + (setq min attr-beg)) + (setq max attr-end) + (goto-char attr-beg) + (setq attr (buffer-substring-no-properties attr-beg attr-end)) + (if (string-match "^\\([[:alnum:]-]+\\)=" attr) + (setq attr-name (match-string-no-properties 1 attr)) + (setq attr-name attr)) + (setq indent (looking-back "^[ \t]*")) + (setq attrs (append attrs (list (list attr-beg attr-end attr-name attr indent)))) + ) ;if + ) ;while + ) ;if in tag + (when attrs + (setq sorter (function + (lambda (elt1 elt2) + (string< (nth 2 elt1) (nth 2 elt2)) + ))) + (setq attrs (sort attrs sorter)) + (delete-region (1- min) max) + (setq ins "") + (dolist (elt attrs) + (if (and (nth 4 elt) (> (length ins) 1)) + (setq ins (concat ins "\n")) + (setq ins (concat ins " "))) + (setq ins (concat ins (nth 3 elt))) + ) + (goto-char (1- min)) + (insert ins) + (web-mode-tag-beginning) + (setq min (line-beginning-position)) + (web-mode-tag-end) + (setq max (line-end-position)) + (indent-region min max) + ) + ;;(message "attrs=%S" attrs) + ))) + +(defun web-mode-attribute-insert () + "Insert an attribute inside current tag." + (interactive) + (let (attr attr-name attr-value) + (cond + ((not (eq (get-text-property (point) 'tag-type) 'start)) + (message "attribute-insert ** invalid context **")) + ((not (and (setq attr-name (read-from-minibuffer "Attribute name? ")) + (> (length attr-name) 0))) + (message "attribute-insert ** failure **")) + (t + (setq attr (concat " " attr-name)) + (when (setq attr-value (read-from-minibuffer "Attribute value? ")) + (setq attr (concat attr "=\"" attr-value "\""))) + (web-mode-tag-end) + (re-search-backward "/?>") + (insert attr) + ) + ) ;cond + )) + +(defun web-mode-attribute-transpose (&optional pos) + "Transpose the current html attribute." + (interactive) + (unless pos (setq pos (point))) + (let (ret attr-beg attr-end next-beg next-end tag-end) + (when (and (get-text-property pos 'tag-attr) + (setq next-beg (web-mode-attribute-next-position pos)) + (setq next-end (web-mode-attribute-end-position next-beg)) + (setq tag-end (web-mode-tag-end-position pos)) + (> tag-end next-end)) + (setq attr-beg (web-mode-attribute-beginning-position pos) + attr-end (web-mode-attribute-end-position pos)) + ;; (message "%S %S - %S %S" attr-beg attr-end next-beg next-end) + (transpose-regions attr-beg (1+ attr-end) next-beg (1+ next-end)) + ))) + +(defun web-mode-attribute-select (&optional pos) + "Select the current html attribute." + (interactive) + (unless pos (setq pos (point))) + (if (null (get-text-property pos 'tag-attr)) + nil + (goto-char pos) + (web-mode-attribute-beginning) + (set-mark (point)) + (web-mode-attribute-end) + (point) + )) + +(defun web-mode-attribute-kill (&optional arg) + "Kill the current html attribute." + (interactive "p") + (unless arg (setq arg 1)) + (while (>= arg 1) + (setq arg (1- arg)) + (web-mode-attribute-select) + (when mark-active + (let ((beg (region-beginning)) (end (region-end))) + (save-excursion + (goto-char end) + (when (looking-at "[ \n\t]*") + (setq end (+ end (length (match-string-no-properties 0))))) + ) ;save-excursion + (kill-region beg end) + ) ;let + ) ;when + ) ;while + ) + +(defun web-mode-block-close (&optional pos) + "Close the first unclosed control block." + (interactive) + (unless pos (setq pos (point))) + (let ((continue t) + (h (make-hash-table :test 'equal)) ctx ctrl n closing-block) + (save-excursion + (while (and continue (web-mode-block-previous)) + (when (setq ctx (web-mode-block-is-control (point))) + (setq ctrl (car ctx)) + (setq n (gethash ctrl h 0)) + (if (cdr ctx) + (puthash ctrl (1+ n) h) + (puthash ctrl (1- n) h)) + (when (> (gethash ctrl h) 0) + (setq continue nil)) + ) + ) ;while + ) ;save-excursion + (when (and (null continue) + (setq closing-block (web-mode-closing-block ctrl))) + (insert closing-block) + (indent-according-to-mode) + ;; (indent-for-tab-command) + ) + )) + +(defun web-mode-closing-block (type) + (cond + ((string= web-mode-engine "php") (concat "")) + ((string= web-mode-engine "django") (concat "{% end" type " %}")) + ((string= web-mode-engine "ctemplate") (concat "{{/" type "}}")) + ((string= web-mode-engine "blade") + (if (string= type "section") (concat "@show") (concat "@end" type))) + ((string= web-mode-engine "dust") (concat "{/" type "}")) + ((string= web-mode-engine "mako") (concat "% end" type)) + ((string= web-mode-engine "closure") (concat "{/" type "}")) + ((string= web-mode-engine "smarty") (concat "{/" type "}")) + ((string= web-mode-engine "underscore") "<% } %>") + ((string= web-mode-engine "lsp") "<% ) %>") + ((string= web-mode-engine "erb") "<% } %>") + ((string= web-mode-engine "erb") "<% end %>") + ((string= web-mode-engine "go") "{{end}}") + ((string= web-mode-engine "velocity") "#end") + ((string= web-mode-engine "velocity") "#{end}") + ((string= web-mode-engine "template-toolkit") "[% end %]") + ((member web-mode-engine '("asp" "jsp")) + (if (string-match-p "[:.]" type) (concat "") "<% } %>")) + (t nil) + ) ;cond + ) + +;;---- POSITION ---------------------------------------------------------------- + +(defun web-mode-comment-beginning-position (&optional pos) + (unless pos (setq pos (point))) + (car (web-mode-comment-boundaries pos))) + +(defun web-mode-comment-end-position (&optional pos) + (unless pos (setq pos (point))) + (cdr (web-mode-comment-boundaries pos))) + +(defun web-mode-part-opening-paren-position (pos &optional limit) + (save-restriction + (unless limit (setq limit nil)) + (goto-char pos) + (let* ((n -1) + (paren (char-after)) + (pairs '((?\) . "[)(]") + (?\] . "[\]\[]") + (?\} . "[}{]") + (?\> . "[><]"))) + (regexp (cdr (assoc paren pairs))) + (continue (not (null regexp))) + (counter 0)) + (while (and continue (re-search-backward regexp limit t)) + (cond + ((> (setq counter (1+ counter)) 500) + (message "part-opening-paren-position ** warning **") + (setq continue nil)) + ((or (web-mode-is-comment-or-string) + (get-text-property (point) 'block-side)) + ) + ((eq (char-after) paren) + (setq n (1- n))) + (t + (setq n (1+ n)) + (setq continue (not (= n 0)))) + ) + ) ;while + (if (= n 0) (point) nil) + ))) + +(defun web-mode-closing-paren-position (&optional pos limit) + (save-excursion + (unless pos (setq pos (point))) + (unless limit (setq limit nil)) + (goto-char pos) + (let* ((n 0) + (block-side (and (get-text-property pos 'block-side) + (not (string= web-mode-engine "razor")))) + (paren (char-after)) + (pairs '((?\( . "[)(]") + (?\[ . "[\]\[]") + (?\{ . "[}{]") + (?\< . "[><]"))) + (regexp (cdr (assoc paren pairs))) + (continue (not (null regexp)))) + (while (and continue (re-search-forward regexp limit t)) + (cond + ((or (web-mode-is-comment-or-string (1- (point))) + (and block-side (not (get-text-property (point) 'block-side)))) + ;;(message "pt=%S" (point)) + ) + ((eq (char-before) paren) + (setq n (1+ n))) + (t + (setq n (1- n)) + (setq continue (not (= n 0))) + ) + ) ;cond + ) ;while + (if (= n 0) (1- (point)) nil) + ))) + +(defun web-mode-closing-delimiter-position (delimiter &optional pos limit) + (unless pos (setq pos (point))) + (unless limit (setq limit nil)) + (save-excursion + (goto-char pos) + (setq pos nil) + (let ((continue t)) + (while (and continue (re-search-forward delimiter limit t)) + (setq continue nil + pos (1- (point))) + ) ;while + pos))) + +(defun web-mode-tag-match-position (&optional pos) + (unless pos (setq pos (point))) + (save-excursion + (web-mode-tag-match pos) + (if (= pos (point)) nil (point)))) + +(defun web-mode-tag-beginning-position (&optional pos) + (unless pos (setq pos (point))) + (let (beg end depth) + (setq depth (get-text-property pos 'jsx-depth)) + (when (and depth (get-text-property pos 'tag-attr-beg)) + (setq depth (get-text-property (1- pos) 'jsx-depth))) + (cond + ((null pos) + (setq end nil)) + ((get-text-property pos 'tag-beg) + (setq beg pos)) + ((and (> pos 1) (get-text-property (1- pos) 'tag-beg)) + (setq beg (1- pos))) + ((get-text-property pos 'tag-type) + (setq beg (previous-single-property-change pos 'tag-beg)) + (when beg (setq beg (1- beg))) + (cond + ((not (get-text-property beg 'tag-beg)) + (setq beg nil)) + ((and depth (not (eq depth (get-text-property beg 'jsx-depth)))) + (let ((continue (> beg (point-min)))) + (while continue + (setq beg (previous-single-property-change beg 'tag-beg)) + (when beg (setq beg (1- beg))) + (cond + ((null beg) + (setq continue nil)) + ((not (get-text-property beg 'tag-beg)) + (setq continue nil + beg nil)) + ((eq depth (get-text-property beg 'jsx-depth)) + (setq continue nil)) + ) ;cond + ) ;while + ) ;let + ) + ) ;cond + ) + (t + (setq beg nil)) + ) ;cond + beg)) + +(defun web-mode-tag-end-position (&optional pos) + (unless pos (setq pos (point))) + (let (end depth) + (setq depth (get-text-property pos 'jsx-depth)) + (when (and depth (get-text-property pos 'tag-attr-beg)) + (setq depth (get-text-property (1- pos) 'jsx-depth))) + (cond + ((null pos) + (setq end nil)) + ((get-text-property pos 'tag-end) + (setq end pos)) + ((get-text-property pos 'tag-type) + (setq end (next-single-property-change pos 'tag-end)) + (cond + ((not (get-text-property end 'tag-end)) + (setq end nil)) + ((and depth (not (eq depth (get-text-property end 'jsx-depth)))) + (let ((continue (< end (point-max)))) + (while continue + (setq end (1+ end)) + (setq end (next-single-property-change end 'tag-end)) + (cond + ((null end) + (setq continue nil)) + ((not (get-text-property end 'tag-end)) + (setq continue nil + end nil)) + ((eq depth (get-text-property end 'jsx-depth)) + (setq continue nil)) + ) ;cond + ) ;while + ) ;let + ) + ) ;cond + ) + (t + (setq end nil)) + ) ;cond + end)) + +;; TODO: prendre en compte jsx-depth +(defun web-mode-tag-next-position (&optional pos limit) + (unless pos (setq pos (point))) + (unless limit (setq limit (point-max))) + (cond + ((or (>= pos (point-max)) (>= pos limit)) nil) + (t + (when (get-text-property pos 'tag-beg) (setq pos (1+ pos))) + (setq pos (next-single-property-change pos 'tag-beg)) + (if (and pos (<= pos limit)) pos nil)) + )) + +;; TODO: prendre en compte jsx-depth +(defun web-mode-tag-previous-position (&optional pos limit) + (unless pos (setq pos (point))) + (unless limit (setq limit (point-min))) + (cond + ((or (<= pos (point-min)) (<= pos limit)) nil) + (t + (when (get-text-property pos 'tag-beg) (setq pos (1- pos))) + (web-mode-go (previous-single-property-change pos 'tag-beg) -1)) + )) + +;; TODO: prendre en compte jsx-depth +(defun web-mode-attribute-beginning-position (&optional pos) + (unless pos (setq pos (point))) + (cond + ((null (get-text-property pos 'tag-attr)) + nil) + ((get-text-property pos 'tag-attr-beg) + pos) + (t + (setq pos (previous-single-property-change pos 'tag-attr-beg)) + (setq pos (1- pos))) + )) + +;; TODO: retoucher en incluant un param limit et en s'inspirant de +;; web-mode-attribute-next-position +(defun web-mode-attribute-end-position (&optional pos) + (unless pos (setq pos (point))) + (let (end depth) + (setq depth (get-text-property pos 'jsx-depth)) + (cond + ((null pos) + (setq end nil)) + ((get-text-property pos 'tag-attr-end) + (setq end pos)) + ((get-text-property pos 'tag-attr) + (setq end (next-single-property-change pos 'tag-attr-end)) + (cond + ((not (get-text-property end 'tag-attr-end)) + (setq end nil)) + ((and depth + (eq depth (get-text-property end 'jsx-depth)) + (not (eq depth (get-text-property end 'jsx-end)))) + ) + ((and depth (eq (1+ depth) (get-text-property end 'jsx-depth))) + ) + ((and depth (not (eq (1+ depth) (get-text-property end 'jsx-depth)))) + (let ((continue (< end (point-max)))) + (while continue + (setq end (1+ end)) + (setq end (next-single-property-change end 'tag-attr-end)) + (cond + ((null end) + (setq continue nil)) + ((not (get-text-property end 'tag-attr-end)) + (setq continue nil + end nil)) + ((eq (1+ depth) (get-text-property end 'jsx-depth)) + (setq continue nil)) + ) ;cond + ) ;while + ) ;let + ) + ) ;cond + ) + (t + (setq end nil)) + ) ;cond + end)) + +(defun web-mode-attribute-next-position (&optional pos limit) + (unless pos (setq pos (point))) + (unless limit (setq limit (point-max))) + (let (continue depth) + (when (get-text-property pos 'tag-attr-beg) + (setq pos (1+ pos))) + (if (< pos limit) + (setq continue t + depth (get-text-property pos 'jsx-depth)) + (setq continue nil + pos nil)) + (while continue + (setq pos (next-single-property-change pos 'tag-attr-beg)) + (cond + ((null pos) + (setq continue nil)) + ((>= pos limit) + (setq continue nil + pos nil)) + ((null depth) + (setq continue nil)) + ((eq depth (get-text-property pos 'jsx-depth)) + (setq continue nil)) + (t + (setq pos (1+ pos) + continue (< pos limit))) + ) + ) ;while + pos)) + +(defun web-mode-attribute-previous-position (&optional pos limit) + (unless pos (setq pos (point))) + (unless limit (setq limit (point-min))) + (let (continue depth) + (when (get-text-property pos 'tag-attr-beg) + (setq pos (1- pos))) + (if (> pos limit) + (setq continue t + depth (get-text-property pos 'jsx-depth)) + (setq continue nil + pos nil)) + (while continue + (setq pos (previous-single-property-change pos 'tag-attr-beg)) + (cond + ((null pos) + (setq continue nil)) + ((< pos limit) + (setq continue nil + pos nil)) + ((null depth) + (setq continue nil)) + ((eq depth (get-text-property pos 'jsx-depth)) + (setq continue nil)) + (t + (setq pos (1- pos) + continue (> pos limit))) + ) ;cond + ) ;while + pos)) + +;; TODO: prendre en compte jsx-depth +(defun web-mode-element-beginning-position (&optional pos) + (unless pos (setq pos (point))) + (cond + ((null (get-text-property pos 'tag-type)) + (setq pos (web-mode-element-parent-position))) + ((eq (get-text-property pos 'tag-type) 'end) + (setq pos (web-mode-tag-match-position pos)) + (setq pos (if (get-text-property pos 'tag-beg) pos nil))) + ((member (get-text-property pos 'tag-type) '(start void)) + (setq pos (web-mode-tag-beginning-position pos))) + (t + (setq pos nil)) + ) ;cond + pos) + +;; TODO: prendre en compte jsx-depth +(defun web-mode-element-end-position (&optional pos) + (unless pos (setq pos (point))) + (cond + ((null (get-text-property pos 'tag-type)) + (setq pos (web-mode-element-parent-position pos)) + (when pos + (setq pos (web-mode-tag-match-position pos)) + (when pos (setq pos (web-mode-tag-end-position pos))) + ) + ) + ((member (get-text-property pos 'tag-type) '(end void)) + (setq pos (web-mode-tag-end-position pos)) + ) + ((member (get-text-property pos 'tag-type) '(start)) + (setq pos (web-mode-tag-match-position pos)) + (when pos (setq pos (web-mode-tag-end-position pos)))) + (t + (setq pos nil)) + ) ;cond + pos) + +(defun web-mode-element-child-position (&optional pos) + (save-excursion + (let (child close) + (unless pos (setq pos (point))) + (goto-char pos) + (cond + ((eq (get-text-property pos 'tag-type) 'start) + (web-mode-tag-match) + (setq close (point)) + (goto-char pos) + ) + ((eq (get-text-property pos 'tag-type) 'void) + ) + ((eq (get-text-property pos 'tag-type) 'end) + (web-mode-tag-beginning) + (setq close (point)) + (web-mode-tag-match) + ) + ((web-mode-element-parent-position pos) + (setq pos (point)) + (web-mode-tag-match) + (setq close (point)) + (goto-char pos) + ) + ) ;cond + (when (and close + (web-mode-element-next) + (< (point) close)) + (setq child (point)) + ) + child))) + +(defun web-mode-element-parent-position (&optional pos) + (let (n tag-type tag-name (continue t) (tags (make-hash-table :test 'equal))) + (save-excursion + (if pos (goto-char pos)) + (while (and continue (web-mode-tag-previous)) + (setq pos (point) + tag-type (get-text-property pos 'tag-type) + tag-name (get-text-property pos 'tag-name) + n (gethash tag-name tags 0)) + (when (member tag-type '(end start)) + (if (eq tag-type 'end) + (puthash tag-name (1- n) tags) + (puthash tag-name (1+ n) tags) + (when (= n 0) (setq continue nil)) + ) ;if + ) ;when + ) ;while + ) ;save-excursion + (if (null continue) pos nil))) + +(defun web-mode-element-previous-position (&optional pos limit) + (unless pos (setq pos (point))) + (unless limit (setq limit (point-min))) + (save-excursion + (goto-char pos) + (let ((continue (not (bobp))) + (props '(start void comment))) + (while continue + (setq pos (web-mode-tag-previous)) + (cond + ((or (null pos) (< (point) limit)) + (setq continue nil + pos nil)) + ((member (get-text-property (point) 'tag-type) props) + (setq continue nil)) + ) + ) ;while + pos))) + +(defun web-mode-element-next-position (&optional pos limit) + (unless pos (setq pos (point))) + (unless limit (setq limit (point-max))) + (save-excursion + (goto-char pos) + (let ((continue (not (eobp))) + (props '(start void comment))) + (while continue + (setq pos (web-mode-tag-next)) + (cond + ((or (null pos) (> (point) limit)) + (setq continue nil + pos nil)) + ((member (get-text-property (point) 'tag-type) props) + (setq continue nil)) + ) + ) ;while +;; (message "pos=%S" pos) + pos))) + +(defun web-mode-part-end-position (&optional pos) + (unless pos (setq pos (point))) + (cond + ((member web-mode-content-type web-mode-part-content-types) + (setq pos (point-max))) + ((not (get-text-property pos 'part-side)) + (setq pos nil)) + ((= pos (point-max)) + (setq pos nil)) + ((not (get-text-property (1+ pos) 'part-side)) + pos) + (t + (setq pos (next-single-property-change pos 'part-side))) + ) ;cond + pos) + +(defun web-mode-part-beginning-position (&optional pos) + (unless pos (setq pos (point))) + (cond + ((member web-mode-content-type web-mode-part-content-types) + (setq pos (point-min))) + ((not (get-text-property pos 'part-side)) + (setq pos nil)) + ((= pos (point-min)) + (setq pos nil)) + ((not (get-text-property (1- pos) 'part-side)) + pos) + (t + (setq pos (previous-single-property-change pos 'part-side))) + ) ;cond + pos) + +(defun web-mode-part-next-position (&optional pos) + (unless pos (setq pos (point))) + (cond + ((and (= pos (point-min)) (get-text-property pos 'part-side)) + ) + ((not (get-text-property pos 'part-side)) + (setq pos (next-single-property-change pos 'part-side))) + ((and (setq pos (web-mode-part-end-position pos)) (>= pos (point-max))) + (setq pos nil)) + ((and (setq pos (1+ pos)) (not (get-text-property pos 'part-side))) + (setq pos (next-single-property-change pos 'part-side))) + ) ;cond + pos) + +(defun web-mode-block-match-position (&optional pos) + (unless pos (setq pos (point))) + (save-excursion + (web-mode-block-match pos) + (if (= pos (point)) nil (point)))) + +(defun web-mode-block-control-previous-position (type &optional pos) + (unless pos (setq pos (point))) + (let ((continue t) controls) + (while continue + (setq pos (web-mode-block-previous-position pos)) + (cond + ((null pos) + (setq continue nil + pos nil)) + ((and (setq controls (web-mode-block-controls-get pos)) + (eq (car (car controls)) type)) + (setq continue nil)) + ) ;cond + ) ;while + pos)) + +;; (defun web-mode-block-opening-paren-position2 (pos limit) +;; (save-excursion +;; (when (> limit pos) +;; (message "block-opening-paren-position: limit(%S) > pos(%S)" limit pos)) +;; (goto-char pos) +;; (let (c +;; n +;; pt +;; (continue (> pos limit)) +;; (pairs '((")" . "(") +;; ("]" . "[") +;; ("}" . "{"))) +;; (h (make-hash-table :test 'equal)) +;; (regexp "[\]\[)(}{]")) +;; (while (and continue (re-search-backward regexp limit t)) +;; (cond +;; ((web-mode-is-comment-or-string) +;; ) +;; (t +;; (setq c (string (char-after))) +;; (cond +;; ((member c '("(" "{" "[")) +;; (setq n (gethash c h 0)) +;; (if (= n 0) +;; (setq continue nil +;; pt (point)) +;; (puthash c (1+ n) h) +;; )) +;; (t +;; (setq c (cdr (assoc c pairs))) +;; (setq n (gethash c h 0)) +;; (puthash c (1- n) h)) +;; ) ;cond +;; ) ;t +;; ) ;cond +;; ) ;while +;; pt))) + +(defun web-mode-block-opening-paren-position (pos limit) + (save-excursion + (when (> limit pos) + (message "block-opening-paren-position: limit(%S) > pos(%S)" limit pos)) + (goto-char pos) + (let (c + n + pt + (continue (> pos limit)) + (pairs '((?\) . ?\() + (?\] . ?\[) + (?\} . ?\{))) + (h (make-hash-table :test 'equal)) + (regexp "[\]\[)(}{]")) + (while (and continue (re-search-backward regexp limit t)) + (cond + ((web-mode-is-comment-or-string) + ) + (t + (setq c (char-after)) + (cond + ((member c '(?\( ?\{ ?\[)) + (setq n (gethash c h 0)) + (if (= n 0) + (setq continue nil + pt (point)) + (puthash c (1+ n) h) + )) + (t + (setq c (cdr (assoc c pairs))) + (setq n (gethash c h 0)) + (puthash c (1- n) h)) + ) ;cond + ) ;t + ) ;cond + ) ;while + pt))) + +(defun web-mode-block-code-beginning-position (&optional pos) + (unless pos (setq pos (point))) + (when (and (setq pos (web-mode-block-beginning-position pos)) + (eq (get-text-property pos 'block-token) 'delimiter-beg)) + (setq pos (next-single-property-change pos 'block-token))) + pos) + +(defun web-mode-block-beginning-position (&optional pos) + (unless pos (setq pos (point))) + (cond + ((or (and (get-text-property pos 'block-side) (= pos (point-min))) + (get-text-property pos 'block-beg)) + ) + ((and (> pos (point-min)) (get-text-property (1- pos) 'block-beg)) + (setq pos (1- pos))) + ((get-text-property pos 'block-side) + (setq pos (previous-single-property-change pos 'block-beg)) + (setq pos (if (and pos (> pos (point-min))) (1- pos) (point-min)))) + (t + (setq pos nil)) + ) ;cond + pos) + +(defun web-mode-block-string-beginning-position (pos &optional block-beg) + (unless pos (setq pos (point))) + (unless block-beg (setq block-beg (web-mode-block-beginning-position pos))) + (let (char (ori pos) (continue (not (null pos)))) + (while continue + (setq char (char-after pos)) + (cond + ((< pos block-beg) + (setq continue nil + pos block-beg)) + ((and (member (get-text-property pos 'block-token) '(string comment)) + (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token))) + (setq pos (web-mode-block-token-beginning-position pos)) + ) + ((member char '(?\) ?\])) + (setq pos (web-mode-block-opening-paren-position pos block-beg)) + (setq pos (1- pos)) + ) + ((and (> ori pos) (member char '(?\( ?\= ?\[ ?\? ?\: ?\; ?\, ?\`))) + (setq continue nil) + (web-mode-looking-at ".[ \t\n]*" pos) + (setq pos (+ pos (length (match-string-no-properties 0)))) + ) + ((web-mode-looking-back "\\_<\\(return\\|echo\\|include\\|print\\)[ \n\t]*" pos) + (setq continue nil)) + (t + (setq pos (1- pos))) + ) ;cond + ) ;while + ;;(message "pos=%S" pos) + pos)) + +(defun web-mode-block-statement-beginning-position (pos &optional block-beg) + (unless pos (setq pos (point))) + (setq pos (1- pos)) + (unless block-beg (setq block-beg (web-mode-block-beginning-position pos))) + (let (char (continue (not (null pos)))) + (while continue + (setq char (char-after pos)) + (cond + ((< pos block-beg) + (setq continue nil + pos block-beg)) + ((and (member (get-text-property pos 'block-token) '(string comment)) + (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token))) + (setq pos (web-mode-block-token-beginning-position pos))) + ((member char '(?\) ?\] ?\})) + (setq pos (web-mode-block-opening-paren-position pos block-beg)) + (setq pos (1- pos))) + ((member char '(?\( ?\[ ?\{ ?\=)) + (setq continue nil) + (web-mode-looking-at ".[ \t\n]*" pos) + (setq pos (+ pos (length (match-string-no-properties 0))))) + ((web-mode-looking-back "\\_<\\(return\\|echo\\|include\\|print\\)[ \n\t]*" pos) + (setq continue nil)) + (t + (setq pos (1- pos))) + ) ;cond + ) ;while + pos)) + +(defun web-mode-block-args-beginning-position (pos &optional block-beg) + (unless pos (setq pos (point))) + (setq pos (1- pos)) ; #512 + (unless block-beg (setq block-beg (web-mode-block-beginning-position pos))) + (let (char (continue (not (null pos)))) + (while continue + (setq char (char-after pos)) + (cond + ((< pos block-beg) + (message "block-args-beginning-position ** failure **") + (setq continue nil + pos block-beg)) + ((and (member (get-text-property pos 'block-token) '(string comment)) + (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token))) + (setq pos (web-mode-block-token-beginning-position pos))) + ((member char '(?\) ?\] ?\})) + (setq pos (web-mode-block-opening-paren-position pos block-beg)) + (setq pos (1- pos))) + ((member char '(?\( ?\[ ?\{)) + (setq continue nil) + (web-mode-looking-at ".[ \t\n]*" pos) + (setq pos (+ pos (length (match-string-no-properties 0))))) + ((and (string= web-mode-engine "php") + (web-mode-looking-back "\\_<\\(extends\\|implements\\)[ \n\t]*" pos)) + (setq continue nil)) + (t + (setq pos (1- pos))) + ) ;cond + ) ;while + pos)) + +(defun web-mode-block-calls-beginning-position (pos &optional block-beg) + (unless pos (setq pos (point))) + (unless block-beg (setq block-beg (web-mode-block-beginning-position pos))) + (let (char (continue (not (null pos)))) + (while continue + (setq char (char-after pos)) + (cond + ((< pos block-beg) + (message "block-calls-beginning-position ** failure **") + (setq continue nil + pos block-beg)) + ((and (member (get-text-property pos 'block-token) '(string comment)) + (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token))) + (setq pos (web-mode-block-token-beginning-position pos))) + ((member char '(?\) ?\])) + (setq pos (web-mode-block-opening-paren-position pos block-beg)) + (setq pos (1- pos))) + ((member char '(?\( ?\[ ?\{ ?\} ?\= ?\? ?\: ?\; ?\,)) + (setq continue nil) + (web-mode-looking-at ".[ \t\n]*" pos) + (setq pos (+ pos (length (match-string-no-properties 0))))) + ((web-mode-looking-back "\\(return\\|else\\)[ \n\t]*" pos) + (setq ;;pos (point) + continue nil)) + (t + (setq pos (1- pos))) + ) ;cond + ) ;while + pos)) + +(defun web-mode-javascript-string-beginning-position (pos &optional reg-beg) + (unless pos (setq pos (point))) + (let ((char nil) + (blockside (get-text-property pos 'block-side)) + (i 0) + (continue (not (null pos)))) + (unless reg-beg + (if blockside + (setq reg-beg (web-mode-block-beginning-position pos)) + (setq reg-beg (web-mode-part-beginning-position pos))) + ) + (while continue + (setq char (char-after pos)) + (cond + ((> (setq i (1+ i)) 20000) + (message "javascript-string-beginning-position ** warning (%S) **" pos) + (setq continue nil + pos nil)) + ((null pos) + (message "javascript-string-beginning-position ** invalid pos **") + (setq continue nil)) + ((< pos reg-beg) + (message "javascript-string-beginning-position ** failure **") + (setq continue nil + pos reg-beg)) + ((and blockside + (member (get-text-property pos 'block-token) '(string comment)) + (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token))) + (setq pos (web-mode-block-token-beginning-position pos))) + ((and (not blockside) + (member (get-text-property pos 'part-token) '(string comment)) + (eq (get-text-property pos 'part-token) (get-text-property (1- pos) 'part-token))) + (setq pos (web-mode-part-token-beginning-position pos))) + ((and (not blockside) + (get-text-property pos 'block-side)) + (when (setq pos (web-mode-block-beginning-position pos)) + (setq pos (1- pos)))) + ((member char '(?\) ?\] ?\})) + (setq pos (web-mode-part-opening-paren-position pos reg-beg)) + (setq pos (1- pos))) + ((member char '(?\( ?\{ ?\[ ?\= ?\? ?\: ?\; ?\, ?\& ?\|)) + (setq continue nil) + (web-mode-looking-at ".[ \t\n]*" pos) + (setq pos (+ pos (length (match-string-no-properties 0))))) + ((web-mode-looking-back "\\(return\\)[ \n\t]*" pos) + (setq continue nil)) + (t + (setq pos (1- pos))) + ) ;cond + ) ;while + ;;(message "js-statement-beg:%S" pos) + pos)) + +;; TODO: reg-beg : jsx-beg +;; TODO: skipper les expr dont la depth est superieure + +;; NOTE: blockside is useful for ejs +(defun web-mode-javascript-statement-beginning-position (pos &optional reg-beg) + (unless pos (setq pos (point))) + (setq pos (1- pos)) + (let ((char nil) + (blockside (get-text-property pos 'block-side)) + (i 0) + (is-jsx (string= web-mode-content-type "jsx")) + (depth-o nil) (depth-l nil) + (continue (not (null pos)))) + (setq depth-o (get-text-property pos 'jsx-depth)) + (unless reg-beg + (cond + (blockside + (setq reg-beg (web-mode-block-beginning-position pos))) + (is-jsx + (setq reg-beg (web-mode-jsx-depth-beginning-position pos))) + (t + (setq reg-beg (web-mode-part-beginning-position pos))) + ) ;cond + ) ;unless + (while continue + (setq char (char-after pos)) + (cond + ((> (setq i (1+ i)) 20000) + (message "javascript-statement-beginning-position ** warning (%S) **" pos) + (setq continue nil + pos nil)) + ((null pos) + (message "javascript-statement-beginning-position ** invalid pos **") + (setq continue nil)) + ((< pos reg-beg) + (when (not is-jsx) + (message "javascript-statement-beginning-position ** failure **")) + (setq continue nil + pos reg-beg)) + ((and is-jsx + (progn (setq depth-l (get-text-property pos 'jsx-depth))) + (not (eq depth-l depth-o))) + ;;(message "%S > depth-o(%S) depth-l(%S)" pos depth-o depth-l) + (setq pos (previous-single-property-change pos 'jsx-depth)) + (setq pos (1- pos)) + ;;(message "--> %S %S" pos (get-text-property pos 'jsx-depth)) + ) + ((and blockside + (member (get-text-property pos 'block-token) '(string comment)) + (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token))) + (setq pos (web-mode-block-token-beginning-position pos))) + ((and (not blockside) + (member (get-text-property pos 'part-token) '(string comment)) + (eq (get-text-property pos 'part-token) (get-text-property (1- pos) 'part-token))) + (setq pos (web-mode-part-token-beginning-position pos))) + ((and (not blockside) + (get-text-property pos 'block-side)) + (when (setq pos (web-mode-block-beginning-position pos)) + (setq pos (1- pos)))) + ((member char '(?\) ?\] ?\})) + (setq pos (web-mode-part-opening-paren-position pos reg-beg)) + (setq pos (1- pos))) + ((and (eq char ?\=) + (web-mode-looking-back "[<>!=]+" pos reg-beg t)) + (setq pos (- pos 1 (length (match-string-no-properties 0)))) + ;;(setq pos (1- pos)) + ;;(message "%S pos=%S" (match-string-no-properties 0) pos) + ) + ((member char '(?\( ?\{ ?\[ ?\=)) + (setq continue nil) + (web-mode-looking-at ".[ \t\n]*" pos) + (setq pos (+ pos (length (match-string-no-properties 0))))) + ((web-mode-looking-back "\\_<\\(return\\)[ \n\t]*" pos) + (setq continue nil) + (web-mode-looking-at "[ \t\n]*" pos) + (setq pos (+ pos (length (match-string-no-properties 0))))) + (t + (setq pos (1- pos))) + ) ;cond + ) ;while + ;;(message "%S -------" pos) + pos)) + +(defun web-mode-javascript-args-beginning-position (pos &optional reg-beg) + (unless pos (setq pos (point))) + (setq pos (1- pos)) + (let ((char nil) + (blockside (get-text-property pos 'block-side)) + (i 0) + (continue (not (null pos)))) + (unless reg-beg + (if blockside + (setq reg-beg (web-mode-block-beginning-position pos)) + (setq reg-beg (web-mode-part-beginning-position pos))) + ) + (while continue + (setq char (char-after pos)) + (cond + ((> (setq i (1+ i)) 20000) + (message "javascript-args-beginning-position ** warning (%S) **" pos) + (setq continue nil + pos nil)) + ((null pos) + (message "javascript-args-beginning-position ** invalid pos **") + (setq continue nil)) + ((< pos reg-beg) + (message "javascript-args-beginning-position ** failure **") + (setq continue nil + pos reg-beg)) + ((and blockside + (member (get-text-property pos 'block-token) '(string comment)) + (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token))) + (setq pos (web-mode-block-token-beginning-position pos))) + ((and (not blockside) + (member (get-text-property pos 'part-token) '(string comment)) + (eq (get-text-property pos 'part-token) (get-text-property (1- pos) 'part-token))) + (setq pos (web-mode-part-token-beginning-position pos))) + ((and (not blockside) + (get-text-property pos 'block-side)) + (when (setq pos (web-mode-block-beginning-position pos)) + (setq pos (1- pos))) + ) + ((member char '(?\) ?\] ?\})) + (when (setq pos (web-mode-part-opening-paren-position pos reg-beg)) + (setq pos (1- pos)))) + ((member char '(?\( ?\[ ?\{)) +;; (web-mode-looking-at ".[ \t\n]*" pos) + (web-mode-looking-at ".[ ]*" pos) + (setq pos (+ pos (length (match-string-no-properties 0))) + continue nil) +;; (message "=>%S" pos) + ) + ((web-mode-looking-back "\\_<\\(var\\|let\\|return\\|const\\)[ \n\t]+" pos) +;; (web-mode-looking-at "[ \t\n]*" pos) + (web-mode-looking-at "[ \t]*" pos) + (setq pos (+ pos (length (match-string-no-properties 0))) + continue nil)) + (t + (setq pos (1- pos))) + ) ;cond + ) ;while + ;;(message "=%S" pos) + pos)) + +(defun web-mode-javascript-calls-beginning-position (pos &optional reg-beg) + (unless pos (setq pos (point))) + (let ((char nil) + (blockside (get-text-property pos 'block-side)) + (i 0) + (continue (not (null pos)))) + (unless reg-beg + (if blockside + (setq reg-beg (web-mode-block-beginning-position pos)) + (setq reg-beg (web-mode-part-beginning-position pos))) + ) + (while continue + (setq char (char-after pos)) + (cond + ((> (setq i (1+ i)) 20000) + (message "javascript-calls-beginning-position ** warning (%S) **" pos) + (setq continue nil + pos nil)) + ((null pos) + (message "javascript-calls-beginning-position ** invalid pos **") + (setq continue nil)) + ((< pos reg-beg) + ;;(message "pos(%S) reg-beg(%S)" pos reg-beg) + ;;(message "javascript-calls-beginning-position ** failure **") + (setq continue nil + pos reg-beg)) + ((and blockside + (member (get-text-property pos 'block-token) '(string comment)) + (eq (get-text-property pos 'block-token) (get-text-property (1- pos) 'block-token))) + (setq pos (web-mode-block-token-beginning-position pos))) + ((and (not blockside) + (member (get-text-property pos 'part-token) '(string comment)) + (eq (get-text-property pos 'part-token) (get-text-property (1- pos) 'part-token))) + (setq pos (web-mode-part-token-beginning-position pos))) + ((and (not blockside) + (get-text-property pos 'block-side)) + (when (setq pos (web-mode-block-beginning-position pos)) + (setq pos (1- pos)))) + ((member char '(?\) ?\] ?\})) + (when (setq pos (web-mode-part-opening-paren-position pos reg-beg)) + (setq pos (1- pos)))) + ((member char '(?\( ?\{ ?\[ ?\= ?\? ?\: ?\; ?\, ?\& ?\|)) + (setq continue nil) + (web-mode-looking-at ".[ \t\n]*" pos) + (setq pos (+ pos (length (match-string-no-properties 0))))) + ((web-mode-looking-back "\\_<\\(return\\|else\\)[ \n\t]*" pos) + (setq continue nil)) + (t + (setq pos (1- pos))) + ) ;cond + ) ;while + pos)) + +(defun web-mode-part-token-beginning-position (&optional pos) + (unless pos (setq pos (point))) + (cond + ((not (get-text-property pos 'part-token)) + nil) + ((or (= pos (point-min)) + (and (> pos (point-min)) + (not (get-text-property (1- pos) 'part-token)))) + pos) + (t + (setq pos (previous-single-property-change pos 'part-token)) + (if (and pos (> pos (point-min))) pos (point-min))) + )) + +(defun web-mode-part-token-end-position (&optional pos) + (unless pos (setq pos (point))) + (cond + ((not (get-text-property pos 'part-token)) + nil) + ((or (= pos (point-max)) + (not (get-text-property (1+ pos) 'part-token))) + pos) + (t + (1- (next-single-property-change pos 'part-token))) + )) + +(defun web-mode-block-token-beginning-position (&optional pos) + (unless pos (setq pos (point))) + (cond + ((not (get-text-property pos 'block-token)) + nil) + ((or (= pos (point-min)) + (and (> pos (point-min)) + (not (get-text-property (1- pos) 'block-token)))) + pos) + (t + (setq pos (previous-single-property-change pos 'block-token)) + (if (and pos (> pos (point-min))) pos (point-min))) + )) + +(defun web-mode-block-token-end-position (&optional pos) + (unless pos (setq pos (point))) + (cond + ((not (get-text-property pos 'block-token)) + nil) + ((or (= pos (point-max)) + (not (get-text-property (1+ pos) 'block-token))) + pos) + (t + (1- (next-single-property-change pos 'block-token))) + )) + +(defun web-mode-block-code-end-position (&optional pos) + (unless pos (setq pos (point))) + (setq pos (web-mode-block-end-position pos)) + (cond + ((not pos) + nil) + ((and (eq (get-text-property pos 'block-token) 'delimiter-end) + (eq (get-text-property (1- pos) 'block-token) 'delimiter-end)) + (previous-single-property-change pos 'block-token)) + ((= pos (1- (point-max))) ;; TODO: comparer plutot avec line-end-position + (point-max)) + (t + pos) + )) + +(defun web-mode-block-end-position (&optional pos) + (unless pos (setq pos (point))) + (cond + ((get-text-property pos 'block-end) + pos) + ((get-text-property pos 'block-side) + (or (next-single-property-change pos 'block-end) + (point-max))) + (t + nil) + )) + +(defun web-mode-block-previous-position (&optional pos) + (unless pos (setq pos (point))) + (cond + ((= pos (point-min)) + (setq pos nil)) + ((get-text-property pos 'block-side) + (setq pos (web-mode-block-beginning-position pos)) + (cond + ((or (null pos) (= pos (point-min))) + (setq pos nil) + ) + ((and (setq pos (previous-single-property-change pos 'block-beg)) + (> pos (point-min))) + (setq pos (1- pos)) + ) + ) + ) ;block-side + ((get-text-property (1- pos) 'block-side) + (setq pos (web-mode-block-beginning-position (1- pos))) + ) + (t + (setq pos (previous-single-property-change pos 'block-side)) + (cond + ((and (null pos) (get-text-property (point-min) 'block-beg)) + (setq pos (point-min))) + ((and pos (> pos (point-min))) + (setq pos (web-mode-block-beginning-position (1- pos)))) + ) + ) + ) ;conf + pos) + +(defun web-mode-block-next-position (&optional pos limit) + (unless pos (setq pos (point))) + (unless limit (setq limit (point-max))) + (cond + ((and (get-text-property pos 'block-side) + (setq pos (web-mode-block-end-position pos)) + (< pos (point-max)) + (setq pos (1+ pos))) + (unless (get-text-property pos 'block-beg) + (setq pos (next-single-property-change pos 'block-side))) + ) + (t + (setq pos (next-single-property-change pos 'block-side))) + ) ;cond + (if (and pos (<= pos limit)) pos nil)) + +;;---- EXCURSION --------------------------------------------------------------- + +(defun web-mode-backward-sexp (n) + (interactive "p") + (if (< n 0) (web-mode-forward-sexp (- n)) + (let (pos) + (dotimes (_ n) + (skip-chars-backward "[:space:]") + (setq pos (point)) + (cond + ((bobp) nil) + ((get-text-property (1- pos) 'block-end) + (backward-char 1) + (web-mode-block-beginning)) + ((get-text-property (1- pos) 'block-token) + (backward-char 1) + (web-mode-block-token-beginning)) + ((get-text-property (1- pos) 'part-token) + (backward-char 1) + (web-mode-part-token-beginning)) + ((get-text-property (1- pos) 'tag-end) + (backward-char 1) + (web-mode-element-beginning)) + ((get-text-property (1- pos) 'tag-attr) + (backward-char 1) + (web-mode-attribute-beginning)) + ((get-text-property (1- pos) 'tag-type) + (backward-char 1) + (web-mode-tag-beginning)) + (t + (let ((forward-sexp-function nil)) + (backward-sexp)) + ) ;case t + ) ;cond + ) ;dotimes + ))) ;let if defun + +(defun web-mode-forward-sexp (n) + (interactive "p") + (if (< n 0) (web-mode-backward-sexp (- n)) + (let (pos) + (dotimes (_ n) + (skip-chars-forward "[:space:]") + (setq pos (point)) + (cond + ((eobp) nil) + ((get-text-property pos 'block-beg) + (web-mode-block-end)) + ((get-text-property pos 'block-token) + (web-mode-block-token-end)) + ((get-text-property pos 'part-token) + (web-mode-part-token-end)) + ((get-text-property pos 'tag-beg) + (web-mode-element-end)) + ((get-text-property pos 'tag-attr) + (web-mode-attribute-end)) + ((get-text-property pos 'tag-type) + (web-mode-tag-end)) + (t + (let ((forward-sexp-function nil)) + (forward-sexp)) + ) ;case t + ) ;cond + ) ;dotimes + ))) ;let if defun + +(defun web-mode-comment-beginning () + "Fetch current comment beg." + (interactive) + (web-mode-go (web-mode-comment-beginning-position (point)))) + +(defun web-mode-comment-end () + "Fetch current comment end." + (interactive) + (web-mode-go (web-mode-comment-end-position (point)) 1)) + +(defun web-mode-tag-beginning () + "Fetch current html tag beg." + (interactive) + (web-mode-go (web-mode-tag-beginning-position (point)))) + +(defun web-mode-tag-end () + "Fetch current html tag end." + (interactive) + (web-mode-go (web-mode-tag-end-position (point)) 1)) + +(defun web-mode-tag-previous () + "Fetch previous tag." + (interactive) + (web-mode-go (web-mode-tag-previous-position (point)))) + +(defun web-mode-tag-next () + "Fetch next tag. Might be html comment or server tag (e.g. jsp)." + (interactive) + (web-mode-go (web-mode-tag-next-position (point)))) + +(defun web-mode-attribute-beginning () + "Fetch html attribute beginning." + (interactive) + (web-mode-go (web-mode-attribute-beginning-position (point)))) + +(defun web-mode-attribute-end () + "Fetch html attribute end." + (interactive) + (web-mode-go (web-mode-attribute-end-position (point)) 1)) + +(defun web-mode-attribute-next (&optional arg) + "Fetch next attribute." + (interactive "p") + (unless arg (setq arg 1)) + (cond + ((= arg 1) (web-mode-go (web-mode-attribute-next-position (point)))) + ((< arg 1) (web-mode-element-previous (* arg -1))) + (t + (while (>= arg 1) + (setq arg (1- arg)) + (web-mode-go (web-mode-attribute-next-position (point))) + ) + ) + ) + ) + +(defun web-mode-attribute-previous (&optional arg) + "Fetch previous attribute." + (interactive "p") + (unless arg (setq arg 1)) + (unless arg (setq arg 1)) + (cond + ((= arg 1) (web-mode-go (web-mode-attribute-previous-position (point)))) + ((< arg 1) (web-mode-element-next (* arg -1))) + (t + (while (>= arg 1) + (setq arg (1- arg)) + (web-mode-go (web-mode-attribute-previous-position (point))) + ) + ) + ) + ) + +(defun web-mode-element-previous (&optional arg) + "Fetch previous element." + (interactive "p") + (unless arg (setq arg 1)) + (cond + ((= arg 1) (web-mode-go (web-mode-element-previous-position (point)))) + ((< arg 1) (web-mode-element-next (* arg -1))) + (t + (while (>= arg 1) + (setq arg (1- arg)) + (web-mode-go (web-mode-element-previous-position (point))) + ) ;while + ) ;t + ) ;cond + ) + +(defun web-mode-element-next (&optional arg) + "Fetch next element." + (interactive "p") + (unless arg (setq arg 1)) + (cond + ((= arg 1) (web-mode-go (web-mode-element-next-position (point)))) + ((< arg 1) (web-mode-element-previous (* arg -1))) + (t + (while (>= arg 1) + (setq arg (1- arg)) + (web-mode-go (web-mode-element-next-position (point))) + ) ;while + ) ;t + ) ;cond + ) + +(defun web-mode-element-sibling-next () + "Fetch next sibling element." + (interactive) + (let ((pos (point))) + (save-excursion + (cond + ((not (get-text-property pos 'tag-type)) + (if (and (web-mode-element-parent) + (web-mode-tag-match) + (web-mode-element-next)) + (setq pos (point)) + (setq pos nil)) + ) + ((eq (get-text-property pos 'tag-type) 'start) + (if (and (web-mode-tag-match) + (web-mode-element-next)) + (setq pos (point)) + (setq pos nil)) + ) + ((web-mode-element-next) + (setq pos (point))) + (t + (setq pos nil)) + ) ;cond + ) ;save-excursion + (web-mode-go pos))) + +(defun web-mode-element-sibling-previous () + "Fetch previous sibling element." + (interactive) + (let ((pos (point))) + (save-excursion + (cond + ((not (get-text-property pos 'tag-type)) + (if (and (web-mode-element-parent) + (web-mode-tag-previous) + (web-mode-element-beginning)) + (setq pos (point)) + (setq pos nil)) + ) + ((eq (get-text-property pos 'tag-type) 'start) + (if (and (web-mode-tag-beginning) + (web-mode-tag-previous) + (web-mode-element-beginning)) + (setq pos (point)) + (setq pos nil)) + ) + ((and (web-mode-element-beginning) + (web-mode-tag-previous) + (web-mode-element-beginning)) + (setq pos (point))) + (t + (setq pos nil)) + ) ;cond + ) ;save-excursion + (web-mode-go pos))) + +(defun web-mode-element-beginning () + "Move to beginning of element." + (interactive) + (web-mode-go (web-mode-element-beginning-position (point)))) + +(defun web-mode-element-end () + "Move to end of element." + (interactive) + (web-mode-go (web-mode-element-end-position (point)) 1)) + +(defun web-mode-element-parent () + "Fetch parent element." + (interactive) + (web-mode-go (web-mode-element-parent-position (point)))) + +(defun web-mode-element-child () + "Fetch child element." + (interactive) + (web-mode-go (web-mode-element-child-position (point)))) + +(defun web-mode-dom-traverse () + "Traverse html dom tree." + (interactive) + (cond + ((web-mode-element-child) + ) + ((web-mode-element-sibling-next) + ) + ((and (web-mode-element-parent) + (not (web-mode-element-sibling-next))) + (goto-char (point-min))) + (t + (goto-char (point-min))) + ) ;cond + ) + +(defun web-mode-closing-paren (limit) + (let ((pos (web-mode-closing-paren-position (point) limit))) + (if (or (null pos) (> pos limit)) + nil + (goto-char pos) + pos) + )) + +(defun web-mode-part-next () + "Move point to the beginning of the next part." + (interactive) + (web-mode-go (web-mode-part-next-position (point)))) + +(defun web-mode-part-beginning () + "Move point to the beginning of the current part." + (interactive) + (web-mode-go (web-mode-part-beginning-position (point)))) + +(defun web-mode-part-end () + "Move point to the end of the current part." + (interactive) + (web-mode-go (web-mode-part-end-position (point)) 1)) + +(defun web-mode-block-previous () + "Move point to the beginning of the previous block." + (interactive) + (web-mode-go (web-mode-block-previous-position (point)))) + +(defun web-mode-block-next () + "Move point to the beginning of the next block." + (interactive) + (web-mode-go (web-mode-block-next-position (point)))) + +(defun web-mode-block-beginning () + "Move point to the beginning of the current block." + (interactive) + (web-mode-go (web-mode-block-beginning-position (point)))) + +(defun web-mode-block-end () + "Move point to the end of the current block." + (interactive) + (web-mode-go (web-mode-block-end-position (point)) 1)) + +(defun web-mode-block-token-beginning () + (web-mode-go (web-mode-block-token-beginning-position (point)))) + +(defun web-mode-block-token-end () + (web-mode-go (web-mode-block-token-end-position (point)) 1)) + +(defun web-mode-part-token-beginning () + (web-mode-go (web-mode-part-token-beginning-position (point)))) + +(defun web-mode-part-token-end () + (web-mode-go (web-mode-part-token-end-position (point)) 1)) + +(defun web-mode-block-opening-paren (limit) + (web-mode-go (web-mode-block-opening-paren-position (point) limit))) + +(defun web-mode-block-string-beginning (&optional pos block-beg) + (unless pos (setq pos (point))) + (unless block-beg (setq block-beg (web-mode-block-beginning-position pos))) + (web-mode-go (web-mode-block-string-beginning-position pos block-beg))) + +(defun web-mode-block-statement-beginning (&optional pos block-beg) + (unless pos (setq pos (point))) + (unless block-beg (setq block-beg (web-mode-block-beginning-position pos))) + (web-mode-go (web-mode-block-statement-beginning-position pos block-beg))) + +(defun web-mode-block-args-beginning (&optional pos block-beg) + (unless pos (setq pos (point))) + (unless block-beg (setq block-beg (web-mode-block-beginning-position pos))) + (web-mode-go (web-mode-block-args-beginning-position pos block-beg))) + +(defun web-mode-block-calls-beginning (&optional pos block-beg) + (unless pos (setq pos (point))) + (unless block-beg (setq block-beg (web-mode-block-beginning-position pos))) + (web-mode-go (web-mode-block-calls-beginning-position pos block-beg))) + +(defun web-mode-javascript-string-beginning (&optional pos reg-beg) + (unless pos (setq pos (point))) + (unless reg-beg + (if (get-text-property pos 'block-side) + (setq reg-beg (web-mode-block-beginning-position pos)) + (setq reg-beg (web-mode-part-beginning-position pos)))) + (web-mode-go (web-mode-javascript-string-beginning-position pos reg-beg))) + +(defun web-mode-javascript-statement-beginning (&optional pos reg-beg) + (unless pos (setq pos (point))) + (unless reg-beg + (if (get-text-property pos 'block-side) + (setq reg-beg (web-mode-block-beginning-position pos)) + (setq reg-beg (web-mode-part-beginning-position pos)))) + (web-mode-go (web-mode-javascript-statement-beginning-position pos reg-beg))) + +(defun web-mode-javascript-args-beginning (&optional pos reg-beg) + (unless pos (setq pos (point))) + (unless reg-beg + (if (get-text-property pos 'block-side) + (setq reg-beg (web-mode-block-beginning-position pos)) + (setq reg-beg (web-mode-part-beginning-position pos)))) + (web-mode-go (web-mode-javascript-args-beginning-position pos reg-beg))) + +(defun web-mode-javascript-calls-beginning (&optional pos reg-beg) + (unless pos (setq pos (point))) + (unless reg-beg + (if (get-text-property pos 'block-side) + (setq reg-beg (web-mode-block-beginning-position pos)) + (setq reg-beg (web-mode-part-beginning-position pos)))) + (web-mode-go (web-mode-javascript-calls-beginning-position pos reg-beg))) + +(defun web-mode-go (pos &optional offset) + (unless offset (setq offset 0)) + (when pos + (cond + ((and (> offset 0) (<= (+ pos offset) (point-max))) + (setq pos (+ pos offset))) + ((and (< offset 0) (>= (+ pos offset) (point-min))) + (setq pos (+ pos offset))) + ) ;cond + (goto-char pos)) + pos) + +;;---- SEARCH ------------------------------------------------------------------ + +(defun web-mode-rsf-balanced (regexp-open regexp-close &optional limit noerror) + (unless noerror (setq noerror t)) + (let ((continue t) + (level 1) + (pos (point)) + ret + (regexp (concat regexp-open "\\|" regexp-close))) + (while continue + (setq ret (re-search-forward regexp limit noerror)) + (cond + ((null ret) + (setq continue nil) + ) + (t + (if (string-match-p regexp-open (match-string-no-properties 0)) + (setq level (1+ level)) + (setq level (1- level))) + (when (< level 1) + (setq continue nil) + ) + ) ;t + ) ;cond + ) ;while + (when (not (= level 0)) (goto-char pos)) + ret)) + +(defun web-mode-block-sb (expr &optional limit noerror) + (unless limit (setq limit (web-mode-block-beginning-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (search-backward expr limit noerror)) + (when (or (null ret) + (not (get-text-property (point) 'block-token))) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-block-sf (expr &optional limit noerror) + (unless limit (setq limit (web-mode-block-end-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (search-forward expr limit noerror)) + (when (or (null ret) + (not (get-text-property (point) 'block-token))) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-block-rsb (regexp &optional limit noerror) + (unless limit (setq limit (web-mode-block-beginning-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (re-search-backward regexp limit noerror)) + (when (or (null ret) + (not (get-text-property (point) 'block-token))) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-block-rsf (regexp &optional limit noerror) + (unless limit (setq limit (web-mode-block-end-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (re-search-forward regexp limit noerror)) + (when (or (null ret) + (not (get-text-property (point) 'block-token))) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-part-sb (expr &optional limit noerror) + (unless limit (setq limit (web-mode-part-beginning-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (search-backward expr limit noerror)) + (when (or (null ret) + (and (not (get-text-property (point) 'part-token)) + (not (get-text-property (point) 'block-side))) + ) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-part-sf (expr &optional limit noerror) + (unless limit (setq limit (web-mode-part-end-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (search-forward expr limit noerror)) + (when (or (null ret) + (and (not (get-text-property (point) 'part-token)) + (not (get-text-property (point) 'block-side))) + ) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-part-rsb (regexp &optional limit noerror) + (unless limit (setq limit (web-mode-part-beginning-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (re-search-backward regexp limit noerror)) + (when (or (null ret) + (and (not (get-text-property (point) 'part-token)) + (not (get-text-property (point) 'block-side))) + ) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-part-rsf (regexp &optional limit noerror) + (unless limit (setq limit (web-mode-part-end-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (re-search-forward regexp limit t)) + (when (or (null ret) + (and (not (get-text-property (point) 'part-token)) + (not (get-text-property (point) 'block-side))) + ) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-javascript-rsb (regexp &optional limit noerror) + (unless limit (setq limit (web-mode-part-beginning-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (re-search-backward regexp limit noerror)) + (when (or (null ret) + (and (not (get-text-property (point) 'part-token)) + (not (get-text-property (point) 'block-side)) + (not (get-text-property (point) 'jsx-depth))) + ) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-javascript-rsf (regexp &optional limit noerror) + (unless limit (setq limit (web-mode-part-end-position (point)))) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (re-search-forward regexp limit t)) + (when (or (null ret) + (and (not (get-text-property (point) 'part-token)) + (not (get-text-property (point) 'block-side)) + (not (get-text-property (point) 'jsx-depth))) + ) + (setq continue nil) + ) ;when + ) ;while + ret)) + +(defun web-mode-dom-sf (expr &optional limit noerror) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (search-forward expr limit noerror)) + (if (or (null ret) + (not (get-text-property (- (point) (length expr)) 'block-side))) + (setq continue nil)) + ) + ret)) + +(defun web-mode-dom-rsf (regexp &optional limit noerror) + (unless noerror (setq noerror t)) + (let ((continue t) (ret nil)) + (while continue + (setq ret (re-search-forward regexp limit noerror)) + ;; (message "ret=%S point=%S limit=%S i=%S" ret (point) limit 0) + (cond + ((null ret) + (setq continue nil)) + ((or (get-text-property (match-beginning 0) 'block-side) + (get-text-property (match-beginning 0) 'part-token)) + ) + (t + (setq continue nil)) + ) ;cond + ) ;while + ret)) + +(defun web-mode-rsb (regexp &optional limit noerror) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (re-search-backward regexp limit noerror)) + (if (or (null ret) + (not (web-mode-is-comment-or-string))) + (setq continue nil))) + ret)) + +(defun web-mode-rsf (regexp &optional limit noerror) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (re-search-forward regexp limit noerror)) + (if (or (null ret) + (not (web-mode-is-comment-or-string))) + (setq continue nil)) + ) + ret)) + +(defun web-mode-sb (expr &optional limit noerror) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (search-backward expr limit noerror)) + (if (or (null ret) + (not (web-mode-is-comment-or-string))) + (setq continue nil))) + ret)) + +(defun web-mode-sf (expr &optional limit noerror) + (unless noerror (setq noerror t)) + (let ((continue t) ret) + (while continue + (setq ret (search-forward expr limit noerror)) + (if (or (null ret) + (not (web-mode-is-comment-or-string))) + (setq continue nil))) + ret)) + +(defun web-mode-content-rsf (regexp &optional limit noerror) + (unless noerror (setq noerror t)) + (let ((continue t) ret beg end) + (while continue + (setq ret (re-search-forward regexp limit noerror) + beg (if (null ret) (point) (match-beginning 0)) + end (if (null ret) (point) (1- (match-end 0)))) + (if (or (null ret) + (and (web-mode-is-content beg) + (web-mode-is-content end))) + (setq continue nil))) + ret)) + +;;---- ADVICES ----------------------------------------------------------------- + +(defadvice ac-start (before web-mode-set-up-ac-sources activate) + "Set `ac-sources' based on current language before running auto-complete." + (when (equal major-mode 'web-mode) + ;; set ignore each time to nil. User has to implement a hook to change it + ;; for each completion + (setq web-mode-ignore-ac-start-advice nil) + (run-hooks 'web-mode-before-auto-complete-hooks) + (unless web-mode-ignore-ac-start-advice + (when web-mode-ac-sources-alist + (let ((new-web-mode-ac-sources + (assoc (web-mode-language-at-pos) + web-mode-ac-sources-alist))) + (setq ac-sources (cdr new-web-mode-ac-sources))))))) + +;;---- MINOR MODE ADDONS ------------------------------------------------------- + +(defun web-mode-yasnippet-exit-hook () + "Yasnippet exit hook" + (when (and (boundp 'yas-snippet-beg) (boundp 'yas-snippet-end)) + (indent-region yas-snippet-beg yas-snippet-end))) + +(defun web-mode-imenu-index () + (interactive) + "Returns imenu items." + (let (toc-index + line) + (save-excursion + (goto-char (point-min)) + (while (not (eobp)) + (setq line (buffer-substring-no-properties + (line-beginning-position) + (line-end-position))) + (let (found + (i 0) + item + regexp + type + type-idx + content + content-idx + content-regexp + close-tag-regexp + concat-str + jumpto + str) + (while (and (not found ) (< i (length web-mode-imenu-regexp-list))) + (setq item (nth i web-mode-imenu-regexp-list)) + (setq regexp (nth 0 item)) + (setq type-idx (nth 1 item)) + (setq content-idx (nth 2 item)) + (setq concat-str (nth 3 item)) + (when (not (numberp content-idx)) + (setq content-regexp (nth 2 item) + close-tag-regexp (nth 4 item) + content-idx nil)) + + (when (string-match regexp line) + + (cond + (content-idx + (setq type (match-string type-idx line)) + (setq content (match-string content-idx line)) + (setq str (concat type concat-str content)) + (setq jumpto (line-beginning-position))) + (t + (let (limit) + (setq type (match-string type-idx line)) + (goto-char (line-beginning-position)) + (save-excursion + (setq limit (re-search-forward close-tag-regexp (point-max) t))) + + (when limit + (when (re-search-forward content-regexp limit t) + (setq content (match-string 1)) + (setq str (concat type concat-str content)) + (setq jumpto (line-beginning-position)) + ) + ))) + ) + (when str (setq toc-index + (cons (cons str jumpto) + toc-index) + ) + (setq found t)) + ) + (setq i (1+ i)))) + (forward-line) + (goto-char (line-end-position)) ;; make sure we are at eobp + )) + (nreverse toc-index))) + +;;---- UNIT TESTING ------------------------------------------------------------ + +(defun web-mode-test () + "Executes web-mode unit tests. See `web-mode-tests-directory'." + (interactive) + (let (files ret regexp) + (setq regexp "^[[:alnum:]][[:alnum:]._]+\\'") + (setq files (directory-files web-mode-tests-directory t regexp)) + (dolist (file files) + (cond + ((eq (string-to-char (file-name-nondirectory file)) ?\_) + (delete-file file)) + (t + (setq ret (web-mode-test-process file))) + ) ;cond + ) ;dolist + )) + +(defun web-mode-test-process (file) + (with-temp-buffer + (let (out sig1 sig2 success err) + (setq-default indent-tabs-mode nil) + (if (string-match-p "sql" file) + (setq web-mode-enable-sql-detection t) + (setq web-mode-enable-sql-detection nil)) + (insert-file-contents file) + (set-visited-file-name file) + (web-mode) + (setq sig1 (md5 (current-buffer))) + (delete-horizontal-space) + (while (not (eobp)) + (forward-line) + (delete-horizontal-space) + (end-of-line)) + (web-mode-buffer-indent) + (setq sig2 (md5 (current-buffer))) + (setq success (string= sig1 sig2)) + (setq out (concat (if success "ok" "ko") " : " (file-name-nondirectory file))) + (message out) + (setq err (concat (file-name-directory file) "_err." (file-name-nondirectory file))) + (if success + (when (file-readable-p err) + (delete-file err)) + (write-file err) + (message "[%s]" (buffer-string)) + ) ;if + out))) + +;;---- MISC -------------------------------------------------------------------- + +(defun web-mode-set-engine (engine) + "Set the engine for the current buffer." + (interactive + (list (completing-read + "Engine: " + (let (engines) + (dolist (elt web-mode-engines) + (setq engines (append engines (list (car elt))))) + engines)))) + (setq web-mode-content-type "html" + web-mode-engine (web-mode-engine-canonical-name engine) + web-mode-minor-engine engine) + (web-mode-on-engine-setted) + (web-mode-buffer-highlight)) + +(defun web-mode-set-content-type (content-type) + "Set the content-type for the current buffer" + (interactive (list (completing-read "Content-type: " web-mode-part-content-types))) + (setq web-mode-content-type content-type) + (when (called-interactively-p 'any) + ) + (web-mode-buffer-highlight)) + +(defun web-mode-on-engine-setted () + (let (elt elts engines) + + (when (string= web-mode-engine "razor") (setq web-mode-enable-block-face t)) + (setq web-mode-engine-attr-regexp (cdr (assoc web-mode-engine web-mode-engine-attr-regexps))) + (setq web-mode-engine-token-regexp (cdr (assoc web-mode-engine web-mode-engine-token-regexps))) + + ;;(message "%S %S" web-mode-engine-attr-regexp web-mode-engine) + + (when (null web-mode-minor-engine) + (setq web-mode-minor-engine "none")) + + (setq elt (assoc web-mode-engine web-mode-engine-open-delimiter-regexps)) + (if elt + (setq web-mode-block-regexp (cdr elt)) + (setq web-mode-engine "none")) + + (unless (boundp 'web-mode-extra-auto-pairs) + (setq web-mode-extra-auto-pairs nil)) + + (setq web-mode-auto-pairs + (append + (cdr (assoc web-mode-engine web-mode-engines-auto-pairs)) + (cdr (assoc nil web-mode-engines-auto-pairs)) + (cdr (assoc web-mode-engine web-mode-extra-auto-pairs)) + (cdr (assoc nil web-mode-extra-auto-pairs)))) + + (unless (boundp 'web-mode-extra-snippets) + (setq web-mode-extra-snippets nil)) + + (setq elts + (append + (cdr (assoc web-mode-engine web-mode-extra-snippets)) + (cdr (assoc nil web-mode-extra-snippets)) + (cdr (assoc web-mode-engine web-mode-engines-snippets)) + (cdr (assoc nil web-mode-engines-snippets)))) + + (dolist (elt elts) + (unless (assoc (car elt) web-mode-snippets) + (setq web-mode-snippets (append (list elt) web-mode-snippets))) + ) + + (setq web-mode-engine-font-lock-keywords + (symbol-value (cdr (assoc web-mode-engine web-mode-engines-font-lock-keywords)))) + + (when (and (string= web-mode-minor-engine "jinja") + (not (member "endtrans" web-mode-django-control-blocks))) + (add-to-list 'web-mode-django-control-blocks "endtrans") + (setq web-mode-django-control-blocks-regexp + (regexp-opt web-mode-django-control-blocks t)) + ) + +;; (message "%S" (symbol-value (cdr (assoc web-mode-engine web-mode-engines-font-lock-keywords)))) + + )) + +(defun web-mode-detect-engine () + (save-excursion + (goto-char (point-min)) + (when (re-search-forward "-\\*- engine:[ ]*\\([[:alnum:]-]+\\)[ ]*-\\*-" web-mode-chunk-length t) + (setq web-mode-minor-engine (match-string-no-properties 1)) + (setq web-mode-engine (web-mode-engine-canonical-name web-mode-minor-engine))) + web-mode-minor-engine)) + +(defun web-mode-guess-engine-and-content-type () + (let (buff-name elt found) + + (setq buff-name (buffer-file-name)) + (unless buff-name (setq buff-name (buffer-name))) + (setq web-mode-is-scratch (string= buff-name "*scratch*")) + (setq web-mode-content-type nil) + + (when (boundp 'web-mode-content-types-alist) + (setq found nil) + (dolist (elt web-mode-content-types-alist) + (when (and (not found) (string-match-p (cdr elt) buff-name)) + (setq web-mode-content-type (car elt) + found t)) + ) ;dolist + ) ;when + + (unless web-mode-content-type + (setq found nil) + (dolist (elt web-mode-content-types) + (when (and (not found) (string-match-p (cdr elt) buff-name)) + (setq web-mode-content-type (car elt) + found t)) + ) ;dolist + ) ;unless + + (when (boundp 'web-mode-engines-alist) + (setq found nil) + (dolist (elt web-mode-engines-alist) + (cond + ((stringp (cdr elt)) + (when (string-match-p (cdr elt) buff-name) + (setq web-mode-engine (car elt)))) + ((functionp (cdr elt)) + (when (funcall (cdr elt)) + (setq web-mode-engine (car elt)))) + ) ;cond + ) ;dolist + ) ;when + + (unless web-mode-engine + (setq found nil) + (dolist (elt web-mode-engine-file-regexps) + ;;(message "%S %S" (cdr elt) buff-name) + (when (and (not found) (string-match-p (cdr elt) buff-name)) + (setq web-mode-engine (car elt) + found t)) + ) + ) + + (when (and (or (null web-mode-engine) (string= web-mode-engine "none")) + (string-match-p "php" (buffer-substring-no-properties + (line-beginning-position) + (line-end-position)))) + (setq web-mode-engine "php")) + + (when (and (string= web-mode-content-type "javascript") + (string-match-p "@jsx" + (buffer-substring-no-properties + (point-min) + (if (< (point-max) web-mode-chunk-length) + (point-max) + web-mode-chunk-length) + ))) + (setq web-mode-content-type "jsx")) + + (when web-mode-engine + (setq web-mode-minor-engine web-mode-engine + web-mode-engine (web-mode-engine-canonical-name web-mode-engine)) + ) + + (when (and (or (null web-mode-engine) + (string= web-mode-engine "none")) + web-mode-enable-engine-detection) + (web-mode-detect-engine)) + + (web-mode-on-engine-setted) + + )) + +(defun web-mode-engine-canonical-name (name) + (let (engine) + (cond + ((null name) + nil) + ((assoc name web-mode-engines) + name) + (t + (dolist (elt web-mode-engines) + (when (and (null engine) (member name (cdr elt))) + (setq engine (car elt))) + ) ;dolist + engine) + ))) + +(defun web-mode-on-after-save () + (when web-mode-is-scratch + (web-mode-guess-engine-and-content-type) + (web-mode-buffer-highlight)) + nil) + +(defun web-mode-on-exit () + (web-mode-with-silent-modifications + (put-text-property (point-min) (point-max) 'invisible nil) + (remove-overlays) + (remove-hook 'change-major-mode-hook 'web-mode-on-exit t) + )) + +(defun web-mode-reload () + "Reload web-mode." + (interactive) + (web-mode-with-silent-modifications + (put-text-property (point-min) (point-max) 'invisible nil) + (remove-overlays) + (setq font-lock-unfontify-region-function 'font-lock-default-unfontify-region) + (load "web-mode.el") + (setq web-mode-change-beg nil + web-mode-change-end nil) + (web-mode) + )) + +(defun web-mode-trace (msg) + (let (sub) + ;; (when (null web-mode-time) (setq web-mode-time (current-time))) + (setq sub (time-subtract (current-time) web-mode-time)) + (when nil + (save-excursion + (let ((n 0)) + (goto-char (point-min)) + (while (web-mode-tag-next) + (setq n (1+ n)) + ) + (message "%S tags found" n) + ))) + (message "%18s: time elapsed = %Ss %9Sµs" msg (nth 1 sub) (nth 2 sub)) + )) + +(defun web-mode-reveal () + "Display text properties at point." + (interactive) + (let (symbols out) + (setq out (format + "[point=%S engine=%S minor=%S content-type=%S language-at-pos=%S]\n" + (point) + web-mode-engine + web-mode-minor-engine + web-mode-content-type + (web-mode-language-at-pos (point)))) + (setq symbols (append web-mode-scan-properties '(font-lock-face face))) + (dolist (symbol symbols) + (when symbol + (setq out (concat out (format "%s(%S) " (symbol-name symbol) (get-text-property (point) symbol))))) + ) + (message "%s\n" out) + ;;(message "syntax-class=%S" (syntax-class (syntax-after (point)))) + (message nil))) + +(defun web-mode-debug () + "Display informations useful for debugging." + (interactive) + (let ((modes nil) + (customs '(web-mode-enable-current-column-highlight web-mode-enable-current-element-highlight indent-tabs-mode)) + (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))) + (message "\n") + (message "--- WEB-MODE DEBUG BEG ---") + (message "versions: emacs(%S.%S) web-mode(%S)" + emacs-major-version emacs-minor-version web-mode-version) + (message "vars: engine(%S) minor(%S) content-type(%S) file(%S)" + web-mode-engine + web-mode-minor-engine + web-mode-content-type + (or (buffer-file-name) (buffer-name))) + (message "system: window(%S) config(%S)" window-system system-configuration) + (message "colors: fg(%S) bg(%S) " + (cdr (assoc 'foreground-color default-frame-alist)) + (cdr (assoc 'background-color default-frame-alist))) + (mapc (lambda (mode) + (condition-case nil + (if (and (symbolp mode) (symbol-value mode) (not (member mode ignore))) + (add-to-list 'modes mode)) + (error nil)) + ) ;lambda + minor-mode-list) + (message "minor modes: %S" modes) + (message "vars:") + (dolist (custom customs) + (message (format "%s=%S " (symbol-name custom) (symbol-value custom)))) + (message "--- WEB-MODE DEBUG END ---") + (switch-to-buffer "*Messages*") + (goto-char (point-max)) + (recenter) + )) + +(provide 'web-mode) + +;;; web-mode.el ends here + +;; Local Variables: +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: diff --git a/site-elisp/aweshell b/site-elisp/aweshell new file mode 160000 index 0000000..7d6afd1 --- /dev/null +++ b/site-elisp/aweshell @@ -0,0 +1 @@ +Subproject commit 7d6afd1959194956495252abeef0c1cd39ebeee2 diff --git a/site-elisp/awesome-pair b/site-elisp/awesome-pair new file mode 160000 index 0000000..4aa25e1 --- /dev/null +++ b/site-elisp/awesome-pair @@ -0,0 +1 @@ +Subproject commit 4aa25e10b0a8bbb31f199cce41f70d35d18209bd diff --git a/site-elisp/color-rg b/site-elisp/color-rg new file mode 160000 index 0000000..9aa81f6 --- /dev/null +++ b/site-elisp/color-rg @@ -0,0 +1 @@ +Subproject commit 9aa81f6c711870ae1a7c6182d911671512a48387 diff --git a/site-elisp/delete-block b/site-elisp/delete-block new file mode 160000 index 0000000..50e1df3 --- /dev/null +++ b/site-elisp/delete-block @@ -0,0 +1 @@ +Subproject commit 50e1df3e273ffa049525726fb72818e859ecc9cf diff --git a/site-elisp/emacs-application-framework b/site-elisp/emacs-application-framework new file mode 160000 index 0000000..40d6e68 --- /dev/null +++ b/site-elisp/emacs-application-framework @@ -0,0 +1 @@ +Subproject commit 40d6e68085f1f2b6fc3231644e8b5a6c346982c7 diff --git a/site-elisp/epaint b/site-elisp/epaint new file mode 160000 index 0000000..8b40f92 --- /dev/null +++ b/site-elisp/epaint @@ -0,0 +1 @@ +Subproject commit 8b40f927cbb3633d41b9bb4d40d072e522fa3739 diff --git a/site-elisp/grep-dired b/site-elisp/grep-dired new file mode 160000 index 0000000..1f53289 --- /dev/null +++ b/site-elisp/grep-dired @@ -0,0 +1 @@ +Subproject commit 1f532893f03728406dcf5842e49c019f6186623e diff --git a/site-elisp/header2 b/site-elisp/header2 new file mode 160000 index 0000000..e41bb4f --- /dev/null +++ b/site-elisp/header2 @@ -0,0 +1 @@ +Subproject commit e41bb4fe0e003130e8c7af199ef4546a2cf57856 diff --git a/site-elisp/instant-rename-tag b/site-elisp/instant-rename-tag new file mode 160000 index 0000000..5909263 --- /dev/null +++ b/site-elisp/instant-rename-tag @@ -0,0 +1 @@ +Subproject commit 5909263fa697d2ca44d8fd8b2741315af02d9d9f diff --git a/site-elisp/leetcode b/site-elisp/leetcode new file mode 160000 index 0000000..28b78c4 --- /dev/null +++ b/site-elisp/leetcode @@ -0,0 +1 @@ +Subproject commit 28b78c45c86570cb1e3538f275eb4de1cf28cd04 diff --git a/site-elisp/multi-term b/site-elisp/multi-term new file mode 160000 index 0000000..8deb0f2 --- /dev/null +++ b/site-elisp/multi-term @@ -0,0 +1 @@ +Subproject commit 8deb0f2252399cca2426eb3cc3e9646c5de726b3 diff --git a/site-elisp/snails b/site-elisp/snails new file mode 160000 index 0000000..44f77cc --- /dev/null +++ b/site-elisp/snails @@ -0,0 +1 @@ +Subproject commit 44f77cc35f75e623a6e2a419629a16ec9b9c3fbf diff --git a/snippets/c++-mode/acc b/snippets/c++-mode/acc new file mode 100644 index 0000000..f234a4c --- /dev/null +++ b/snippets/c++-mode/acc @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: accumulate +# key: acc +# -- +std::accumulate(${1:v}.begin(), $1.end(), ${2:0}); diff --git a/snippets/c++-mode/accl b/snippets/c++-mode/accl new file mode 100644 index 0000000..c712dc1 --- /dev/null +++ b/snippets/c++-mode/accl @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# name: accumulate_lambda +# key: accl +# -- +auto acc = [${3:}] (${4:auto} const& ${5:r}, ${6:auto} const& ${7:v}) { + $0 +}; +std::accumulate(${1:v}.begin(), $1.end(), ${2:0}, acc); diff --git a/snippets/c++-mode/cls b/snippets/c++-mode/cls new file mode 100644 index 0000000..52178d7 --- /dev/null +++ b/snippets/c++-mode/cls @@ -0,0 +1,10 @@ +# -*- mode: snippet -*- +# name: class +# key: cls +# -- +class ${1:Name} { +public: + ${1:$(yas/substr yas-text "[^: ]*")}(); + ${2:virtual ~${1:$(yas/substr yas-text "[^: ]*")}();} +}; +$0 \ No newline at end of file diff --git a/snippets/c++-mode/dcast b/snippets/c++-mode/dcast new file mode 100644 index 0000000..7a53c6c --- /dev/null +++ b/snippets/c++-mode/dcast @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: dynamic cast +# key: dcast +# -- +dynamic_cast<${1:type}>(${2:v}) diff --git a/snippets/c++-mode/dpcast b/snippets/c++-mode/dpcast new file mode 100644 index 0000000..384f202 --- /dev/null +++ b/snippets/c++-mode/dpcast @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: dynamic pointer cast +# key: dpcast +# -- +std::dynamic_pointer_cast<${1:type}>(${2:v}) diff --git a/snippets/c++-mode/forc b/snippets/c++-mode/forc new file mode 100644 index 0000000..f598b12 --- /dev/null +++ b/snippets/c++-mode/forc @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# name: for_c +# key: forc +# -- +for (${1:auto} ${2:i}: ${3:v}) { + $0 +} \ No newline at end of file diff --git a/snippets/c++-mode/scast b/snippets/c++-mode/scast new file mode 100644 index 0000000..2b042b3 --- /dev/null +++ b/snippets/c++-mode/scast @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: static cast +# key: scast +# -- +static_cast<${1:type}>(${2:v}) diff --git a/snippets/c++-mode/sct b/snippets/c++-mode/sct new file mode 100644 index 0000000..648db90 --- /dev/null +++ b/snippets/c++-mode/sct @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# name: struct +# key: sct +# -- +struct ${1:Name} { + ${1:$(yas/substr yas-text "[^: ]*")}(); + ${2:virtual ~${1:$(yas/substr yas-text "[^: ]*")}();} +}; +$0 \ No newline at end of file diff --git a/snippets/c++-mode/spcast b/snippets/c++-mode/spcast new file mode 100644 index 0000000..0f9f38d --- /dev/null +++ b/snippets/c++-mode/spcast @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: static pointer cast +# key: spcast +# -- +std::static_pointer_cast<${1:type}>(${2:v}) diff --git a/snippets/c++-mode/sptr b/snippets/c++-mode/sptr new file mode 100644 index 0000000..00b7b73 --- /dev/null +++ b/snippets/c++-mode/sptr @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: shared_ptr +# key: sptr +# -- +std::shared_ptr<${1:type}> ${2:name}$0 diff --git a/snippets/c++-mode/todo b/snippets/c++-mode/todo new file mode 100644 index 0000000..ddd0f89 --- /dev/null +++ b/snippets/c++-mode/todo @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: todo_full +# key: todo +# -- +`(yas-with-comment "TODO: ")` \ No newline at end of file diff --git a/snippets/c++-mode/uptr b/snippets/c++-mode/uptr new file mode 100644 index 0000000..eb31b9c --- /dev/null +++ b/snippets/c++-mode/uptr @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: unique_ptr +# key: uptr +# -- +std::unique_ptr<${1:type}> ${2:name}$0 diff --git a/snippets/c++-mode/wptr b/snippets/c++-mode/wptr new file mode 100644 index 0000000..dac1513 --- /dev/null +++ b/snippets/c++-mode/wptr @@ -0,0 +1,5 @@ +# -*- mode: snippet -*- +# name: weak_ptr +# key: wptr +# -- +std::weak_ptr<${1:type}> ${2:name}$0 diff --git a/snippets/latex-mode/.yas-ignore-filenames-as-triggers b/snippets/latex-mode/.yas-ignore-filenames-as-triggers new file mode 100644 index 0000000..e69de29 diff --git a/snippets/latex-mode/.yas-make-groups b/snippets/latex-mode/.yas-make-groups new file mode 100644 index 0000000..e69de29 diff --git a/snippets/latex-mode/.yas-parents b/snippets/latex-mode/.yas-parents new file mode 100644 index 0000000..eed5b44 --- /dev/null +++ b/snippets/latex-mode/.yas-parents @@ -0,0 +1 @@ +text-mode diff --git a/snippets/latex-mode/abstract.yasnippet b/snippets/latex-mode/abstract.yasnippet new file mode 100644 index 0000000..bf05994 --- /dev/null +++ b/snippets/latex-mode/abstract.yasnippet @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# contributor : Mads D. Kristensen +# key : abs +# group: sections +# name : \abstract +# -- +\begin{abstract} +$0 +\end{abstract} \ No newline at end of file diff --git a/snippets/latex-mode/align.yasnippet b/snippets/latex-mode/align.yasnippet new file mode 100644 index 0000000..4fd7beb --- /dev/null +++ b/snippets/latex-mode/align.yasnippet @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# contributor : Rasmus Borgsmidt +# key : align +# group: environments +# name : \begin{align} ... \end{align} +# -- +\begin{align} + $0 +\end{align} \ No newline at end of file diff --git a/snippets/latex-mode/alignstar.yasnippet b/snippets/latex-mode/alignstar.yasnippet new file mode 100644 index 0000000..538a2dd --- /dev/null +++ b/snippets/latex-mode/alignstar.yasnippet @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# contributor : Rasmus Borgsmidt +# key : align* +# group: environments +# name : \begin{align*} ... \end{align*} +# -- +\begin{align*} + $0 +\end{align*} \ No newline at end of file diff --git a/snippets/latex-mode/array.yasnippet b/snippets/latex-mode/array.yasnippet new file mode 100644 index 0000000..aa67ae9 --- /dev/null +++ b/snippets/latex-mode/array.yasnippet @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# contributor : Peter Urbak +# key : arr +# group: environments +# name : \begin{array} ... \end{array} +# -- +\begin{array}{$1} + $0 +\end{array} diff --git a/snippets/latex-mode/article.yasnippet b/snippets/latex-mode/article.yasnippet new file mode 100644 index 0000000..a9e5203 --- /dev/null +++ b/snippets/latex-mode/article.yasnippet @@ -0,0 +1,28 @@ +# -*- mode: snippet -*- +# contributor: Mads D. Kristensen +# contributor : Song Qiang +# key: article +# group: skeleton +# name: \documentclass{article} ... +# -- +\documentclass[11pt]{article} + +\usepackage{graphicx,amsmath,amssymb,subfigure,url,xspace} +\newcommand{\eg}{e.g.,\xspace} +\newcommand{\bigeg}{E.g.,\xspace} +\newcommand{\etal}{\textit{et~al.\xspace}} +\newcommand{\etc}{etc.\@\xspace} +\newcommand{\ie}{i.e.,\xspace} +\newcommand{\bigie}{I.e.,\xspace} + +\title{${1:title}} +\author{${2:Author Name}} + +\begin{document} +\maketitle + + +\bibliographystyle{${3:plain}} +\bibliography{${4:literature.bib}} + +\end{document} diff --git a/snippets/latex-mode/beamer.yasnippet b/snippets/latex-mode/beamer.yasnippet new file mode 100644 index 0000000..4c4c7c3 --- /dev/null +++ b/snippets/latex-mode/beamer.yasnippet @@ -0,0 +1,37 @@ +# -*- mode: snippet -*- +# contributor: Claudio Marforio +# key: beamer +# group: skeleton +# name: \documentclass{beamer} ... +# -- +\documentclass[xcolor=dvipsnames]{beamer} + +\usepackage{graphicx,subfigure,url} + +% example themes +\usetheme{Frankfurt} +\usecolortheme{seahorse} +\usecolortheme{rose} + +% put page numbers +% \setbeamertemplate{footline}[frame number]{} +% remove navigation symbols +% \setbeamertemplate{navigation symbols}{} + +\title{${1:Presentation Title}} +\author{${2:Author Name}} + +\begin{document} + +\frame[plain]{\titlepage} + +\begin{frame}[plain]{Outline} + \tableofcontents +\end{frame} + +\section{${3:Example Section}} +\begin{frame}{${4:Frame Title}} + +\end{frame} + +\end{document} diff --git a/snippets/latex-mode/begin.yasnippet b/snippets/latex-mode/begin.yasnippet new file mode 100644 index 0000000..e18b643 --- /dev/null +++ b/snippets/latex-mode/begin.yasnippet @@ -0,0 +1,10 @@ +# -*- mode: snippet -*- +# contributor: Mads D. Kristensen +# contributor : Bjorn Reese +# key: begin +# group: environments +# name: \begin{environment} ... \end{environment} +# -- +\begin{${1:$$(yas/choose-value (mapcar 'car (LaTeX-environment-list)))}} +$0 +\end{$1} \ No newline at end of file diff --git a/snippets/latex-mode/bib.yasnippet b/snippets/latex-mode/bib.yasnippet new file mode 100644 index 0000000..9dc6ad7 --- /dev/null +++ b/snippets/latex-mode/bib.yasnippet @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor: Mads D. Kristensen +# key: bib +# group: misc +# name: \bibliography +# -- +\bibliographystyle{plain} +\bibliography{$1}$0 \ No newline at end of file diff --git a/snippets/latex-mode/big.yasnippet b/snippets/latex-mode/big.yasnippet new file mode 100644 index 0000000..ff59479 --- /dev/null +++ b/snippets/latex-mode/big.yasnippet @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Song Qiang +# key: big +# group: math +# name: \bigl( ... \bigr) +# -- +\\${1:$$(yas/choose-value '("big" "Big" "bigg" "Bigg"))}l( $0 \\$1r) \ No newline at end of file diff --git a/snippets/latex-mode/bigop.yasnippet b/snippets/latex-mode/bigop.yasnippet new file mode 100644 index 0000000..7aa214f --- /dev/null +++ b/snippets/latex-mode/bigop.yasnippet @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: François Garillot +# key: bigop +# group: math +# name: \bigop_{n}^{} +# -- +\\big${1:$$(yas/choose-value '("oplus" "otimes" "odot" "cup" "cap" "uplus" "sqcup" "vee" "wedge"))}_{$2}^{$3}$0 diff --git a/snippets/latex-mode/binom.yasnippet b/snippets/latex-mode/binom.yasnippet new file mode 100644 index 0000000..98d663d --- /dev/null +++ b/snippets/latex-mode/binom.yasnippet @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Song Qiang +# key: binom +# group: math +# name: \binom{n}{k} +# -- +\binom{${1:n}}{${2:k}} \ No newline at end of file diff --git a/snippets/latex-mode/block.yasnippet b/snippets/latex-mode/block.yasnippet new file mode 100644 index 0000000..39f3cd0 --- /dev/null +++ b/snippets/latex-mode/block.yasnippet @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# contributor: Claudio Marforio +# key: block +# group: environments +# name : \begin{*block} ... \end{*block} +# -- +\begin{${1:$$(yas/choose-value '("block" "exampleblock" "alertblock"))}}{${2:Block Title}} + +\end{$1} diff --git a/snippets/latex-mode/bold.yasnippet b/snippets/latex-mode/bold.yasnippet new file mode 100644 index 0000000..c717a7b --- /dev/null +++ b/snippets/latex-mode/bold.yasnippet @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Mrcio M. Ribeiro +# key: bf +# group: font +# name: {\bf ... } +# -- +{\bf $1}$0 \ No newline at end of file diff --git a/snippets/latex-mode/case.yasnippet b/snippets/latex-mode/case.yasnippet new file mode 100644 index 0000000..70a67d0 --- /dev/null +++ b/snippets/latex-mode/case.yasnippet @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# contributor: Mads D. Kristensen +# key: case +# group: math +# name: \begin{cases} ... \end{cases} +# -- +\begin{cases} +$0 \\\\ +\end{cases} diff --git a/snippets/latex-mode/cha.yasnippet b/snippets/latex-mode/cha.yasnippet new file mode 100644 index 0000000..898e21d --- /dev/null +++ b/snippets/latex-mode/cha.yasnippet @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# contributor : Mads D. Kristensen +# key : cha +# group: sections +# name : \chapter +# -- +\chapter{${1:name}} +\label{${2:"waiting for reftex-label call..."$(unless yas/modified-p (reftex-label nil 'dont-insert))}} +$0 \ No newline at end of file diff --git a/snippets/latex-mode/chastar.yasnippet b/snippets/latex-mode/chastar.yasnippet new file mode 100644 index 0000000..d9a8bb9 --- /dev/null +++ b/snippets/latex-mode/chastar.yasnippet @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor : Mads D. Kristensen +# key : cha* +# group: sections +# name : \chapter* +# -- +\chapter*{${1:name}} +$0 \ No newline at end of file diff --git a/snippets/latex-mode/cite.yasnippet b/snippets/latex-mode/cite.yasnippet new file mode 100644 index 0000000..e709854 --- /dev/null +++ b/snippets/latex-mode/cite.yasnippet @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor : Marcio M. Ribeiro +# key: cite +# group: references +# name : \cite +# -- +\cite{${1:label$(unless yas/modified-p (car (reftex-citation 't)))}}$0 diff --git a/snippets/latex-mode/coprod.yasnippet b/snippets/latex-mode/coprod.yasnippet new file mode 100644 index 0000000..770bbaa --- /dev/null +++ b/snippets/latex-mode/coprod.yasnippet @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: François Garillot +# key: coprod +# group: math +# name: \coprod_{n}^{} +# -- +\coprod_{$1}^{$2}$0 diff --git a/snippets/latex-mode/desc.yasnippet b/snippets/latex-mode/desc.yasnippet new file mode 100644 index 0000000..4b77ad2 --- /dev/null +++ b/snippets/latex-mode/desc.yasnippet @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# contributor : Mads D. Kristensen +# key : desc +# group: environments +# name : \begin{description} ... \end{description} +# -- +\begin{description} +\item[${1:label}] $0 +\end{description} diff --git a/snippets/latex-mode/doc.yasnippet b/snippets/latex-mode/doc.yasnippet new file mode 100644 index 0000000..6203573 --- /dev/null +++ b/snippets/latex-mode/doc.yasnippet @@ -0,0 +1,10 @@ +# -*- mode: snippet -*- +# contributor: Mads D. Kristensen +# key: doc +# name: \documentclass +# -- +\documentclass[$2]{${1:$$(yas/choose-value '("article" "report" "book" "letter"))}} + +\begin{document} +$0 +\end{document} diff --git a/snippets/latex-mode/em.yasnippet b/snippets/latex-mode/em.yasnippet new file mode 100644 index 0000000..84fe8f0 --- /dev/null +++ b/snippets/latex-mode/em.yasnippet @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Mrcio M. Ribeiro +# key: em +# group: font +# name: {\em ...} +# -- +{\em $1}$0 \ No newline at end of file diff --git a/snippets/latex-mode/enum.yasnippet b/snippets/latex-mode/enum.yasnippet new file mode 100644 index 0000000..9d7e398 --- /dev/null +++ b/snippets/latex-mode/enum.yasnippet @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# contributor : Mads D. Kristensen +# key: enum +# group: environments +# name : \begin{enumerate} ... \end{enumerate} +# -- +\begin{enumerate} +\item $0 +\end{enumerate} diff --git a/snippets/latex-mode/eq.yasnippet b/snippets/latex-mode/eq.yasnippet new file mode 100644 index 0000000..64be33f --- /dev/null +++ b/snippets/latex-mode/eq.yasnippet @@ -0,0 +1,10 @@ +# -*- mode: snippet -*- +# contributor: Mads D. Kristensen +# key: eq +# group: math +# name: \begin{equation} ... \end{equation} +# -- +\begin{equation} +\label{${1:"waiting for reftex-label call..."$(unless yas/modified-p (reftex-label nil 'dont-insert))}} +$0 +\end{equation} diff --git a/snippets/latex-mode/eqs.yasnippet b/snippets/latex-mode/eqs.yasnippet new file mode 100644 index 0000000..1eee28c --- /dev/null +++ b/snippets/latex-mode/eqs.yasnippet @@ -0,0 +1,10 @@ +# -*- mode: snippet -*- +# contributor: Mads D. Kristensen +# key: eqs +# group: math +# name: \begin{align} ... \end{align} +# -- +\begin{${1:$$(yas/choose-value '("align" "align*" "multline" "gather" "subequations"))}} +\label{${2:"waiting for reftex-label call..."$(unless yas/modified-p (reftex-label nil 'dont-insert))}} +$0 +\end{$1} diff --git a/snippets/latex-mode/fig.yasnippet b/snippets/latex-mode/fig.yasnippet new file mode 100644 index 0000000..2152c36 --- /dev/null +++ b/snippets/latex-mode/fig.yasnippet @@ -0,0 +1,12 @@ +# -*- mode: snippet -*- +# contributor : Mads D. Kristensen +# key : fig +# group: environments +# name : \begin{figure} ... \end{figure} +# -- +\begin{figure}[htbp] + \centering + $0 + \caption{${1:caption}} + \label{${2:"waiting for reftex-label call..."$(unless yas/modified-p (reftex-label nil 'dont-insert))}} +\end{figure} diff --git a/snippets/latex-mode/frac.yasnippet b/snippets/latex-mode/frac.yasnippet new file mode 100644 index 0000000..12fa023 --- /dev/null +++ b/snippets/latex-mode/frac.yasnippet @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Song Qiang +# key: frac +# group: math +# name: \frac{numerator}{denominator} +# -- +\frac{${1:numerator}}{${2:denominator}}$0 \ No newline at end of file diff --git a/snippets/latex-mode/frame.yasnippet b/snippets/latex-mode/frame.yasnippet new file mode 100644 index 0000000..62158d8 --- /dev/null +++ b/snippets/latex-mode/frame.yasnippet @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# contributor: Claudio Marforio +# key: frame +# group: environments +# name : \begin{frame} ... \end{frame} +# -- +\begin{frame}{${1:Frame Title}} + +\end{frame} diff --git a/snippets/latex-mode/gls.yasnippet b/snippets/latex-mode/gls.yasnippet new file mode 100644 index 0000000..b944042 --- /dev/null +++ b/snippets/latex-mode/gls.yasnippet @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor : Peter Urbak +# key : newgls +# group: misc +# name : \newglossaryentry{...}{...} +# -- +\newglossaryentry{$1}{name={$1}, + description={$2.}} diff --git a/snippets/latex-mode/graphics.yasnippet b/snippets/latex-mode/graphics.yasnippet new file mode 100644 index 0000000..c3add51 --- /dev/null +++ b/snippets/latex-mode/graphics.yasnippet @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# contributor : Mads D. Kristensen +# key : graphics +# name : \includegraphics +# -- +\includegraphics[width=${1:\linewidth}]{${2:file}} \ No newline at end of file diff --git a/snippets/latex-mode/href.yasnippet b/snippets/latex-mode/href.yasnippet new file mode 100644 index 0000000..78ce877 --- /dev/null +++ b/snippets/latex-mode/href.yasnippet @@ -0,0 +1,6 @@ +# -*- mode: snippet -*- +# key: href +# group: environments +# name: \href{url}{text} +# -- +\href{${1:url}}{${2:text}}$0 \ No newline at end of file diff --git a/snippets/latex-mode/int.yasnippet b/snippets/latex-mode/int.yasnippet new file mode 100644 index 0000000..ead32d7 --- /dev/null +++ b/snippets/latex-mode/int.yasnippet @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Song Qiang +# key: int +# group: math +# name: \int_{n}^{} +# -- +\\${1:$$(yas/choose-value '("int" "oint" "iint" "iiint" "iiiint" "idotsint"))}{$2}^{$3}$0 diff --git a/snippets/latex-mode/it.yasnippet b/snippets/latex-mode/it.yasnippet new file mode 100644 index 0000000..d9052bf --- /dev/null +++ b/snippets/latex-mode/it.yasnippet @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Mads D. Kristensen +# key: it +# group: environments +# name: \item +# -- +\item $0 \ No newline at end of file diff --git a/snippets/latex-mode/itd.yasnippet b/snippets/latex-mode/itd.yasnippet new file mode 100644 index 0000000..94d9358 --- /dev/null +++ b/snippets/latex-mode/itd.yasnippet @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Rasmus Borgsmidt +# key: itd +# group: environments +# name: \item[] (description) +# -- +\item[${1:label}] $0 \ No newline at end of file diff --git a/snippets/latex-mode/item.yasnippet b/snippets/latex-mode/item.yasnippet new file mode 100644 index 0000000..14fb2d0 --- /dev/null +++ b/snippets/latex-mode/item.yasnippet @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# contributor : Mads D. Kristensen +# key : item +# group: environments +# name : \begin{itemize} ... \end{itemize} +# -- +\begin{itemize} +\item $0 +\end{itemize} diff --git a/snippets/latex-mode/label.yasnippet b/snippets/latex-mode/label.yasnippet new file mode 100644 index 0000000..9bcc82b --- /dev/null +++ b/snippets/latex-mode/label.yasnippet @@ -0,0 +1,7 @@ + -*- mode: snippet -*- +# contributor : Mrcio M. Ribeiro +# key: lab +# group: references +# name : \label +# -- +\label{${1:label$(unless yas/modified-p (reftex-label nil 'dont-insert))}}$0 diff --git a/snippets/latex-mode/letter.yasnippet b/snippets/latex-mode/letter.yasnippet new file mode 100644 index 0000000..258cf3d --- /dev/null +++ b/snippets/latex-mode/letter.yasnippet @@ -0,0 +1,27 @@ +# -*- mode: snippet -*- +# contributor: Mads D. Kristensen +# contributor : Song Qiang +# key: letter +# group: skeleton +# name: \documentclass{letter} ... +# -- +\documentclass{letter} +\signature{${1:Foo Bar}} +\address{${2:Address line 1 \\\\ +Address line 2 \\\\ +Address line 3}} +\begin{document} + +\begin{letter} +{${3:Recipient's address}} + +\opening{Dear ${4:Sir}:} + +$0 + +\closing{Yours Sincerely,} + +\end{letter} + +\end{document} + diff --git a/snippets/latex-mode/lim.yasnippet b/snippets/latex-mode/lim.yasnippet new file mode 100644 index 0000000..04f1417 --- /dev/null +++ b/snippets/latex-mode/lim.yasnippet @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: François Garillot +# key: lim +# group: math +# name: \lim_{n} +# -- +\lim_{$1}$0 diff --git a/snippets/latex-mode/math.yasnippet b/snippets/latex-mode/math.yasnippet new file mode 100644 index 0000000..cfbdd04 --- /dev/null +++ b/snippets/latex-mode/math.yasnippet @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# contributor: Song Qiang +# key: math +# group: math +# name: displaymath \[ ... \] +# -- +\[ +$1 +\] diff --git a/snippets/latex-mode/matrix.yasnippet b/snippets/latex-mode/matrix.yasnippet new file mode 100644 index 0000000..58d643c --- /dev/null +++ b/snippets/latex-mode/matrix.yasnippet @@ -0,0 +1,11 @@ +# -*- mode: snippet -*- +# contributor: Song Qiang +# key: matrix +# group: math +# name: \begin{matrix} ... \end{} +# -- +\begin{${1:$$(yas/choose-value '("pmatrix" "bmatrix" "Bmatrix" "vmatrix" "Vmatrix" "smallmatrix"))}} +\label{${2:"waiting for reftex-label call..."$(unless yas/modified-p (reftex-label nil 'dont-insert))}} +$0 +\end{$1} + diff --git a/snippets/latex-mode/minipage.yasnippet b/snippets/latex-mode/minipage.yasnippet new file mode 100644 index 0000000..447b31e --- /dev/null +++ b/snippets/latex-mode/minipage.yasnippet @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# contributor: Mads D. Kristensen +# key: minipage +# group: environments +# name: \begin{minipage}[position][width] ... \end{minipage} +# -- +\begin{minipage}[${1:htbp}]{${2:1.0}${3:\linewidth}} + $0 +\end{minipage} \ No newline at end of file diff --git a/snippets/latex-mode/par.yasnippet b/snippets/latex-mode/par.yasnippet new file mode 100644 index 0000000..ffe3e14 --- /dev/null +++ b/snippets/latex-mode/par.yasnippet @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# contributor : Mads D. Kristensen +# key: par +# group: sections +# name : \paragraph +# -- +\paragraph{${1:name}} +\label{${2:"waiting for reftex-label call..."$(unless yas/modified-p (reftex-label nil 'dont-insert))}} +$0 \ No newline at end of file diff --git a/snippets/latex-mode/prod.yasnippet b/snippets/latex-mode/prod.yasnippet new file mode 100644 index 0000000..7174475 --- /dev/null +++ b/snippets/latex-mode/prod.yasnippet @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: François Garillot +# key: prod +# group: math +# name: \prod_{n}^{} +# -- +\prod_{$1}^{$2}$0 diff --git a/snippets/latex-mode/ref.yasnippet b/snippets/latex-mode/ref.yasnippet new file mode 100644 index 0000000..c3a4116 --- /dev/null +++ b/snippets/latex-mode/ref.yasnippet @@ -0,0 +1,7 @@ + -*- mode: snippet -*- +# contributor : Mrcio M. Ribeiro +# key: ref +# group: references +# name : \ref +# -- +\ref{${1:label$(unless yas/modified-p (reftex-reference nil 'dont-insert))}}$0 \ No newline at end of file diff --git a/snippets/latex-mode/sc.yasnippet b/snippets/latex-mode/sc.yasnippet new file mode 100644 index 0000000..5194a85 --- /dev/null +++ b/snippets/latex-mode/sc.yasnippet @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Rasmus Borgsmidt +# key: sc +# group: font +# name: {\sc ...} +# -- +{\scshape $1}$0 \ No newline at end of file diff --git a/snippets/latex-mode/sec.yasnippet b/snippets/latex-mode/sec.yasnippet new file mode 100644 index 0000000..993e5aa --- /dev/null +++ b/snippets/latex-mode/sec.yasnippet @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# contributor : Mads D. Kristensen +# key : sec +# group: sections +# name : \section +# -- +\section{${1:name}} +\label{${2:"waiting for reftex-label call..."$(unless yas/modified-p (reftex-label nil 'dont-insert))}} +$0 \ No newline at end of file diff --git a/snippets/latex-mode/secstar.yasnippet b/snippets/latex-mode/secstar.yasnippet new file mode 100644 index 0000000..1d6ff55 --- /dev/null +++ b/snippets/latex-mode/secstar.yasnippet @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor : Mads D. Kristensen +# key : sec* +# group: sections +# name : \section* +# -- +\section*{${1:name}} +$0 \ No newline at end of file diff --git a/snippets/latex-mode/ssub.yasnippet b/snippets/latex-mode/ssub.yasnippet new file mode 100644 index 0000000..c78dae6 --- /dev/null +++ b/snippets/latex-mode/ssub.yasnippet @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# contributor : Mads D. Kristensen +# key: ssub +# group: sections +# name : \subsubsection +# -- +\subsubsection{${1:name}} +\label{${2:"waiting for reftex-label call..."$(unless yas/modified-p (reftex-label nil 'dont-insert))}} +$0 \ No newline at end of file diff --git a/snippets/latex-mode/ssubstar.yasnippet b/snippets/latex-mode/ssubstar.yasnippet new file mode 100644 index 0000000..5399487 --- /dev/null +++ b/snippets/latex-mode/ssubstar.yasnippet @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor : Mads D. Kristensen +# key: ssub* +# group: sections +# name : \subsubsection* +# -- +\subsubsection*{${1:name}} +$0 \ No newline at end of file diff --git a/snippets/latex-mode/sub.yasnippet b/snippets/latex-mode/sub.yasnippet new file mode 100644 index 0000000..f71ebb2 --- /dev/null +++ b/snippets/latex-mode/sub.yasnippet @@ -0,0 +1,9 @@ +# -*- mode: snippet -*- +# contributor : Mads D. Kristensen +# key: sub +# group: sections +# name : \subsection +# -- +\subsection{${1:name}} +\label{${2:"waiting for reftex-label call..."$(unless yas/modified-p (reftex-label nil 'dont-insert))}} +$0 \ No newline at end of file diff --git a/snippets/latex-mode/subfig.yasnippet b/snippets/latex-mode/subfig.yasnippet new file mode 100644 index 0000000..7388475 --- /dev/null +++ b/snippets/latex-mode/subfig.yasnippet @@ -0,0 +1,10 @@ +# -*- mode: snippet -*- +# contributor : Mads D. Kristensen +# key: subfig +# group: environments +# name : \subfigure +# -- +\subfigure[${1:caption}]{ + \label{${2:"waiting for reftex-label call..."$(unless yas/modified-p (reftex-label nil 'dont-insert))}} + $0 +} diff --git a/snippets/latex-mode/substar.yasnippet b/snippets/latex-mode/substar.yasnippet new file mode 100644 index 0000000..3af6aae --- /dev/null +++ b/snippets/latex-mode/substar.yasnippet @@ -0,0 +1,8 @@ +# -*- mode: snippet -*- +# contributor : Mads D. Kristensen +# key: sub* +# group: sections +# name : \subsection* +# -- +\subsection*{${1:name}} +$0 \ No newline at end of file diff --git a/snippets/latex-mode/sum.yasnippet b/snippets/latex-mode/sum.yasnippet new file mode 100644 index 0000000..2dd1ff5 --- /dev/null +++ b/snippets/latex-mode/sum.yasnippet @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Song Qiang +# key: sum +# group: math +# name: \sum_{n}^{} +# -- +\sum_{$1}^{$2}$0 diff --git a/snippets/latex-mode/table.yasnippet b/snippets/latex-mode/table.yasnippet new file mode 100644 index 0000000..ebcc444 --- /dev/null +++ b/snippets/latex-mode/table.yasnippet @@ -0,0 +1,14 @@ +# -*- mode: snippet -*- +# contributor : Mads D. Kristensen +# key: table +# group: environments +# name : \begin{table} ... \end{table} +# -- +\begin{table}[htbp] + \centering + \begin{tabular}{${3:format}} + $0 + \end{tabular} + \caption{${1:caption}} + \label{${2:"waiting for reftex-label call..."$(unless yas/modified-p (reftex-label nil 'dont-insert))}} +\end{table} diff --git a/snippets/latex-mode/tt.yasnippet b/snippets/latex-mode/tt.yasnippet new file mode 100644 index 0000000..24461f2 --- /dev/null +++ b/snippets/latex-mode/tt.yasnippet @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Rasmus Borgsmidt +# key: tt +# group: font +# name: {\tt ...} +# -- +{\tt $1}$0 \ No newline at end of file diff --git a/snippets/latex-mode/url.yasnippet b/snippets/latex-mode/url.yasnippet new file mode 100644 index 0000000..eb56f6b --- /dev/null +++ b/snippets/latex-mode/url.yasnippet @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Mads D. Kristensen +# key: url +# group: environments +# name: \url +# -- +\url{${1:$$(yas/choose-value '("http" "ftp"))}://${2:address}}$0 \ No newline at end of file diff --git a/snippets/latex-mode/use.yasnippet b/snippets/latex-mode/use.yasnippet new file mode 100644 index 0000000..8b99050 --- /dev/null +++ b/snippets/latex-mode/use.yasnippet @@ -0,0 +1,7 @@ +# -*- mode: snippet -*- +# contributor: Mads D. Kristensen +# key: use +# group: misc +# name: \usepackage +# -- +\usepackage[$2]{$1}$0 \ No newline at end of file diff --git a/snippets/latex-mode/verb.yasnippet b/snippets/latex-mode/verb.yasnippet new file mode 100644 index 0000000..c63f997 --- /dev/null +++ b/snippets/latex-mode/verb.yasnippet @@ -0,0 +1,11 @@ +# -*- mode: snippet -*- +# contributor: Mads D. Kristensen +# contributor : Bjorn Reese +# contributor : Song Qiang +# key: verb +# group: environments +# name: \begin{verbatim} ... \end{verbatim} +# -- +\begin{verbatim} +$0 +\end{verbatim}