commit 96a9c67adacf2c51f19d1a8f72d7830e3699272d Author: CAPELLE Mikaël Date: Mon Jan 13 15:14:54 2020 +0100 Initial commit. 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 0000000..e55762e Binary files /dev/null and b/images/KEC_Dark_BK.png differ diff --git a/images/KEC_Dark_BK_Small.png b/images/KEC_Dark_BK_Small.png new file mode 100644 index 0000000..9a6a7d0 Binary files /dev/null and b/images/KEC_Dark_BK_Small.png differ diff --git a/images/KEC_Light_BK.png b/images/KEC_Light_BK.png new file mode 100644 index 0000000..5534757 Binary files /dev/null and b/images/KEC_Light_BK.png differ diff --git a/images/KEC_Light_BK_Small.png b/images/KEC_Light_BK_Small.png new file mode 100644 index 0000000..49459e5 Binary files /dev/null and b/images/KEC_Light_BK_Small.png differ 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}