commit 168bd9cce801934ad5708cf1e7a93db183df9add Author: brettlangdon Date: Mon Nov 28 10:29:51 2016 -0500 Squashed 'emacs.d/' content from commit 664ba6a git-subtree-dir: emacs.d git-subtree-split: 664ba6ab2c4ea0aa00aa8483e587efb34829abbe diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE new file mode 100644 index 0000000..fdb7479 --- /dev/null +++ b/.github/ISSUE_TEMPLATE @@ -0,0 +1,4 @@ +If you are posting about a *bug* please close this issue and open a new one +using [SPC h I] or [M-m h I] (I = capital i) from within Spacemacs. If the +bug makes Spacemacs unusable, you can find the bug report template [here](https://github.com/syl20bnr/spacemacs/blob/develop/core/templates/REPORTING.template) +You can delete this message to start typing. diff --git a/.github/PULL_REQUEST_TEMPLATE b/.github/PULL_REQUEST_TEMPLATE new file mode 100644 index 0000000..96c72a7 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE @@ -0,0 +1,7 @@ +Thank you for contributing to Spacemacs! + +Before you submit this pull request, please ensure it is against the develop branch and not master. + +This message should be replaced with a description of your change. + +Thank you <3 \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..22e8323 --- /dev/null +++ b/.gitignore @@ -0,0 +1,53 @@ +auto-save-list/ +elpa/ +export/ +ac-comphist.dat +eproject.lst +.smex-items +\#* +.places +.cache +/eww-bookmarks +eshell/history +.emacs.desktop +.emacs.desktop.lock +eshell/alias +eshell/lastdir +/url/cookies +my-org/ +org-files/ +semanticdb/ +edts/ +.recentf +.recentf~ +projectile.cache +projectile-bookmarks.eld +tramp +elnode/ +var/ +crown/ +*.stackdump +bookmarks +/.my-keybindings.el.swp +.DS_Store +tmp/ +/history +.python-environments/ +server/ +/network-security.data +*.elc +*.pyc +/*.zip +*.db +python-*-docs-html +/.cask/ +/session.* +/srecode-map.el +/recentf + +# Private directory +private/ +!private/README.md +!private/snippets/README.md +!private/local/README.md +/games/ diff --git a/.projectile b/.projectile new file mode 100644 index 0000000..1974e79 --- /dev/null +++ b/.projectile @@ -0,0 +1,10 @@ +-/semanticdb +-/url +-/edts +-/elpa +-/.cache +-ac-comphist.dat +-.emacs.desktop +-.emacs.desktop.lock +-.smex-items +-*.elc \ No newline at end of file diff --git a/.travis-build.sh b/.travis-build.sh new file mode 100755 index 0000000..0b8be23 --- /dev/null +++ b/.travis-build.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +## run_build.sh --- Travis CI File for Spacemacs +## +## Copyright (c) 2012-2014 Sylvain Benner +## Copyright (c) 2014-2015 Sylvain Benner & Contributors +## +## Author: Sylvain Benner +## URL: https://github.com/syl20bnr/spacemacs +## +## This file is not part of GNU Emacs. +## +## License: GPLv3 + +tests=("core") + +if [ $USER != "travis" ]; then + echo "This script is not designed to run locally." + echo "Instead, navigate to the appropriate test folder and run make there instead." + exit 1 +fi + +if [ $TRAVIS_SECURE_ENV_VARS = false ] && + [ $TRAVIS_PULL_REQUEST != false ] && + [ $TRAVIS_BRANCH = "master" ]; then + + printf '=%.0s' {1..70} + printf "\n し(*・∀・)/ Thanks for the contribution! \(・∀・*)ノ\n" + printf '=%.0s' {1..70} + printf "\n( ^◡^)っ Please submit your pull request against the develop branch.\n" + echo "You can read the contribution guidelines at:" + echo "https://github.com/syl20bnr/spacemacs/blob/develop/CONTRIBUTING.org" + exit 1 +fi + +echo "Pwd $(pwd)" +rm -rf ~/.emacs.d +ln -sf `pwd` ~/.emacs.d + +for test in "${tests[@]}"; do + rm -rf ~/.emacs.d/elpa + rm -rf ~/.emacs.d/.cache + rm -f ~/.spacemacs + + testdir=~/.emacs.d/tests/$test + echo "Running '$test' in '$testdir' folder" + if [ -f $testdir/dotspacemacs.el ]; then + cp $testdir/dotspacemacs.el ~/.spacemacs + fi + cd $testdir && echo "Now in $(pwd)" + make test || exit 2 +done diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..6a8b254 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,25 @@ +language: generic +sudo: false + +branches: + only: + - master + - develop + +before_install: + - curl -fsSkL https://gist.github.com/rejeep/ebcd57c3af83b049833b/raw > x.sh && source ./x.sh + - evm install $EVM_EMACS --use --skip + +env: + - EVM_EMACS=emacs-24.4-travis + - EVM_EMACS=emacs-24.5-travis + - EVM_EMACS=emacs-git-snapshot-travis + +matrix: + fast_finish: true + allow_failures: + env: + - EVM_EMACS=emacs-git-snapshot-travis + +script: + - ./.travis-build.sh diff --git a/CHANGELOG.org b/CHANGELOG.org new file mode 100644 index 0000000..86c6465 --- /dev/null +++ b/CHANGELOG.org @@ -0,0 +1,3759 @@ +* Release 0.200.x +** 0.200.5 (2016/11/03) +*** Fixes +- Removed themes missing from MELPA (=colorsarenice-theme= and =stekene-theme=) +** 0.200.4 (2016/10/26) +*** Fixes +- Update go-guru package reflecting MELPA changes +** 0.200.3 (2016/10/18) +*** Fixes +- Fix broken macOS paths for homebrew service (thanks to mgiles) +*** Improvements +- Add =system-configuration-features= to system description (~SPC h d s~) + for Emacs 25 and later (thanks to JAremko) +- Add support for =doom= themes (thanks to TheBB) +- Revert back default value for =dotspacemacs-startup-lists= (was previously + changed to be nil) +- Warn if layers changed outside =dotspacemacs/layers= function + (thanks to TheBB) +- Show a list of Spacemacs warnings in home buffer (thanks to TheBB) +- Prevent =:toggle= expression from being evaluated for excluded packages + (thanks to TheBB) +- Various documentation improvements (thanks to arronmabrey, carbohydratesn, + d12frosted, d1egoaz, deb0ch, duianto, eagleflo, JAremko, jredville, lunik1, + mineo, nixmaniack, philtothetop, roryokane, swaroopch, TheBB, Tritlo, tudho, + xificurC) +*** Layer changes +**** Spacemacs distribution +- Add =golden-ratio= toggle key in window transient-state only when + =golden-ratio= package is used (thanks to bmag) +- Enable line numbers for =conf-mode= (by deriving =conf-mode= from + =text-mode=) (thanks to valentjedi) +- New key binding ~SPC c h~ to hide/show comments in a file using the package + =hide-comnt= +- Add ~q~ key binding to quit the =evil-number= transient-state (thanks to duianto) +- Activating =linum-relative= now correctly activates =linum= (thanks to deb0ch) +**** C/C++ +- Match entire path after -I when reading cc-file (function + =company-mode/load-clang-complete-file=) (thanks to jlewallen) +**** Common-lisp +- Enable fuzzy matching for auto-completion (thanks to tuhdo) +**** D +- Add support for auto-completion via =DCD= (thanks to tuhdo) +- Add new key bindings for code navigation: + - ~SPC m g g~ to go to definition + - ~SPC m g b~ to jump back (after go to definition with above command) + - ~SPC m g r~ to find references to all symbol at point + (thanks to tuhdo) +**** IPython-notebook +- Fix deprecated =axes.color_cycle= in =matplotlibrc= (thanks to Retorz) +**** Ivy +- Fix spacemacs layout transient-state to correctly exit when selecting a layout + (thanks to gilbertw1) +- Make =ivy= restrict buffers to current spacemacs layout (thanks to bmag) +**** Elixir +- Add support for =org-babel= (thanks to usharf) +- Enable =flycheck= on idle since recent changes to =flycheck-mix= make it safe + (thanks to aaronjensen) +**** ERC +- Fix connecting to default servers with TLS more than once with ERC + (thanks to Hoot215) +**** Git +- Use =fill-column-indicator= only when the package is effectively used + (thanks to bmag) +- Use =magit= 2.8 built-in fullscreen display function (update your + packages) (thanks to houli) +**** Go +- Replace deprecated =go-oracle= by =go-guru= (thanks to edrex) +- Remove check for =GOPATH= when initializing =go-guru= (thanks to goofansu) +- Fix usage of =go-rename= on symlinked projects (thanks to grncdr) +**** Helm +- Add key binding ~M-RET~ (meta-return) to open the file =packages.el= + of a layer in =helm-spacemacs-help= under ~SPC h SPC~ (thansk to CestDiego) +**** Html +- Fix hooks for CSS-mode since it now derives from =prog-mode= in Emacs 25 + (thanks to TheBB) +**** Javascript +- Add missing command prefix names (thanks to shanavas786) +**** Ocaml +- Add =cmti= extension to list of ignored completion extensions + (thanks to rgrinberg) +**** Org +- Fix location of =org-async-init.el= (thanks to fintelkai) +- Add support for =:q= and =:wq= ex commands for abort and finalize in + =org-capture= and =org-src-edit= (thanks to mwillsey) +- Add support for =Twitter Bootstrap= for export to html. + To enable the support for =bootstrap= set the new layer variable + =org-enable-bootstrap-support= to =t= (thanks to kalhauge) +**** Nim +- Add support =nimsuggest= for better completion using Nim's IDE tool + (thanks to tuhdo) +- Add support for =eldoc= via =nimsuggest= (thanks to tuhdo) +- New key bindings for code navigation: + - ~SPC m g g~ to jump to definition + - ~SPC m g b~ to jump back + (thanks to tuhdo) +**** Plantuml +- Replace deprecated =puml-mode= by =plantuml-mode= (thanks to skuro) +**** Python +- Fix start of REPL for Emacs 25.1 (thanks to bmag) +- Make =python-tab-width= configurable (thanks to TheBB) +- Add support for =wdb= debugger when inserting breakpoints using ~SPC m d b~ + (thanks to koterpillar) +- Use =semantic= for =imenu= only when =semantic-mode= is enabled + (thanks to bmag) +- Improve =spacemacs/python-execute-file= on ~SPC m c c~ to pre-fill + "python " as the compile command when using the universal prefix + argument ~SPC u SPC m c c~ (thanks to bmag) +**** Ruby +- Add support for =minitest= test runner (thanks to pawandubey) +**** Ruby on rails +- Declare prefix command for =ruby-mode= and =enh-ruby-mode= (thanks to selmanj) +**** Scala +- Remove =ensime= obsolete commands =ensime-db-start= and + =ensime-db-list-locals= (thanks to atreeyang) +**** Shell-scripts +- New key binding ~SPC i !~ to insert shebang line in script files using + package =insert-shebang= +**** Syntax checking +- Add support for new =flycheck= feature =flycheck-explain-error= on ~SPC e e~ + (thanks to fmdkdd) +**** Typescript +- Add support for auto-completion (thanks to TheBB) +**** Yaml +- Add support for syntax checking (thanks to rski) +**** Ycmd +- Improve search of nearest file in compilation database (thanks to deb0ch) +** 0.200.2 (2016/10/14) +*** Fixes +- Fix compatibility with the =xterm-color= package (thanks to bixuanzju) +** 0.200.1 (2016/10/09) +*** Fixes +- Restore missing support for custom Evil ex command key via the new + =dotspacemacs-ex-command-key= variable (thanks to Dietr1ch) +- core: Fix lazy installation of layers +- core: Fix Quelpa recipes construction (thanks to ynilu) +- core: Fix unwanted exclusion of packages when setting + =dotspacemacs-install-packages= to =all= +- core: Fix =spacemacs/ert-run-tests-buffer= to run only the tests in current + buffer (thanks to bmag) +*** Dotfile changes +- New variable =dotspacemacs-ex-command-key= to define the key to press + to enter an Evil ex command, default is ~:~ (thanks to Dietr1ch) +- Change default value of =dotspacemacs-startup-lists= to =nil= +*** Layer changes +**** Agda +- Enable auto-completion (thanks to bixuanzju) +**** Clojure +- Add support for =org-babel= (thanks to drewokane) +**** Git +- Adjust linum gutter to accomodate text-size changes (thanks to nspaeth) +**** Html +- Replace =jade-mode= by =pug-mode= (Jade is now Pug) (thanks to robbyoconnor) +**** Markdown +- Enable =orgtbl-mode=, this makes working with tables much nicer + (thanks to robbyoconnor) +**** React +- Enable =emmet-mode= (thanks to kaipr) +**** Shell +- Fix shell regular expression to add shell buffers to useful buffers + (thanks to TheBB) +**** Ycmd +- Improve performance on large projects by removing buffer parsing on newline + insertion (thanks to deb0ch) +*** Improvements +- Add support for transparency in multiple frames (thanks to TGThorax) +- Add ~J~ and ~K~ key bindings on the home buffer to navigate between widgets + (thanks to tobimensch) +- Various documentation improvements (thanks to andschwa, bmag, duianto, jazzpi, + Tritlo, vigilancer) +** 0.200.0 (2016/10/02) +*** IMPORTANT: Breaking changes +- The support for Emacs 24.3 has been dropped, Spacemacs needs at least Emacs + 24.4 to work correctly. +- =extensions= are deprecated as announced in previous release, if you still + have =extensions= directories you must rename them to =local= and move + the contents of the =extensions.el= files to the =packages.el= files adding + the keyword =:location local= to them in the package list. Refer to other + layers for examples (for instance the =python= layer) +- =-excluded-packages= variables are now deprecated as announced in + previous release, you must now use the keyword =:excluded t= of the package + list, see the =vim-empty-lines= layer for example. +- Key binding ~SPC :~ acting as =M-x= as been replaced by ~SPC SPC~. + If you want to revert to the old ~SPC :~ key binding set the new + variable =dotspacemacs-emacs-command-key= to ":". +- Key binding ~SPC f e h~ is now ~SPC h SPC~ +- Key bindings to delete things are now more consistent and use the ~d~ key. + We moved ~SPC w c~ and ~SPC w C~ to ~SPC w d~ and ~SPC w D~. +- Refactor ~SPC w~ and ~SPC b~ regarding deletion to clean redundant actions + and bring more consistency between the two prefixes (see + =Distribution layer changes= section in change log for more information) +- ~SPC j~ prefix has been modified to include =jump= commands: + - =avy= commands are now behind the prefix ~SPC j~ for =jump=: + - ~SPC j j~ to jump to a character in the buffer (works as an evil motion) + - ~SPC j l~ to jump to a line with avy (works as an evil motion) + - ~SPC j w~ to jump to a word in the current buffer (works as an evil motion) + - the following key bindings have been moved: + - ~SPC j j~ to split a line has been moved to ~SPC j n~ + - ~SPC j h~ and ~SPC j l~ have been moved to ~SPC j 0~ and ~SPC j $~ + respectively. + - ~SPC J~ to split a string or sexp has been moved to ~SPC j s~ +- All helm related key bindings under ~SPC h~ that are not about help have + been moved to different key bindings: + - ~SPC h b~ for =helm-filtered-bookmarks~is now ~SPC f b~ + - ~SPC h l~ for =helm-resume= is now ~SPC r l~ + - ~SPC h L~ for =helm-locate-library= is now ~SPC f e l~ +- Git key bindings under ~SPC g~ have been reorganised to free up some keys + and capitalize on =Magit= dispatch menu to keep things consistent (see + =git= section in change log for more information) +- Spacemacs layouts scope has been changed, now ~SPC b b~ lists the buffers of + the current layout, use ~SPC B b~ to list all the opened buffers. +- =org-indent= is now turned off by default +- Micro states are now called transient states, the macro + =spacemacs|define-micro-state= is deprecated, it is replaced by the new + =hydra= powered macro =spacemacs|define-transient-state=. +- Spacemacs layouts and workspaces transient states now exit when a layout or + workspace is selected, use ~C-0~ ... ~C-9~ to switch to a layout and keep + the transient state open. +- Remove support for the value =all= for =dotspacemacs-configuration-layers= + variable. To install all the packages supported by Spacemacs there is a new + variable =dotspacemacs-install-packages=. +- Remove layer variable =colors-enable-rainbow-identifiers= in =colors= layer, + You have to replace it by =colors-colorize-identifiers 'all=. +- The =bépo= layer has been replaced by the new layer =keyboard-layout=, see the + =README.org= of the layer for more info. +*** Hot new features +- Refactor of the layer system which should reduce startup time by 20~25%. +- New option to lazy install layers based on =auto-mode-alist= (similar to + =Prelude= lazy install of packages but for layers) via the variable + =dotspacemacs-enable-lazy-installation=. +- Add support for Ivy via the new layer =ivy=, when used it replaces =helm= + (thanks to justbur, d12frosted, goofansu, lszekeres, nixmaniack, ralesi, + TheBB, zilongshanren) +- Add support for different keyboard layouts via the new layer + =keyboard-layout=, currently supported layouts are =bépo= and =dvorak= + (thanks to StreakyCobra) +- New transient states powered by =Hydra=, they replace the deprecated + micro states (thanks to justbur) +- New =jump to definition= abstraction to handle multiple jump backends like + tags, dumb-jump etc... (thanks to TheBB) +- Global access to all available REPLs with ~SPC a '~ and `SPC m '~ (thanks to + AlejandroCatalina and TheBB) +- New debugging tools: + - press ~SPC q d~ to restart Emacs in debug mode with command line parameter + =--debug-init= + - press ~SPC q D~ to restart Emacs without Spacemacs but with a list of + selected packages to load. + (thanks to StreakyCobra) +- New way to install all the supported packages by Spacemacs via the variable + =dotspacemacs-install-packages= +- Improved =emacs= and =hybrid= editing styles to fix configuration + inconsistencies +- the =spacemacs= layer has been split into multiple layers to allow better + modularity (these layers are in =+spacemacs= sub-directory): + - spacemacs-completion + - spacemacs-editing + - spacemacs-editing-visual + - spacemacs-evil + - spacemacs-language + - spacemacs-layouts + - spacemacs-misc + - spacemacs-org + - spacemacs-ui + - spacemacs-ui-visual + (thanks to justbur) +*** New Layers +- asm in =+lang= (thanks to thudo) +- bibtex in =+lang= (thanks to JP-Ellis) +- csv in =+lang= (thanks to jb55) +- cfengine in =+tools= (thanks to nickanderson) +- helm in =completion= (moved from spacemacs-base) (thanks to justbur) +- imenu-list in =+tools= (thanks to bmag) +- ivy in =completion= (thanks to justbur) +- keyboard-layout (replaces the bépo layer) (thanks to StreakyCobra) +- nlinum in =+misc= (thanks to CodeFalling) +- pdf-tools in =+tools= (thanks to Andre0991) +- plantuml in =+lang= (thanks to robbyoconnor) +- rebox in =+tools= (thanks to choppsv1) +- shaders in =+lang= (thanks to Ell) +- slack in =+chat= (thanks to kostajh) +- systemd in =+tools= (thanks to StreakyCobra) +*** Dotfile changes +**** Changes for variable values and keywords +- Add new keyword =:packages= for the list of layers in variable + =dotspacemacs-configuration-layer=, =:packages= allow to select or exclude + packages from a layer. +- Add new keyword =:enabled-for= for the list of layers in variable + =dotspacemacs-configuration-layer=, this keyword controls the effect of a + layer on the other layers. For instance one can enable the =auto-completion= + only for the =python= layer with the value + =(auto-completion :enabled-for python)= + Note that this keyword is the opposite of the existing keyword + =:disabled-for=. (thanks to TheBB) +- The value of =dotspacemacs-editing-style= can now be a list containing the + keyword =:variables= (similar to =dotspacemacs-configuration-layers=) to + define additional variables to modify the behavior of the editing style. This + new keyword is useful for =hybrid= style which supports these variables: + - =hybrid-mode-enable-evilified-state=, if non nil then buffer are evilified, + - =hybrid-mode-enable-hjkl-bindings=, if non nil navigation on ~hjkl~ keys is + enabled (for instance in =helm= buffers), + - =hybrid-mode-default-state=, the default state when opening a new buffer, + by default it is =normal=. +- The value of =dotspacemacs-default-font= can now be a list (thanks to TheBB) +- New supported values for =dotspacemacs-startup-lists=: + - agenda + - todos + (thanks to tonyday567) +- Change default value of =dotspacemacs-startup-lists= to =nil= +- Change default value of =dotspacemacs-check-for-update= to =nil= +- Remove support for value =all= in variable =dotspacemacs-configuration-layers= +- Remove variable =dotspacemacs-startup-recent-list-size= which has been replaced + by adding support for cons cells in variable =dotspacemacs-startup-list= + (thanks to ralesi) +**** New variables +- New variable =dotspacemacs-enable-lazy-installation= to install a layer only + when a file with a supported type is opened. Possible values are =all=, + =unused= and =nil=: + - =unused= will lazy install only unused layers + - =all= will lazy install any layer that support lazy installation even the + used layers + - =nil= disable the lazy installation feature + Default value is =unused= +- New variable =dotspacemacs-frozen-packages=. It is a list of packages, these + packages cannot be updated or rollbacked. +- New variable =dotspacemacs-install-packages= which replaces the variable + =dotspacemacs-delete-orphan-packages=. This new variable defines the behavior + of Spacemacs for installed packages. + Possible values are =used-only=, =used-but-keep-unused= and =all=. + - =used-only= installs only explicitly used packages and uninstall any + unused packages as well as their unused dependencies. + - =used-but-keep-unused= installs only the used packages but won't uninstall + them if they become unused. + - =all= installs *all* packages supported by Spacemacs and never uninstall + them. + Default value is =used-only=. +- New variable =dotspacemacs-emacs-command-key= which replaces the variable + =dotspacemacs-command-key=. This variable represents the key to press after + the leader key to execute =M-x=. Default value is ~SPC~. +- New variable =dotspacemacs-folding-method= to allow choosing between + different code folding methods. Currently supported are =evil= and =origami=. + Default value is =evil=. (thanks to ralesi) +- New variable =dotspacemacs-ex-substitute-global=, if non-nil then + the behavior of the =g= flag in =:substitute= ex-command is inverted. + Default value is nil (thanks to fbergroth) +- New variable =dotspacemacs-smart-closing-parenthesis=. If non-nil pressing + the closing parenthesis ~)~ key in insert mode passes over any automatically + added closing parenthesis, bracket, quote, etc... + This can be temporary disabled by pressing ~C-q~ before ~)~. Default is nil. + (thanks to StreakyCobra) +- New variable =dotspacemacs-retain-visual-mode-on-shift=, If non nil ~>~ is + remapped to ~>gv~ and ~<~ is remapped to ~~ magit-submodule-popup + - ~SPC g A~ magit-cherry-pick-popup + - ~SPC g c~ magit-commit-popup + - ~SPC g C~ magit-checkout + - ~SPC g d~ magit-diff-popup + - ~SPC g D~ spacemacs/magit-diff-head + - ~SPC g e~ magit-ediff-compare + - ~SPC g E~ magit-ediff-show-working-tree + - ~SPC g f~ magit-fetch-popup + - ~SPC g F~ magit-pull-popup + - ~SPC g i~ magit-init + - ~SPC g l~ magit-log-popup + - ~SPC g L~ magit-log-buffer-file + - ~SPC g r~ magit-rebase-popup + - ~SPC g P~ magit-push-popup + - ~SPC g U~ magit-unstage-file + - ~SPC g x~ magit-reset-popup + - the above key bindings have been replaced by only one key binding ~SPC g m~ + displaying the =Magit= dispatch popup ++ =git-link= key bindings have been moved from ~SPC g h~ to ~SPC g l~ since + it provides support for other Git hosting services (not only GitHub) + - ~SPC g l c~ on a commit hash, browse to the current file at this commit + - ~SPC g l C~ on a commit hash, create link to the file at this commit + and copy it + - ~SPC g l l~ on a region, browse to file at current lines position + - ~SPC g l L~ on a region, create a link to the file highlighting the + selected lines ++ New key binding ~SPC g f h~ to get the commit history of the current file +**** GitHub +- Add support for =git-link= in =git-timemachine=, this allow to copy + the SHA-1 or selected lines links for the current commit (thanks to dcluna) +- Move clone commands under ~SPC g h c~: + - ~SPC g h c /~ search for a repository to clone it + - ~SPC g h c c~ clone and optionally fork repository + - ~SPC g h c r~ add a remote that is an existing fork of selected remote + - ~SPC g h c f~ fork remote in current user namespace + - ~SPC g h c u~ add upstream as remote +**** Go +- New layer variable =go-tab-width= (thanks to microamp) +- New key binding ~SPC m g c~ to open a clone of the current buffer with a + coverage info (thanks to JAremko) +- Add support for =gometalinter= via new layer variable + =go-use-gometalinter= (thanks to JAremko) +- Improve indentation (thanks to bogdanteleaga) +- Show function signatures (thanks to carlosgaldino) +**** Graphviz +- Add support for =org-babel= (thanks to choppsv1) +**** Gtags +- Refactoring of the layer to support more languages (thanks to choppsv1 and + TheBB) +- New layer variable =gtags-enable-by-default= to control whether =gtags-mode= + should be enabled by default or not (thanks to TheBB) +- New key binding ~SPC m g D~ to navigate to definition in another window + (thanks to NJBS) +- Remove =helm-gtags= lighter from mode line (thanks to NJBS) +**** Haskell +- New layer variable =haskell-completion-backend= to select the desired + completion backend (thanks to d12frosted) +- Add package =intero= (based on cydparser layer) (thanks to d12frosted) +- Add package =helm-hoogle= under ~SPC m h f~ (thanks to jb55) +- Add package =hlint-refactor= (thanks to cydparser) +- Add package =company-ghci= (thanks to dysinger) +- Add all =haskell-mode= key bindings to =literate-haskell-mode= + (thanks to jb55) +- Add support for =intero-apply-suggestions= (thanks to Tehnix) +- Swap key bindings ~SPC m F~ and ~SPC m f~ (thanks to ljli) +- Evilify =haskell-debug-mode= (thanks to d12frosted) +- Fix ~SPC m h i~ and ~SPC m h t~ key bindinds (thanks to d12frosted) +- Disable =haskell-tags-on-save= by default (thanks to bgamari) +- Remove =structured-haskell-mode= because of poor integration (thanks to + d12frosted) +- Remove =ghci-ng= support (thanks to d12frosted) +**** Helm +- Rename action =Add layer= to =Install layer= in =helm-spacemacs-help= + (thanks to CestDiego) +- Fix =helm-source-header= face not updating when changing themes + (thanks to ghoot) +- Enable fuzzy matching in all Helm sources (thanks to bling) +**** Html +- Add prefix command names (thanks to shanavas786) +- Use built-in =web-mode= pairing (disable =smartparens=) (thanks to TheBB) +- Enable =emmet-mode= in sass and scss modes (thanks to utkarshkukreti) +- Make =pug= files use =jade-mode= since Jade is now called Pug + (thanks to robbyoconnor) +- Fix =emmet= expansion if =yasnippet= isn’t turned on (thanks to TheBB) +**** Idris +- New key binding ~SPC m l~ for extracting lemma (thanks to bixuanzju) +- New key binding ~SPC m c~ for =idris-case-dwim= (thanks to bixuanzju) +- New key binding ~SPC m s q~ to quit the Idris process (thanks to bixuanzju) +- Register Idris REPL for ~SPC a '~ (thanks to bixuanzju) +- Add basic auto-completion (thanks to bixuanzju) +- Add support for =golden-ration= for *idris-holes* and *idris-info* + (thanks to houli) +- Add prefix command names (thanks to bixuanzju) +- Enhance =auto-completion= support for Idris layer, now =auto-completion= + will ask Idris process for completions (thanks to bixuanzju) +- Enable =auto-completion= in REPL (thanks to bixuanzju) +- Disable =golden-ratio= in holes buffer (thanks to houli) +**** IPython-notebook +- Move transient state key binding to ~SPC m .~ +- Evilify notebooklist buffer +- Fix loading of keymap (thanks to TheBB) +**** Jabber +- Add support for evilified key bindings (thanks to mssun) +- Don't overwrite mini-buffer when active (thanks to toshism) +**** Java +- Add support for =eclimd= with new key bindings: + - ~SPC m d s~ to start daemon + - ~SPC m d k~ to stop daemon + (thanks to elken) +**** JavaScript +- Add REPL via =skewer-mode= and =livid-mode= (thanks to dcluna) +- Fix offset detection in js2-mode (thans to TheBB) +- Diminish =tern= and =skewer= modes (thanks to cpaulik) +**** LaTeX +- Add prefix command names (thanks to NJBS) +- New key bindings for fill and uncomment: + - ~SPC m %~ to comment or uncomment a paragraph + - ~SPC m ;~ to comment or uncomment a region + - ~SPC m f e~ to fill LaTeX environment + - ~SPC m f p~ to fill LaTeX paragraph + - ~SPC m f r~ to fill LaTeX region + - ~SPC m f s~ to fill LaTeX section + (thanks to kccai) +- New key binding ~SPC m a~ for =TeX-command-run-all= (thanks to kccai) +**** Markdown +- New layer variable =markdown-live-preview-engine=, Possibe values are =eww= + (built-in browser) or =vmd= (installed with =npm=) +- Add package =vmd-mode= (thanks to bixuanzju) +- New key binding ~SPC m c P~ to live preview in Emacs' built-in browser + (thanks to lunaryorn) +**** mu4e +- Add package =mu4e-maildirs-extension= (thanks to choppsv1) +- Add package =mu4-alert= (thanks to zakkak) +- New key bindings: + - ~J~ to go to next unread thread marking other mail read on the way + - ~C-j~ to go to next header + - ~C-k~ to go to previoys header + (thanks to myrjola) +- Enable =org-mu4e= (thanks to choppsv1) +- Use =helm--completing-read-default= (thanks to jeizsm) +- Improve set account by "to" field (thanks to sorpaas) +**** OCaml +- New key binding ~SPC m = ~ to indent buffer with =ocp-indent= (thanks to NJBS) +- New key binding ~SPC m g o~ to list occurrences for identifier under point + (thanks to NJBS) +- Add support for =ocamllex= , =ocamlyacc= files (thanks to YasuharuIida) +- Remove key binding =merlin-refresh=, this function is obsolete since merlin + 2.0 (thanks to bixuanzju) +- Remove unused =flycheck= config, merlin is capable of doing it + (thanks to bixuanzju) +- Fix override of =exec-path= by =utop= configuration (thanks to bixuanzju) +**** Org +- Add package =org-reveal= (thanks to knl) +- Add local package =space-doc-mode= to improve org files readability + (thanks to JAremko) +- Add support for =org-babel= +- Replace =org-repo-todo= by =org-projectile= (thanks to TheBB) +- New layer variable =org-projectile-file= to set the filename where you want + to store project-specific TODOs. +- New key bindings for =org-agenda=: + - ~RET~ for =org-agenda-goto= + - ~M-RET~ for =org-agenda-show-and-scroll-up= + - ~SPC m a~ for =org-agenda= + - ~SPC m d~ for =org-agenda-deadline= + - ~SPC m s~ for =org-agenda-schedule= + - ~SPC m f~ for =org-agenda-set-effort= + - ~SPC m P~ for =org-agenda-set-property= + - ~SPC m :~ for =org-agenda-set-tags= + - ~SPC m I~ for =org-agenda-clock-in= + - ~SPC m O~ for =org-agenda-clock-out= + - ~SPC m q~ for =org-agenda-clock-cancel= + - ~SPC m q~ for =org-agenda-refile= +- New key bindings for =org-calendar=: + - ~M-l~ One day forward + - ~M-h~ One day backward + - ~M-j~ One week forward + - ~M-k~ One week backward + - ~M-L~ One month forward + - ~M-H~ One month backward + - ~M-J~ One year forward + - ~M-K~ One year backward +- New key binding ~SPC m h s~ for =org-insert-subheading= (thanks to jgertm) +- =org-indent= is now turned off by default because of the numerous glitches + (thanks to TheBB) +- Add code blocks support for =evil-surround= using ~:~ and ~#~ + (thanks to TheBB) +- Set =org-imenu-depth= to 8 (thanks to justbur) +- set =org-image-actual-width= to nil which allows to resize images in an org + buffer. +- Follow the confirm and abort conventions (thanks to myrjola) +**** OSX +- Add package =osx-dictionary= (thanks to nixmaniack) +- New layer variable =osx-use-dictionary-app= to use OS X dictionary app + instead of wordnet. Default value is =t=. (thanks to nixmaniack) +- Support pasting text with ~s-v~ in terminals (thanks to lyallcooper) +**** NixOS +- Add =nix-mode= to variable =spacemacs-indent-sensitive-modes= to disable + automatic indentation on pasting text (thanks to Profpatsch) +**** Pdf-tools +- New key bindings ~0~ and ~$~ to full left and right scroll + (thanks to Andre0991) +- New key binding ~zr~ to reset zoom factor (thanks to Andre0991) +**** Puppet +- Use =ruby-mode= for Puppetfile support (thanks to nwolfe) +**** Purescript +- Add package =flycheck-purescript= (thanks to diogob) +- New key binding ~SPC m g g~ (thanks to kRITZCREEK) +- Incorporate new functionality from =psc-ide=: + - New layer variable =purescript-add-import-on-completion= to add imports on + completion. Default value is =t=. + - New layer variable =purescript-enable-rebuild-on-save= to get a popup buffer + showing you your current warnings/errors one at a time. This is primarily + meant as an alternative to using flycheck. Default value is =nil=. + - New =psc-ide= key bindings: + - ~SPC m m b~ to rebuilds the current file and displays any warnings or + errors + - ~SPC m m i a~ to add an import for the identifier at the current cursor + position + - ~SPC m m i s~ to inserts a suggestion for the warning/error at the current + cursor position + - ~SPC m m t~ to add a new clause for the function signature at point + - ~SPC m m c s~ to casesplits on the identifier at the current cursor + position + - ~SPC m m q~ to quit the current psc-ide-server + - ~SPC m m L~ to load a specific module + (thanks to kRITZCREEK) +- Fix org layout if there is no agenda files and display an error message + (thanks to TheBB) +**** Python +- Add package =live-py-mode= (thanks to cpaulik) +- Add package =py-isort= to sort the imports (thanks to swaroopch) +- Add support for =org-babel= +- Replace package =py-yapf= with =yapfify=. =Yapfify= uses project settings + applicable to the file that yapf is called on. Also it shows an error if + =yapf= fails (thanks to JorisE) +- New layer variable =python-sort-imports-on-save=, if non-nil, automatically + sort imports on save. Default value is =nil= (thanks to swaroopch) +- New key binding ~SPC m r I~ to sort imports with =isort= python package + (thanks to TheBB) +- New key bindings to manage virtual environments: + - ~SPC m V a~ to activate a virtual environment in any directory + - ~SPC m V d~ to deactivate the active virtual environment + - ~SPC m V w~ to work on virtual environment in ~WORKON_HOME~ + (thanks to cpaulik) +- New key binding ~SPC m g b~ for =anaconda-mode-go-back= (thanks to jluttine) +- Add support for a lisp REPL in =hy= buffers (thanks to dannyfreeman) +- Add support for =pyenv= in =hy= buffers (thanks to dannyfreeman) +- Add support for =smartparens= in =hy= buffers (thanks to dannyfreeman) +- Fix =pylookup= key binding ~SPC m h H~ (thanks to darkfeline) +- Fix IPython 5 integration and make it work with =pyenv= (thanks to cpaulik) +- Make =pylookup= use std =completing-read= function (thanks to darkfeline) +- Make =pylookup.py= compatible with Python 2 and 3 (thanks to hemcsec) +- Enable lazy loading of =py-yapf=. +- Only disable =semantic-idle-summary= if =anaconda-mode= is used + (thanks to cpaulik) +- Set =comment-inline-offset= to 2 for =python-mode= Since python's PEP8 + recommends two spaces for inline spaces (thanks to xiaohanyu) +- Set breakpoints correctly when =pyenv= is used (thanks to cpaulik) +**** React +- Add support for =smartparens= (thanks to axyz) +- Add "^import React" to =magic-mode-alist= (thanks to axyz) +- Add =javascript-standard= as a =flycheck= checker (thanks to shahinism) +- Use node_modules version of eslint or global if not available (thanks axyz) +**** Restclient +- Add package =ob-http=. +- New key binding ~SPC m y~ to copy the query around point as a =curl= command + (thanks to d1egoaz) +**** Ruby +- Add package =rake= with key bindings: + - ~SPC m k k~ to runs rake + - ~SPC m k r~ to re-runs the last rake task + - ~SPC m k R~ to regenerates the rake cache + - ~SPC m k f~ to finds definition of a rake task + (thanks to asok) +- New =rspec= key binding ~SPC m t ~~ for + =rspec-toggle-spec-and-target-find-example= (thanks to asok) +- New =rspec= key binding ~SPC m t TAB~ for =rspec-toggle-spec-and-target= + (thanks to asok) +- New =rspec= key binding ~SPC m t d~ to run rspec in a specified directory + (thanks to dcluna) +- New key binding ~SPC b o~ to run bundle open (thanks to asok) +- Add =popwin= configuration to =*rake-compilation*= (thanks to nixmaniack) +- Add support for =Appraisals= files (thanks to jcf) +- Fix =chruby= configuration to find out the ruby version to use (thanks to asok) +- Enter automatically =inf-ruby-mode= when an =rspec= compilation hits a + breakpoint (thanks to dcluna) +**** Ruby on Rails +- Add =which-key= prefixes (thanks to ralesi) +**** Rust +- Remove layer variable =rust-enable-racer=, now =racer= is always used + (thanks to fbergroth) +- Remove package =company-racer= since =racer= works with default + =company= backends (thanks to fbergroth) +- Remove obsolete package =rustfmt= which has been integrated into =rust-mode= + (thanks to fbergroth) +- Remove =racer= lighter in the mode line (thanks to NJBS) +- New layer variable =rust-enable-rustfmt-on-save= (thanks to isphinx) +- New package =rustfmt= with new key binding ~SPC m =~ to format the buffer + (thanks to isphinx) +- New key binding ~SPC m c f~ to format all project files with =rustfmt= + (thanks to dmit) +- Add support for =Cargo.lock= and =.cargo/config= files for =toml-mode= + (thanks to Stebalien) +**** Scala +- Add support for =org-babel= (thanks to tonylotts) +- New layer variable =scala-use-unicode-arrows= to replace ASCII arrows + with unicode ones (thanks to moonranger) +- Enable lazy loading of =sbt-mode=. +- Disable Ensime autostart (thanks to d1egoaz) +- Use scala-mode instead of scala-mode-2 which is deprecated + (thanks to j-martin) +- Fix dot completion bug (thanks to gilbertw1) +**** Search-engine +- Denote all search functions as autoloadable (thanks to TheBB) +**** Shell +- New =eshell-z= package (thanks to CestDiego) +- New layer variable =shell-default-full-span=, if non-nil, the shell buffers + span full width of a window (thanks to dubnde) +- New key binding ~SPC p '~ for =projectile-shell-pop= (thanks to StreakyCobra) +- ~C-d~ is now bound to =eshell-delchar-or-maybe-eof= which checks if there is + a char after the point. If so, it performs the normal delete-char, + otherwise if quit eshell (thanks to microamp) +- Add support for the universal prefix argument to open a shell/term buffer in + the current window instead of a new window (i.e. ~SPC u SPC '~) +- Add support for =org-babel= +- Fix first =eshell= with no color (thanks to TheBB) +- Fix =projectile-multi-term-in-root= (~SPC p $ t~) (thanks to TheBB) +- Enable auto-jump to end of buffer in hybrid style (thanks to TheBB) +- Disable =global-hl-line-mode= in =shell-like= buffers (thanks to TheBB) +**** Shell-scripts +- Add package =company-shell= (thanks to joehillen) +- Enable =flycheck= in =sh-mode= (thanks to fbergroth) +- New key binding ~SPC m \~ for =sh-backslash-region= to add a backslash at + end of lines (thanks to fbergroth) +**** SML +- Improve indentation by binding ~RET~ to =reindent-then-newline-and-indent= + (thanks to cpaulik) +**** Spell-checking +- Use package =flyspell-correct= instead of =helm-flyspell= + (thanks to d12frosted) +- Add package =flyspell-popup= (thanks to usharf) +**** Spotify +- Enable lazy loading +**** Syntax-checking +- New key binding ~SPC e L~ to open the errors buffer and switch to it. +- Improve =flycheck= loading process (thanks to TheBB) +- Enable lazy loading of =flycheck=. +- Don't switch to =error-list= window if already on it (thanks to bmag) +- Fix bug where errors are not filtered correctly when setting + =flycheck-navigation-minimum-level= (thanks to maxigit) +**** Themes-megapack +- Add theme =Darkokai= (thanks to ekmecic) +**** Tmux +- Fix =golden-ratio= (thanks to TheBB) +**** Typescript +- Rewrite of the layer, see its =README.org= for more info (thanks to JAremko) +- New key binding ~SPC m s p~ to send region or buffer to the web playground + (thanks to JAremko) +- Add typescript format and make tide formatter the default (thanks to JAremko) +- Add support for =evil-shift-width= (thanks to TheBB) +- Allow =tsfmt= to use the local project's configuration (thanks to overminder) +- Swap ~C-j~ and ~C-k~ in tide reference mode (thanks to zilongshanren) +**** Version-control +- Fix git gutter toggle (thanks to ralesi) +- Fix errors with graphical elements in daemon mode (thanks to TheBB) +**** Vim-unimpaired +- Keep the point at the same location when calling + =evil-unimpaired/insert-space-above= and =evil-unimpaired/insert-space-below= + (thanks to jschaf) +- New key bindings ~] q~ and ~[ q~ for =spacemacs/next-error= and + =spacemacs/previous-error= (thanks to bling) +**** Windows-scripts +- Add support for =.cmd= and =.psm1= files (thanks to ralesi) +**** Yaml +- Fix auto-completion (thanks to perfectayush) +*** Core Changes +- Refactor layer system to allow a 20~25% performance boost on startup. +- Move bootstrap packages from =core-spacemacs.el= to a new layer called + =spacemacs-bootstrap=. +- Checking for new version on startup behavior has been tweaked to lower the + frequency on the checks and reduce the number of operations made: + - reduce number of required git commands per check from 3 to 1 + - remove recurrent version check every 6 hours, i.e. the check happens only + at startup + - rate limit the checks to once per day + - change default value of variable =dotspacemacs-check-for-update= to =nil= + - make function =spacemacs/check-for-new-version= interactive so checking + for a new version can be done on demand. +- New macro =spacemacs|define-jump-handlers= to define jump backends for a given + mode (thanks to TheBB) +- Implement an API for =local-vars-hook= which allows to read some directory + local variables before executing an hooked function (thanks to d12frosted) +- Make function =spacemacs/get-last-version= interactive +- New file in layers called =layers.el=, this file is responsible to declare + layer dependencies. +- New variable =spacemacs-start-directory=. With this new variable, user can + easily load spacemacs anywhere (thanks to exaos) +- New variable =spacemacs-default-company-backends= which allow the user to + fine tune the default company backends inherited by all the modes + (thanks to izahn) +- New command line parameters =--no-layer= and =--distribution= + - =--no-layer= deactivates all the layers except the distribution layer + - =--distribution= allows to change temporarily the distribution +- New funtion =spacemacs/report-issue= to create GitHub issues from within + Emacs based on a template (thanks to dwang20151005) +- New functions =configuration-layer/remove-layer= and + =configuration-layer/remove-layers=. +- New function =spacemacs/describe-package= giving useful information on a + package in the Spacemacs layers context (key binding ~SPC h d P~) +- New keyword =:toggle= for package lists =-packages=. Its value can be a + symbol or a list. A package is considered to be used if the toggle evaluates + to non nil. By default =:toggle= is =t=. +- New keyword =:min-version= for package lists =-packages=. Providing a + min-version allows to fetch the elpa version of a built-in package. +- New value =bootstrap= for package =:step= keyword, it is used for bootstrap + packages. +- New value =site= for package =:location= keyword, a site package is a package + installed on the host by a third party (ie. =mu4e= which is installed by =mu=) +- New documentation formatting tool =doc-fmt= (thanks to JAremko) +- New keywords for =spacemacs|add-toggle= macro: + - =:prefix= a symbol that is bound to the raw prefix argument + (as in =(interactive "P")= forms). + - =:on-message= an expression overriding the default 'on' toggle + message (useful to document a toggle's argument) + - =:mode= a minor mode, when provided, =:on=, =:off= and =:status= are + automatically defined to support the minor mode. + (thanks to dcluna and TheBB) +- Print toggles messages only when the toggle functions are used interactively + (thanks to bmag) +- Add =Quelpa= support for local packages which means that local packages can be + installed like any other ELPA package (thanks to d12frosted) +- Add footer in home buffer +- Add support for functions for =:status= in =spacemacs|add-toggle= + (thanks to TheBB) +- Add support for themes =omtose-darker= and =omtose-softer= (thanks to Cifer-Y) +- Update base16 themes to match new list (thanks to belak) +- Add emojis to issue template (thanks to CestDiego) +- Remove variable =user-dropbox-directory= +- Center spacemacs banner in window at startup (thanks to ralesi and deb0ch) +- Center ascii banners in window at startup (thanks to deb0ch) +- Display warning buffer at the bottom of the screen when installing packages. +- Display more information about the number of loaded packages in the home + buffer: + - =e= elpa + - =r= recipe + - =l= local + - =b= built-in +- Display a numerical progression in mode-line representing the number of + packages to configure. +- Display a warning message when a non-excluded package has no pre-init, init + or post-init function in a layer. +- Merge version strings into one string displayed in the left-hand side: + =spacemacs-version@emacs-version (distribution)= +- Improve =spacemacs|diminish= function (thanks to TheBB) +- Use =$SPACEMACDIR/init.el= instead of =~/.spacemacs= when both exist + (thanks to bmag) +- Fix font definition for first frame in daemon mode (thanks to StreakyCobra) +- Fix message format in =init.el= (thanks to YasuharuIida) +- Fix random banner display when closing and reopening the home buffer + (thanks to TheBB) +- Fix home buffer random banner choice (thanks to deb0ch) +- Fix =.gitignore= file to enable submodule update (thanks to jgmize) +- Optimize function =spacemacs//get-package-directory= (thanks to ivanbrennan) +- Improving performance by avoiding to visit dump files in function + =spacemacs/dump-vars-to-file= (thanks to bmag) +*** Other fixes and improvements +- Fix all documentation links on GitHub (thanks to JAremko) +- Improve Spacemacs themes readability of highlight-persist and smartparens + overlays when there is an active region (thanks to nashamri) +- Typos and documentation improvements (thanks to adrsta, Andre099, 1andreas-h, + axyz, balajisivaraman, benansell, bmag, brettcannon, cpaulik, ChuntaoLu, + d12frosted, d1egoaz, darkfeline, dathinaios, deb0ch, Dominionized, duianto, + eapolinario, eareese, jfchevrette, gilch, hasufell, hghwng, ivanbrennan, + jgertm, jkrmr, johankj, Johnstone-Tech, jonboiser, jpfairbanks, jschnurr, + kalouantonis, Karunamon, krobelus, li-xinyang, loxaxs, lzhoucs, madand, + Marlin-Na, mathcass, maxigit, microamp, nashamri, NJBS, ohspite, + pablooliveira, padi, paulyoung, rbanffy, robbyoconnor, robert-m-johnson, + roryokane, royxue, sbdchd, sebastianpoeplau, shanavas786, sooheon, splaspood, + StreakyCobra, svanburen, taheris, tchajed, TheBB, tj64, tko, tonylotts, + trenpixster, voidlily, WillianPaiva, WuTheFWasThat, xiaohanyu, xfq, zifeo, + zjyjer) +- Other contributions (thanks to hujianxin, nixmaniack) +*** Core team members +**** Current +- Sylvain Benner (syl20bnr) +- Boris (d12frosted) +- Eivind Fonn (TheBB) +**** Old +- Fabien Dubosson (StreakyCobra) +- Justin Burkett (justbur) +* Release 0.105.x +** 0.105.22 (2016/08/19) +*** Fixes +- Rename the =emacs-eclim= package to =eclim= (thanks to CestDiego) +** 0.105.21 (2016/06/08) +*** Fixes +- Fix hybrid state when escaping to normal state +- Fix installation instructions on OS X (thanks to d12frosted) +- Fix broken =vinegar= key bindings +- Fix =tmux= layer (thanks to aaronjensen) +- Fix =scala= layer + - Use =scala-mode= instead of =scala-mode2= (thanks to j-martin) + - Fix =sbt= command to generate =ensime= configuration (thanks to d1egoaz) +** 0.105.20 (2016/05/10) +*** Fixes +- Update Spaceline configuration for new version +** 0.105.19 (2016/04/20) +*** Fixes +- Fix =dired-x= autoload (thanks to darkfeline) +- Fix ~SPC f y~ in =dired= buffers (thanks to dcluna) +- Fix ~C-i~ key binding for =evil-jump-forward=. +- Fix ~SPC q r~ to restart Emacs and restore Spacemacs layouts. +- Fix go to next/previous error when a compilation buffer is opened + (thanks to dennishamester) +- Fix error when opening =spacemacs-helm= with unknown org documentation + files (thanks to kuangdash) +- Fix wrong states when exiting =evil-lisp-state= and =evil-iedit-state= + while using the =emacs= editing style. +- Fix ASCII banners first line being overwritten by the version numbers +- Use MELPA version of =persp-mode=, the package may need to be deleted + manually from the =elpa= directory and a restart of Emacs may be + required. +- Discover layers before running dotfile tests when reloading the + configuration, prevents false negatives (thanks to TheBB) +- Remove duplicated configuration for =eldoc= (thanks to zilongshanren) +*** Layer changes +**** Clojure +- Fix usage of deprecated =cider-turn-on-eldoc-mode=, using =eldoc-mode= + instead (thanks to tekacs and sooheon) +**** Elm +- Fix text copy/paste +- Fix auto-completion +**** Javascript +- Improve detection of =tern= binary, if =tern= is not found a message + is displayed in the =*Messages*= buffer (thanks to nixmaniack) +**** Go +- Fix execution of tests with function names containing underscores + (thanks to jaffee) +**** Python +- Use MELPA version of =py-yapf= package (thanks to cpaulik) +- Fix =makefile= of =pylookup= (thanks to hemcsec) +- Disable =semantic-idle-summary= which obfuscates =anaconda= information + in the minibuffer (thanks to cpaulik) +**** Scala +- Fix =ensime-typecheck-current-file=, rename it to + =ensime-typecheck-current-buffer= +- Fix =scala-enable-eldoc-mode=, rename it to =scala-enable-eldoc= + (thanks to channingwalton) +**** Shell +- Fix error when attempting to delete the last shell window + (thanks to joelmccracken) +**** Tmux +- Fix loading of package (thanks to aaronjensen) +**** Vinegar +- Correct =dired= configuration (thanks to StreakyCobra) +*** Improvements +- Various documentation improvements (thanks to d12frosted, gilch, ksrb, + nixmaniack, StreakyCobra, TheBB, The-Compiler, xiaohanyu) +** 0.105.18 (2016/04/10) +- Revert hotfix for =Yasnippet=, the bug has been fixed upstream and is now + available in MELPA (thanks to TheBB) +- Remove obsolete package =evil-jumper= which is now part of =evil= + (thanks to justbur) +** 0.105.17 (2016/04/09) +- Hotfix for Yasnippet, using stable version until resolution of + https://github.com/capitaomorte/yasnippet/issues/673 +** 0.105.16 (2016/04/01) +- Add FAQ entry about HTTPS issues (thanks to TheBB) +- Add startup list to Zemacs home buffer. +** 0.105.15 (2016/04/01) +*** Improvements +- Emacs to THE MAX! Release of Zemacs! +*** Layer changes +**** Javascript +- New layer variable =javascript-disable-tern-port-files=, when non nil + tern port files are not created. Default value is nil. (thanks to mijoharas) +**** Swift +- Fix all =swift= major-mode key bindings (thanks to xinranmsn) +** 0.105.14 (2016/03/09) +*** Fixes +- Fix bad window index for =neotree= buffer (thanks to bmag) +- Fix error when using ~SPC p l~ right after Emacs started (thanks to bixuanzju) +*** Layer changes +**** Go +- Fix bug when there is no test suite when running tests + (thanks to bogdanteleaga) +**** React +- Fix broken =helm-imenu= (thanks to huaoguo) +*** Improvements +- Various documentation improvements (thanks to triklsbg) + +** 0.105.13 (2016/03/06) +*** Fixes +- Fix smooth-scroll toggling at startup (thanks to TheBB) +- Fix auto-completion toggle ~SPC t a~ (thanks to TheBB) +*** Layer changes +**** Clojure +- Fix function name =cider-pop-back= (thanks to mlachmih) +**** Scala +- Fix various function names: + - =ensime-refactor-diff-organize-imports= + - =ensime-refactor-diff-extract-method= + - =ensime-refactor-diff-rename= + - =ensime-refactor-diff-extract-local= + (thanks to TheBB) +*** Improvements +- Reformat =README.md= title section. +- Add a GitHub pull request template (thanks to robbyoconnor) +** 0.105.12 (2016/03/02) +*** Fixes +- Fix activation of package dependencies +- Fix =smooth-scrolling= error due to recent changes in package repository +*** Layer changes +**** Distribution +- New key binding ~SPC t v~ to toggle smooth scrolling. +**** C-C++ +- Add notes on related layers (thanks to magthe) +- Remove srefactor from static package list (thanks to magthe) +- Set paths for C headers from clang (thanks to magthe) +**** Evil-snipe +- Disable =evil-snipe= in =ranger= (thanks to TheBB) +**** Haskell +- Fix bad indentation when pasting text (thanks to robbyoconnor) +**** Markdown +- Add support for =rust= code blocks (thanks to panicbit) +**** Org +- Fix custom Spacemacs layout when =org-agenda-files= isn't a list. + The org-agenda-files variable can be the name of a directory or a file. + (thanks to jmiven) +**** Osx +- Fix =osx-use-options-as-meta= for Emacs 25 (thanks to d12frosted) +**** React +- make =evil-matchit= jump between html/jsx tags (thanks to tko) +**** Racket +- Add command prefix names for =racket-mode= key bindings + (thanks to rodrigosetti) +**** Scala +- Rename =ensime-refactor-inline-local= to =ensime-refactor-diff-inline-local= + (thanks to chessman) +**** Shell +- Fix reverse key bindings for comint-previous/next (thanks to olejorgenb)) +- Scope the aliases under =eshell= so they are not defined globally + (thanks to bling) +**** Themes megapack +- Add =railscasts-theme= (thanks to olsonjeffery) +*** Improvements +- Improve =toggle-maximize-centered-buffer= (thanks to justbur) +- Add =display-graphic-p= to ~SPC h d s~ (thanks to TheBB) +- Various documentation improvements (thanks to d12frosted, davbo, marcopaga, + microamp, nixmaniack, NJBS, SShrike, TheBB, Tinche, triklsbg, xfq) +** 0.105.11 (2016/02/18) +Improve loading robustness: +- When an ELPA repository is down Spacemacs will now be able to finish loading +- Spacemacs will use the default theme (i.e. no theme) if there is any error + during the download of the starting theme. +** 0.105.10 (2016/02/18) +*** Fixes +- Fix re-toggle of fullscreen when pressing ~SPC f e R~ (thanks to MadAnd) +- Fix display of recent bookmarks without filename (thanks to lislon) +- Fix =toggle-maximize-buffer= (thanks to justbur) +- Remove files from rollback slot list (thanks to microamp) +- Don't catch errors while loading if =--debug-init= is provided. +- Don't change scratch major mode if buffer exists (thanks to TheBB) +- Restore windows layout when quitting =ediff= (thanks to fbergroth) +- Ensure that =pcache-directory= ends in a slash (thanks to rpglover64) +- Ensure new Spacemacs layouts only shows home buffer (thanks to bmag) +*** Improvements +- Add a bug report template for GitHub issues on ~SPC h I~ + (thanks to StreakyCobra) +- Add files used by =eww= to =.gitignore= (thanks to ahyatt) +- Various enhancements for themes handling (thanks to TheBB) +- Allow =default= theme (no theme) to be defined in =dotspacemacs-themes= + (thanks to izahn) +- Add support for missing =base16= themes (thanks to curtmack) +- Update recent files list when a file is renamed (thanks to lislon) +- Improve frame-fullscreen and maximize-frame toggles (thanks to MadAnd) +- Diminish relative line numbers lighter in mode-line (thanks to peterhoeg) +- Various documentation improvements (thanks to balajisivaraman, crododile, + darkfeline, ernestas, franciscoj, j4, kRITZCREEK, nixmaniack, numkem, + robbyoconnor, TheBB, tonylotts) +*** Layer changes +**** Auto-completion +- Better choice of =company= front-ends (thanks to fbergroth) +**** C-C++ +- Get =clang= args even if =flycheck= isn't installed (thanks to TheBB) +**** Clojure +- Fix renamed =cider-test-run-tests= function (thanks to AlejandroCatalina) +- Substitute =align-cljlet= with =clojure-align=. =align-cljlet= was deprecated + in favour of the vertical alignment in the clojure-mode package (thanks to + vise890) +**** Elm +- Fix =flycheck= not working on sub-directories (thanks to AlejandroCatalina) +**** ERC +- Fix initialisation of =erc-terminal-notifier= (thanks to Andre0991) +**** Gnus +- Remove =gnus-fetch-old-headers= customization which was causing slowdown + while consulting some newsgroups (thanks to StreakyCobra) +**** Haskell +- Fix broken =hoogle-lookup-from-local= (thanks to jb55) +**** Html +- Remove =.jsx= from =web-mode= auto mode alist (thanks to lunaryorn) +**** Org +- Remove ~H~ and ~L~ key bindings from =evil-org= (thanks to choppsv1) +**** Python +- Add missing =py-yapf= configuration (thanks to TheBB) +- Enable =anaconda-eldoc-mode= (thanks to TheBB) +- Only load =pyenv= if it is installed (thanks to cpaulik) +**** Racket +- Disable =company-quickhelp-mode= only when it is already enabled + (thanks to syohex) +**** React +- Disable auto-quote of attributes (thanks to TheBB) +- Fix react magic mode, it will now recognize =/** @jsx React.DOM */= in the + first line of a file (thanks to EMayej) +**** Ruby +- Use =popwin= for =rspec= compilations (thanks to joshcass) +- Do not force =rspec-mode= on ruby files (thanks to morhekil) +**** Rust +- Fix indentation setting for =evil-shift-width= (thanks to Stebalien) +**** Shell +- Set the correct shell-pop size variable (thanks to TheBB) +**** Themes-megapack +- Add =dracula= theme (thanks to MarkRedeman) +- Add =omtose-phellack= theme (thanks to duien) +- Add =majapahit= theme (thanks to kostajh) +**** Tmux +- Fix key bindings ~C-h~, ~C-j~, ~C-k~ and ~C-l~ (thanks to justbur) +**** Vagrant +- New key binding ~SPC V R~ to reload to restart VMs (thanks to kostajh) +**** Version control +- Fix bugs due to wrong mode for =diff-hl= margin (thanks to abaw) +- Fix =git-gutter= linum setup (thanks to person808) +**** Wakatime +- Fix wakatime-dashboard url (thanks to hallfox) +** 0.105.9 (2016/01/17) +*** Improvements +- Fix error on Microsoft Windows 10 OS regarding missing =printf= command + (don't call =exec-path-from-shell= function on Microsoft Windows) + (thanks to syohex) +- New key bindings ~C-e~ and ~C-y~ in evilified buffers to scroll lines + (thanks to CestDiego) +- Remove key binding hack for =evil-jumper= since the issue has been fixed + upstream (thanks to justbur) +- Remove unused =init-dired+= function (thanks to AlejandroCatalina) +- Various documentation improvements (thanks to balajisivaraman, jcppython, + jmiven, jorisE) +*** New conventions +- =use-package= code guidelines +- Key bindings documentation only need to mention ~SPC~ prefix +*** Layer changes +**** Markdown +- Add syntax highlighting for =R= code blocks (thanks to rustyplanet) +**** Org +- Fix early creation of empty =org= directory (thanks to tboby) +- Add default key binding ~C-c c~ for =org-capture= + (thanks to AlejandroCatalina) +**** Spacemacs +- Add =bracketed-paste= package to improve pasted text in terminals + (thanks to AlejandroCatalina) +** 0.105.8 (2016/01/12) +*** Fixes +- Fix the red mode-line when error occurs during loading +- Fix and improve layer templates and layer creation (thanks to chrisbarrett) +- Fix and simplify copyrights in file headers +- Fix =.gitignore= pattern for =private= directory (thanks to jballanc) +*** Improvements +- New key binding ~SPC h d l~ to describe the last key pressed, useful + when reporting a bug (thanks to StreakyCobra) +- Sort alphabetically the list of package to be update on the home buffer +- Improve =describe-system-info= function with completion engine info + (ivy completion engine will be available in 0.106) (thanks to StreakyCobra) +- Add link to =BountySource= page to =README.md= (thanks to houli) +- Move =request= storage folder to =.cache= directory +*** Layer changes +**** Markdown +- Add support for javascript code blocks syntax highlighting + (thanks to AlejandroCatalina) +** 0.105.7 (2016/01/11) +*** Fixes +- Fix missing ~q~ key binding in the home buffer introduced in =0.105.5= + (thanks to justbur) +**** ERC and RCIRC layers +- Properly add all opened buffers to custom layouts + (thanks to AlejandroCatalina) +**** Go layer +- Prevent from clobbering environment variables if already set (thanks to whilp) +**** Haskell +- Remove reference to undefined function =haskell-cabal-hook= + (thanks to chrisbarrett) +**** Python layer +- Fix errors when reading =.python-version= files (thanks to fbergroth) +*** Dotfile changes +- New variable =dotspacemacs-scratch-mode= to configure the default major-mode + for the scratch buffer, default value is =text-mode= (thanks to TheBB) +*** Improvements +- Display a list of packages to update when pressing the =[Update packages]= + in the home buffer +- Add highlight of TODOs in text mode files (thanks to StreakyCobra) +- Various documentation improvements (thanks to StreakyCobra, TheBB) +** 0.105.6 (2016/01/09) +*** Fixes +- Fix shadowed ~TAB~ (~C-i~) key in terminal (thanks to StreakyCobra) +** 0.105.5 (2016/01/08) +*** Fixes +**** Core +- Fix unavailable major mode leader keys in =evilified= buffers + (thanks to justbur) +- Fix ~b~ key binding on home buffer (thanks to justbur) +*** Layer changes +**** Spacemacs +- Bind =evil-jumper/forward= to == to make it work when + =dotspacemacs-distinguish-gui-tab= is non nil (thanks to TheBB) +**** Auto-completion +- Add =~/.spacemacs.d/snippets= directory to the snippet sources of + yasnippet. +- Don't enter =evil-insert-state= after =aya-expand= when =holy-mode= if active + (thanks to abaw) +** 0.105.4 (2016/01/07) +*** Fixes +**** Core +- Fix home buffer obfuscating opened file when Emacs starts (thanks to justbur) +**** Ruby layer +- Fix =rbenv= loading (thanks to TheBB) +**** Spacemacs layouts +- Fix jumping to last layout when the last layout is the default layout + (thanks to TheBB) +**** Yasnippet +- Fix and improve =yasnippet= loading (thanks to TheBB) +** 0.105.3 (2016/01/06) +*** Fixes +**** Emacs lisp layer +- Fix wrong hook for adding evil text objects (thanks to justbur) +**** Ledger +- Fix missing major mode key bindings (thanks to travisbhartwell) +**** Ocaml +- Fix smartparens configuration (thanks to edwintorok) +*** Layer changes +**** Spacemacs +- Improve robustness of =spacemacs/toggle-transparency= function + (thanks to justbur) +*** Other improvements +- Fix layer install section in all layers READMEs to be more explicit + and remove a source of confusion for new comers (thanks to mattbaker) +- Typos and documentation improvements (thanks to d12frosted) +** 0.105.2 (2016/01/05) +- Fix empty mode-line when a new Spacemacs version is available + (thanks to TheBB) +** 0.105.1 (2016/01/05) +*** Fixes +- Fix and improve support for GUI clients using a server started with + =emacs --daemon=: + - Fix font + - Fix graphical Spaceline separator + - Fix theme colors (most of them) + - Fix Spacemacs logo in home buffer + - Add support for graphical Nyan Cat +**** Spacemacs layer +- Fix broken =evil-escape-mode= when toggling =holy-mode= (emacs style) +**** Bépo layer +- Fix support for Magit (thanks to StreakyCobra) +**** Magit layer +- Fix ~TAB~ key bindings to expand/collapse sections (thanks to justbur) +**** Scala layer +- Fix a typo in function name =scala-auto-insert-asterisk-in-comments= + (thanks to lunaryorn) +*** Layer changes +**** Spacemacs +- New key binding ~SPC h n~ to browse the Emacs news (thanks to lunaryorn) +**** Themes megapack +- Add =monokai= theme (thanks to jonboiser) +*** Other improvements +- Typos and documentation improvements (thanks to mjs2600, person808, + robbyoconnor, StreakyCobra, TheBB and xfq) +** 0.105.0 (2016/01/04) +*** IMPORTANT - Breaking changes +- ~SPC l~ for =avy-goto-line= is now under ~SPC y~. ~SPC l~ is for + spacemacs layouts. +- ~SPC a p~ is now for =list-processes= and ~SPC a P~ for =proced=, + =paradox= is now on ~SPC a k~. +- ~SPC s l~ is now used to bring back last search buffer and ~SPC s j~ + is for jumping into a file using =imenu=. +- In home buffer, jumping to bookmark list is now on ~b~. +- Projectile: caching is now disabled by default, while it should not + break anything if you have some functions relying on caching being + enabled be sure to activate it explicitly in your dotfile with + =(setq projectile-enable-caching t)=. +- Git: new key bindings scheme using =evil-magit= package. If you want + to continue to use the old evilified bindings add =evil-magit= package + to the =dotspacemacs-excluded-packages= variable of your dotfile. +- Ruby: the default major mode is now the Emacs built-in =ruby-mode=. + If you want to continue to use =enh-ruby-mode= set the layer variable + =ruby-enable-enh-ruby-mode= to =t=. +*** Hot new features +- Spacemacs layouts under ~SPC l~ with =eyebrowse= integration + (thanks to CestDiego, bmag and TheBB) +- Revamped Magit key bindings thanks to =evil-magit= which provides + a faithful port of Magit UX using Vim key bindings (thanks to justbur) +- Brand new website on =spacemacs.org= with =readthedocs= documentation pages + (thanks to bobbyangelov, nashamri and TheBB) +- New command line parameters for =emacs=: + - =--timed-requires=, =--profile= and =--adv-timers [n]= to profile and + benchmark Emacs initialization (thanks to justbur) + - =--insecure= to disable https when fetching ELPA packages. + - =--debug-init= (built-in Emacs parameter) now enable Spacemacs verbose + messages when Emacs is loading. +*** Other important notes +- All =extensions= directories have been renamed to =local=. =extensions= + directories will be deprecated in 0.106.0. +- The =evil-leader= functions =evil-leader/set-key= and + =evil-leader/set-key-for-mode= are now obsolete and will be deprecated + in a future version. +*** New conventions +- Commit and abort commands conventions: + - ~SPC m ​,​~ and ~SPC m c~ to Valid/Confirm + - ~SPC m a~ and ~SPC m k~ to Abort/Discard + (thanks to StreakyCobra) +- Update evilified state rebinding conventions: + ~SPC~ to ~​'​~, ~/~ to ~\~ and ~:~ to ~|~ +*** New Layers +- bepo in =keyboard-layouts= (thanks to StreakyCobra) +- command-log in =tools= (thanks to bmag) +- elfeed in =tools= (thanks to d12frosted) +- evil-cleverparans (thanks to justbur) +- geolocation (thanks to Gogs) +- mu4e in =email= (thanks to darkfeline) +- octave in =lang= (thanks to izahn) +- selectric in =fun= (thanks to algernon) +- spacemacs-layouts (thanks to CestDiego) +- speed-reading (thanks to AdrieanKhisbe) +- swift in =lang= (thanks +- theming (thanks to TheBB) +- typography (thanks to lunaryorn) +- vimscript in =lang= (thanks to ralesi) +*** Dotfile changes +- New variable =dotspacemacs-elpa-https= if non nil use HTTPS otherwise + use HTTP. Default is t. +- New variable =dotspacemacs-elpa-timeout=, default is 5 seconds +- New variable =dotspacemacs-check-for-update= to toggle check for Spacemacs + updates at startup, default is =t= (thanks to tenthousandfailures) +- New variable =dotspacemacs-default-layout-name= to set the name of the + default Spacemacs layout. +- New variable =dotspacemacs-display-default-layout= to toggle display + of the name of the default layout in the mode-line, default is =nil=. +- New variable =dotspacemacs-auto-resume-layouts= to resume automatically + the last layout when Emacs starts. +- New variable =dotspacemacs-max-rollback-slots= to set the maximum number + of rollback slots to keep in the cache. +- New variable =dotspacemacs-line-numbers= to enable line numbers + globally, possible values are =relative=, =t= or =nil=. + Default is =nil= (thanks to StreakyCobra) +- New variable =dotspacemacs-distinguish-gui-tab=, if non nil then ~TAB~ + and ~C-i~ are distinct using GUI Emacs, default is =nil= (thanks to justbur) +- New variable =dotspacemacs-startup-recent-list-size= to configure the + number of recent files to display in the home buffer (thanks to bmag) +- New variable =dotspacemacs-whitespace-cleanup= to enable automatic + cleanup of whitespace on save. Possible values are =all=, =trailing=, + =changed= or =nil=. Default is =changed= (thanks to nixmaniack) +- Remove =dotspacemacs-verbose-loading=, it is now enabled automatically + with the command line parameter =--debug-init= +*** Distribution layer changes +- New key binding ~SPC *~ to search for current selection or symbol under point + in the current project. ~SPC /~ is similar but does not auto-fill the search + pattern. This new behavior mimics ~*~ and ~/~ keys of Vim + (thanks to StreakyCobra) +- New key binding ~SPC h d F~ to describe a face, by default the face under + point is selected (thanks to TheBB) +- New key binding ~SPC h k~ to display the top level of key bindings + (thanks to justbur) +- New key binding ~SPC h d K~ to describe a keymap (thanks to justbur) +- New key binding ~SPC h SPC~ for =helm-spacemacs= (~SPC f e h~ is still + available) (thanks to StreakyCobra) +- New key binding ~SPC f E~ to edit a file with =sudo= (thanks to cpaulik) +- New key binding ~SPC q r~ to restart Emacs (thanks to nixmaniack) +- New key binding ~SPC c q~ to close compilation window (thanks to joehillen) +- New key binding ~SPC c k~ to kill current compilation (thanks to jb55) +- New key binding ~SPC x o~ to open URLs with =avy= (thanks to StreakyCobra) +- New key binding ~backtab~ to go up a directory in =helm= (thanks to justbur) +- New key binding ~SPC b s~ to switch to =*sratch*= buffer (thanks to StreakyCobra) +- New key bindings in =help-mode= buffers to navigate links: + - ~g b~ or ~[~ to go back (same as clicking on =[back]= button) + - ~g f~ or ~]~ to go forward (same as clicking on =[forward]= button) + - ~g h~ to go to help for symbol under point + (thanks to AdrieanKhisbe) +- New key bindings under ~SPC i l~ to insert lorem ipsum text to a buffer + (thanks to lunaryorn) +- New key bindings for local and directory variables: + - ~SPC f v d~ to add a directory variable, + - ~SPC f v f~ to add a local variable to the current file, + - and ~SPC f v p~ to add a local variable to the first line of the current file + (thanks to lunaryorn) +- New key bindings ~C-q~ in helm buffers to jump to a candidate using =avy= + (thanks to ralesi) +- Bind ~g~ and ~G~ in helm micro-state (thanks to dsdshcym) +- ~TAB~ now correctly jump between links in help buffers with motion state + (thanks to justbur) +- ~SPC t n~ now toggle line numbers locally instead of globally + (thanks to StreakyCobra) +- ~SPC a p~ is now for =list-processes= (thanks to calebmeyer) +- ~SPC f J~ now open junk file using =helm= (thanks to nixmaniack) +- Move toggle for =vi-tilde-fringe= to ~SPC T ~~ +- Move =paradox= to ~SPC a k~ (thanks to calebmeyer) +- Move =proced= to ~SPC a P~ (thanks to calebmeyer) +- Add =space-line= package which replaces the =powerline= package + (thanks to TheBB) +- Add =help-fns+= package (thanks to justbur) +- Add =helm-flx= package (thanks to TheBB) +- Add =hl-todo= package (thanks to StreakyCobra) +- Add =lorem-ipsum= package (thanks to StreakyCobra) +- Add automatic setup of =evil-shift-width= based on the current mode settings + (thanks to TheBB) +- Add Evil text objects =slash= (/), =underscore= (_), =hyphen= (-), + =tilde= (~) and =equal= (=) (thanks to TheBB) +- Add custom helm mode-line (thanks to TheBB) +- Add custom info+ mode-line (thanks to TheBB) +- Add =bug-reference-prog-mode= to =prog-mode-hook= (thanks to lunaryorn) +- Add the ability to search with =ag=, =pt= etc... when pressing ~C-s~ in + =helm-projectile-switch-project= (~SPC p p~) (thanks to TheBB) +- Add case insensitive alphabetical sort of =which-key= buffers +- Add ~gg~ and ~G~ support in =neotree= buffers (thanks to synic) +- Set =compilation-scroll-output= to =first-error= (thanks to joehillen) +- Fix =helm= micro-state bug with numerical prefix arguments (thanks to TheBB) +- Fix =helm= freezes when using mouse to click and drag in the results list + (thanks to TheBB) +- Fix =helm-do-grep-preselect-candidate= void variable error (thanks to TheBB) +- Fix =linum-relative-mode= toggle being called twice the first time it is used + (thanks to justbur) +- Fix ~SPC j k~ unwanted auto-comment (thanks to driftcrow) +- Fix =spacemacs/write-file= being repeatable with ~.~ (thanks to StreakyCobra) +- Fix =debug-on-error= toggle (thanks to lunaryorn) +- Fix =recentf-exclude= to be customizable (thanks to duerrp) +- Fix =spacemacs/kill-other-buffers= (thanks to TheBB) +- Fix reversed mode-line toggle (thanks to TheBB) +- Fix =ahs-edit-mode= function which requires an argument (thanks to hanmoi-choi) +- Fix =spacemacs/sudo-edit= to make it work on remote ssh buffers with + multi-hops (thanks to dcluna) +- Fix transparency toggle (thanks to justbur) +- Fix toggle for =truncate-lines= (thanks to driftcrow) +- Fix visible cursor in =helm= buffers +- Enable built-in Emacs lock files by setting =create-lockfiles= to =t= + (thanks to xfq) +- Greatly simplify =holy-mode= by disabling =evil-mode= (thanks to justbur) +- Standardise zoom key bindings: ~+~ and ~=~ zoom in, ~-~ zoom out and ~0~ + reset the zoom level (thanks to StreakyCobra) +- Evilify package menu (thanks to nixmaniack) +- Evilify Neotree buffer (thanks to bmag) +- Set =dired-dwim-target= to =t= to make =dired= to guess a default target + directory (thanks to StreakyCobra) +- Set =helm-org-format-outline-path= to =t= by default (thanks to TheBB) +- Increase number of stored recent files to 1000 (thanks to duerrp) +- Allow evil operators to show commands in =which-key= (thanks to justbur) +- Allow =last-search-buffer= to resume last search even if no saved search + (thanks to nixmaniack) +- Improve =count-words-analysis= output (thanks to StreakyCobra) +- Switch between columns layout now correctly toggle golden-ratio + (thanks to geksilla) +- Do not kill the Emacs server when killing frame (thanks to drewkett) +- Do not change =custom-file= value if already set (thanks to lunaryorn) +- Use =evil-indent-plus= package to replace =evil-indent-textobject= + (thanks to TheBB) +- Use built-in evil variable =evil-want-Y-yank-to-eol= to set Y behavior + (thanks to person808) +- Use built-in =evil-set-initial-state= function to set the default evil + states (thanks to justbur) +- Use =tab-width= instead of obsolete =default-tab-width= (thanks to lunaryorn) +- Remove obsolete =evil-jumper-file= (thanks to TheBB) +- Remove key binding for deprecated =rxt-fontify-regexp-at-point= + (thanks to mineo) +- Remove custom =write-file= function and use built-in =save-buffer= function + instead (thanks to cpaulik) +- Disable projectile caching by default (thanks to cpaulik) +- Disable version control integration of =Neotree= by setting + =neo-vc-integration= to =nil= (thanks to synic) +- Make google translate language code case-insensitive (thanks to lislon) +**** Helm-spacemacs +- Add =add to dotfile= action on a layer (thanks to CestDiego) +- Add action to open =.org= files for editing (thanks to TheBB) +- Add FAQ source (thanks to StreakyCobra) +- Beautify sources (thanks to TheBB) +**** Evilified map +- Fix shadowed keys in minibuffer +- Fix bug where key bindings could be unexpectedly redefined + (thanks to darkfeline) +*** Layer changes +**** Auto-completion +- Add =helm-company= package available on ~C-/~ while company popup is active + (thanks to TheBB) +- Fix =yas-snippet-dirs= setup (thanks to TheBB) +- Fix =yasnippet= expand to select first snippet automatically + (thanks to TheBB) +- Make =auto-yasnippet= points to private directory by default + (thanks to taiansu) +**** Better defaults +- Fix =spacemacs/backward-kill-word-or-region= with rectangular selection + (thanks to bmag) +**** C/C++ +- Fix flycheck clang args loading (thanks to zhengyangfeng00) +**** Chinese +- Add =fcitx= support (thanks to zilongshanren) +- Add pinyin support for =avy-goto-char= (thanks to CodeFalling) +**** Clojure +- New key binding ~SPC m s I~ for =cider-jack-in-clojurescript= + (thanks to benalbrecht) +- New refactoring key bindings: ~SPC mred~ for =cljr-extract-def=, + ~SPC mrfu~ for =cljr-find-usages= and ~SPC mrsc~ for =cljr-show-changelog= + (thanks to mbertheau) +- Use =cljr--all-helpers= for automatic setup of refactoring key bindings + (thanks to grammati) +**** Dash +- Enable =zeal= on =Microsoft Windows= (thanks to dotneter-) +**** Elixir +- New key binding ~SPC m s c~ to compile the current buffer in the IEx process + (thanks to timbuchwaldt) +- New key binding ~SPC m s m~ to reload the module in the current buffer in + your IEx process (thanks to timbuchwaldt) +- New key binding ~SPC m t r~ to rerun the last test (thanks to djm) +- Bind ~q~ to =quit-window=in various elixir modes (thanks to utkarshkukreti) +- Enable =company-mode= in =alchemist-iex-mode= (thanks to utkarshkukreti) +- Fix =ruby-end= hook removal (thanks to TheBB) +**** Elm +- Fix incorrect command for =elm-repl-load= (thanks to holguinj) +- Fix key bindings for REPL commands updated upstream (thanks to tcallan) +**** Emacs lisp +- Add =auto-compile= package (thanks to justbur) +- New key bindings for compilation: + ~SPC m c c~ to byte compile the current file, + ~SPC m c l~ to popup compile-log buffer + (thanks to justbur) +- Add ~q~ to exit =macrostep= (thanks to ralesi) +**** Erc +- Fix notification icon (thanks to aminb) +- Fix erroneous micro-state key binding (thanks to StreakyCobra) +**** Ess +- Simplify the configuration of ESS minor modes (thanks to izahn) +- ~SPC m s i~ now automatically start the correct REPL for the current + buffer (thanks to izahn) +- Fix company activation (thanks to michelk) +**** Evil-snipe +- Update =evil-snipe= mode names (thanks to person808) +**** Eyebrowse +- Add ~h~ and ~l~ bindings to eyebrowse micro-state (thanks to TheBB) +- Fix workspace numbers, the first workspace now starts at 1 instead of 0 + (thanks to d12frosted) +- Fix call to =eyebrowse-rename= (thanks to TheBB) +**** Games +- Add =Pacmacs= game (thanks to CestDiego) +**** Git +- New key binding scheme using =evil-magit= package (thanks to justbur) +- New key binding ~SPC g i~ for =magit-init= (thanks to CestDiego) +- New key binding ~SPC g c~ for =magit-checkout= (thanks to PierreR) +- New key bindings ~SPC m ​,​~ and ~SPC m c~ to Valid/Confirm =with-editor= + buffers (thanks to justbur) +- New key bindings ~SPC m a~ and ~SPC m k~ to Abort/Discard =with-editor= + buffers (thanks to justbur) +- Add =gr= and =gR= bindings to refresh in evilified Magit buffers +- Add support for links to Magit buffer in =org= buffers + (thanks to mskorzhinskiy) +- Enable gravatars +- Redefine key bindings to user Magit popups whenever it is possible + (thanks to ralesi) +- Store =magit= gravatars in cache directory (thanks to CestDiego) +- =git-timemachine= and =git-blame= micro-states are now idempotent when + invoked. So these micro-states can be invoked again without side effects. +- Move =magit-gh-pulls= bindings from ~#g~ to ~#~ +- =magit-git-flow= prefix binding is now ~%~ instead of ~#f~ + (thanks to nixmaniack) +- Fix =git-magit-status-fullscreen= (thanks to bmag) +- Fix various bugs with evilification of maps +- Add =gr= and =gR= bindings to refresh in evilified Magit buffers +- Deactivate =evil-snipe= mode which messes with =magit= buffer (thanks to + cpaulik) +**** Github +- New key binding ~SPC g c~ to clone and optionally fork repository + (thanks to cpaulik) +**** Go +- New key binding ~SPC m x x~ to run =go run= for the current main package + (thanks to sectorzero) +- New key bindings for testing: + - ~SPC m t P~ to run =go test= for the current package and all packages under it | + - ~SPC m t t~ to run =go test= for the function you're currently in + and ~SPC m t s~ to run =go test= for the suite you're currently in + (thanks to bogdanteleaga) +- Import =GO15VENDOREXPERIMENT= from environment variables + (thanks to sectorzero) +**** Haskell +- New key binding ~SPC m h H~ to do a local (not using internet) Hoogle lookup + (thanks to jb55) +- New key binding ~SPC m g i~ to jump to imports (thanks to bennofs) +- New key bindings for =ghc-mod=: + - ~SPC m m t~ to insert template + - ~SPC m m u~ to insert template with holes + - ~SPC m m a~ to select one of possible cases + - ~SPC m m f~ to replace a hole + - ~SPC m m e~ to expand template haskell + - ~SPC m m n~ to go to next type hole + - ~SPC m m p~ to go to previous type hole + - ~SPC m m >~ to make indent deeper + - ~SPC m m <~ to make indent shallower + (thanks to Tritlo) +- Add REPL key bindings to =cabal-mode= (thanks to d12frosted) +- Add text alignment rules (thanks to PierreR) +- Fix ~SPC m s S~ key binding for switching back from REPL + (thanks to d12frosted) +- Fix typo in variable =haskell-interactive-popup-errors= (thanks to usharf) +- Fix ~SPC m h t~ and ~SPC m h i~ bindings (thanks to d12frosted) +- Fix ~SPC m s s~ according to conventions, i.e. does not switch to REPL + buffer (thanks to d12frosted) +- Fix missing key bindings when =ghc-mod= is disabled (thanks to d12frosted) +- Fix =ghci-ng= for stack projects (thanks to bjarkevad) +- Force =haskell-mode= loading in cabal files (thanks to d12frosted) +- Remove indentation guides to comply with latest haskell-mode + (thanks to PierreR) +- Remove =haskell-indentation-mode= hook (thanks to d12frosted) +**** Html +- Add =company-css= backend in =web-mode= (thanks to TheBB) +- Enable Emmet tab expansion in hybrid mode (thanks to geo7) +- Expand to className when using Emmet, for =instance div.react-class= + expands to =
= (thanks to CestDegio) +- Mark =css-indent-offset= as safe local variable (thanks to lunaryorn) +- Fix =smartparens= loading (thanks to TheBB) +- Fix erroneous micro-state key binding (thanks to StreakyCobra) +**** Idris +- Use popwin and motion state for special buffers (thanks to holguinj) +**** Javascript +- Add evil-matchit support for js files (thanks to robbyoconnor) +**** LaTeX +- New layer variable =latex-enable-folding= to enable text folding, default + value is =nil= (thanks to justbur) +- New key bindings ~SPC m ​,​~ and ~SPC m k~ for ~C-c C-c~ and ~C-c C-k~ + respectively (thanks to justbur) +- New key bindings: + - ~SPC m .~ to mark LaTeX environment + - ~SPC m *~ to mark LaTeX section + - ~SPC m k~ to kill TeX job + - ~SPC m l~ to recenter output buffer + - ~SPC m m~ to insert LaTeX macro + - ~SPC m s~ to insert LaTeX section + - ~SPC m v~ to view output + (thanks to justbur) +- New folding key bindings (available if =latex-enable-folding= is non nil): + - ~SPC m z b~ to fold TeX buffer + - ~SPC m z e~ to fold TeX environment + - ~SPC m z m~ to fold TeX macro + - ~SPC m z =~ to fold TeX math + - ~SPC m z r~ to fold TeX region + (thanks to justbur) +- New =TeX-font= key bindings: + - ~SPC m x c~ to make font monospaced (for code) + - ~SPC m x e~ to make font emphasised + - ~SPC m x i~ to make font italic + - ~SPC m x o~ to make font oblique + - ~SPC m x r~ to remove font properties + - ~SPC m x f a~ to use calligraphic font + - ~SPC m x f c~ to use small-caps font + - ~SPC m x f f~ to use sans serif font + - ~SPC m x f n~ to use normal font + - ~SPC m x f r~ to use serif font + - ~SPC m x f u~ to use upright font + (thanks to TheBB) +- New key binding ~SPC m -~ to open output buffer (thanks to benquebec) +- Configure =latexmk= as the default build command (thanks to izahn) +- Disable =typo= (thanks to TheBB) +- Fix enabling of minor modes =TeX-source-correlate-mode= and =TeX-PDF-mode= + (thanks to justbur) +**** Markdown +- New key binding ~SPC m x C~ to insert github flavored code block + (thanks to lunaryorn) +- Include missing =gh-md= package (thanks to tko) +**** Nim +- Use MELPA version of =flycheck-nim= package (thanks to Gonzih) +- Remove package =company-nim= which is now part of =nim-mode= + (thanks to robbyoconnor) +**** Ocaml +- Fix error when initializing =opam= (thanks to TheBB) +- Make OCaml generated files invisible to completion (thanks to StreakyCobra) +**** Org +- New key bindings: + - ~SPC m ~ for =org-ctrl-c-ctrl-c= + - ~SPC m *~ for =org-ctrl-c-star= + - ~SPC m RET~ for =org-ctrl-c-ret= + - ~SPC m -~ for =org-ctrl-c-minus= + - ~SPC m ^~ for =org-sort= + - ~SPC m /~ for =org-sparse-tree= + (thanks to TheBB) +- New key binding ~SPC m P~ for =org-set-property= (thanks to swaroopch) +- New key binding ~SPC m !~ for =org-time-stamp-inactive= + (thanks to channingwalton) +- New key binding ~SPC m D~ to insert drawer (thanks to cpaulik) +- Add drawer =evil-surround= pair (thanks to TheBB) +- Use ~SPC a o~ as prefix for org related applications like =org-agenda= + or =org-capture=. The ~a~ is for =application=, and ~o~ for =org= + (thanks to StreakyCobra) +- Use ~RET~ in normal state for follow links (thanks to justbur) +- Enable =flyspell= by default (thanks to robbyoconnor) +- Move =evil-org= to a local package (thanks to TheBB) +- Move =.org-id-locations= to cache directory (thanks to fandag) +**** Osx +- Fix search for =GNU ls= (thanks to lunaryorn) +- Use =osx-trash= package to handle deleted items (thanks to lunaryorn) +- Make =mdfind= the default backend for =helm-locate= (thanks to Andre0991) +- Set font =Apple Color Emoji= for emojis (thanks to myrjola) +**** Puppet +- Remove deprecated =puppetfile-mode= package (thanks to joehillen) +**** Purescript +- Add =psc-ide= support (thanks to kRITZCREEK) +**** Python +- New layer variable =python-auto-set-local-pyenv-version= to automatically + set =pyenv= version from a =.python-version= file. Possible values are + =on-visit=, =on-project-switch= or =nil=, default is =on-visit= + (thanks to fbergroth) +- Various fixes to =pylookup= to make it work again (thanks to TheBB) +- Allow user to customize fill column with the variable =python-fill-column= + (thanks to swaroopch) +- Fix =pylookup= makefile for python version 2.7.10 (thanks to hyh) +**** React +- Fix =flycheck= setup, do not disable =jshint= globally, + but only for =react= mode (thanks to lunaryorn) +- Enable =js-mode= snippet (thanks to rhalukongor) +- Open =index.android.js= and =index.ios.js= with react mode (thanks to erwan) +**** Ruby +- Enable built-in =ruby-mode= by default instead of =enh-ruby-mode= + (thanks to lunaryorn) +- New layer variable =ruby-enable-enh-ruby-mode= to enable =enh-ruby-mode= + by default instead of =ruby-mode=. +- New layer variable =ruby-test-runner= to choose between =ruby-test= or + =rspec= +- Add support for =rspec= (thanks to alexgirdler and dcluna) +- Add support for =chruby= (thanks to bjeanes and Immortalin) +- Add =rubocop= package (thanks to dcluna) +- New =rubocop= key bindings: + - ~SPC m r r f~ to run RuboCop on the currently visited file + - ~SPC m r a D~ to autocorrect current directory + - ~SPC m r r F~ to run auto-correct on the currently visited file + - ~SPC m r a P~ to autocorrect current project + - ~SPC m r r d~ to prompt from a directory on which to run RuboCop + - ~SPC m r r D~ to prompt for a directory on which to run auto-correct + - ~SPC m r r p~ to run RuboCop on the entire project + - ~SPC m r r P~ to run auto-correct on the project +**** Ruby on rails +- Move ~SPC m r r :~ to ~SPC m r :~ +**** Rust +- New key binding ~SPC m c C~ to remove build artefacts with Cargo + (thanks to SShrike) +- New key binding ~SPC m g g~ to jump to definition (thanks to isphinx) +- Use =exec-path-from-shell-copy-env= to set =RUST_SRC_PATH= for Racer + (thanks to mahinshaw) +**** Scala +- New layer variable =scala-enable-eldoc= to explicitly turn on =el-doc=, + default value is =nil= (thanks to d1egoaz) +- New layer variable =scala-auto-insert-asterisk-in-comments= to automatically + insert asterisk in multi-line comments (thanks to lunaryorn) +- New key binding ~SPC m b b~ for =sbt-command= (thanks to lunaryorn) +- Enable Ensime’s =expand-region= integration (thanks to lunaryorn) +- Only disable =flycheck= Scala syntax checker in Ensime (thanks to lunaryorn) +- Fix test key bindings (thanks lunaryorn) +- Fix automatic trigger of completion when hitting ~.~ (thanks to d1egoaz)) +**** Scheme +- New key binding ~SPC m s s~ for scheme implementation selection + (thanks to troydm) +- New key bindings to evaluate code: + - ~SPC m e b~ to evaluate the whole buffer + - ~SPC m e e~ to evaluate last sexp + - ~SPC m e f~ to evaluate current function + - ~SPC m e l~ to evaluate line + - ~SPC m e r~ to evaluate region + (thanks to CestDiego) +**** Shell +- Add =xterm-color= package (thanks to CestDiego) +- New key bindings ~C-j~ and ~C-k~ to browse history in normal state + (thanks to mijoharas and TheBB) +- New key binding ~C-l~ in =eshell= to clear buffer (thanks to CestDiego) +- New key binding ~C-c C-z~ to stop jobs (thanks to darkfeline) +- Add support to open =zsh= common files with =sh-mode= (=.zsh=, =zlogin=, + =zlogout=, =zpreztorc=, =zprofile=, =zshenv=, =zshrc=) (thanks to jcf) +- Use login shell as term shell (thanks to lunaryorn) +- Automatically scroll the buffer on new output by setting variable + =comint-move-point-for-output= to =t=. +- Deactivate scroll margin for shell buffers (thanks to darkfeline) +- Protect prompt in =comint-mode= (thanks to CestDiego) +- Set =eshell-hist-ignoredups= to =t= (thanks to CestDiego) +- Typing =clear= in an =eshell= buffer will clear the buffer + (thanks to CestDiego) +- Fix SIGQUIT bug (thanks to darkfeline) +**** Spell-checking +- New layer variable =spell-checking-enable-by-default= to enable/disable + =flyspell= by default globally (thanks to TheBB) +- Move =auto-dictionary= from spacemacs layer to =spell-checking= + and activate it (thanks to StreakyCobra) +- Disable line numbers in shell buffers (thanks to CestDiego) +- Fix =flyspell-prog-mode= activation (thanks to lunaryorn) +**** Syntax-checking +- New layer variable =syntax-checking-enable-by-default= to enable/disable + =flycheck= by default globally (thanks to TheBB) +- Evilify =flycheck= error list (thanks to TheBB and bmag) +- Enable new global minor mode =flycheck-pos-tip-mode= (thanks to StreakyCobra) +- New key bindings ~SPC e s~ and ~SPC e S~ to select =flycheck= checker + executable (thanks to nashamri) +- Fix escaping in buffer name regexp (thanks to lunaryorn) +- Remove flycheck fringe's bullet underlines (thanks to StreakyCobra) +**** Themes-megapack +- Add =jbeans= theme (thanks to synic) +- Add =farmhouse= theme (thanks to CodeFalling) +- Add =badwolf= theme (thanks to fabianhjr) +**** Vagrant +- Fix obsolete =vagrant-tramp-enable= variable (thanks to joehillen) +**** Version-control +- New key bindings ~SPC T d~ and ~SPC T C-d~ to toggle diff margin in the fringe + (thanks to ralesi) +- New micro-state on ~SPC g .~ to stage, unstage, commit, show diff, + show hunks, etc... (thanks to ralesi) +- Add support for multiple gutter backends: =diff-hl=, =git-gutter= and + =git-gutter+= (thanks to ralesi) +**** Vinegar +- Fix evilified dired (thanks to TheBB) +**** Yaml +- Enable company +*** Website +- Initial version (thanks to bobbyangelov, nashamri and TheBB) +*** Core changes +- New command line parameters =--timed-requires= and =--profile= to debug + and benchmark Emacs initialization (thanks to justbur) +- New command line parameter =--insecure= to disable https +- Add path variable =spacemacs-assets-directory= (thanks to aminb) +- Add a check to make sure that the Spacemacs git repository is not dirty before + switching the Spacemacs versions (thanks to justbur) +- Add an error message when the minimal Emacs version is not met + (thanks Immortalin) +- Add =spacemacs/recompile-elpa= interactive function (thanks to justbur) +- Add =user-emacs-directory= in =async-start= (thanks to brabalan) +- Set =ad-redefinition-action= to =accept= +- Enable distinction between ~C-i~ and ~TAB~ (thanks to justbur) +- Move =evilified-state= library to local package of =spacemacs= layer +- Replace =evil-leader= package by =bind-map= package (thanks to justbur) +- Remove special handling of =spacemacs-theme= and =solarized-theme= + (thanks to TheBB) +- Remove bootstrap packages =dash= and =f= +- Improved travis Build relying on container and EVM (thanks AdrieanKhisbe) +- Improve installation speed of themes and bootstrap packages +- Keep focus while navigating =*help*= buffers (thanks to sooheon) +- Catch errors in executed dotfile functions and signal them to the user + (thanks to justbur) +- Show errors in =*Messages*= buffer when loading .spacemacs instead of + ignoring them (thanks to dcluna) +- Fix overwrite of clipboard at startup (thanks to StreakyCobra) +- Fix error when setting =dotspacemacs-major-mode-leader-key= to nil + (thanks to justbur) +- Fix some loading warnings (thanks to syohex) +- Fix theme cycling after ~SPC T h~ is used (thanks to nixmaniack) +- Fix various usage of obsolete functions (thanks to justbur) +- Fix various free variable references (thanks to justbur) +- Hide mode-line at startup +- Generate necessary HTML for the Spacemacs docs (used for the website) + (thanks to travisbhartwell) +**** Home buffer +- ~b~ now jumps to the bookmark list (thanks to kccai) +- Set Spacemacs home buffer as initial buffer for Emacs clients + (thanks to TheBB) +- Inject Emacs version along with Spacemacs version in home buffer + (thanks to ralesi) +- Add a =Spacemacs Update= button to the spacemacs buffer, and relabel the + package update button to read =Update Packages= (thanks to justbur) +- Show quick help menu when no =.spacemacs= file is found (thanks to person808) +- Do not start spacemacs buffer in motion state when editing style is =emacs= + (thanks to justbur) +- Factor out =spacemacs-buffer= creation (thanks to justbur) +- Move =spacemacs-mode= to =core-spacemacs-buffer.el= (thanks to justbur) +- Simplify =spacemacs-buffer/goto-link-line= (thanks to justbur) +**** Configuration layer +- Limit the number of rollback slots (thanks to elemakil) +- Add a timeout when fetching ELPA archives +- Allow explicit path for package location (thanks to TheBB) +- Fix =configuration-layer/package-usedp= for excluded packages +- Fix automatic deletion of bootstrap packages (thanks to TheBB) +- Fix creation of =README.org= file in =configuration-layer/create-layer= + (thanks to StreakyCobra) +- Add package keyword =:protected= +- Set configuration layer error flag when calling user dotfile functions +**** Micro-state +- =:exit= keyword now accepts a list +- Execute =:on-enter= before =:doc= in micro-state +*** Other fixes and improvements +- =README.md= introduction rewrite (thanks to purcell) +- New badge =Built with Spacemacs= (thanks to nashamri) +- Merge files =HOWTOs.org= in =FAQ.org= (thanks to StreakyCobra) +- Merge the =CONTRIBUTING.md= and =doc/CONTRIBUTE.org= files into a new + =CONTRIBUTING.org= file (thanks to StreakyCobra) +- Delete unneeded =.gitmodules= file (thanks to robbyoconnor) +- Add =cl-= prefix to =cl-lib= functions (thanks to coldnew, robbyoconnor) +- Replace =eval-after-load= with =with-eval-after-load= (thanks to person808) +- New Spacemacs screenshot in =README.md= (thanks to nashamri) +- New text banners of the Spacemacs logo (thanks to sshbio) +- Add prefix command names (thanks to grammati, jenanwise, davoclavo, tekerson, + d12frosted, CestDiego, lunaryorn, nixmaniack, AlexCharlton) +- Typos and documentation improvements (thanks to AdrieanKhisbe, bardec, + bebound, benquebec, bmag, bogdanteleaga, CarlQLange, CestDiego, CodeFalling, + com4, cpaulik, d12frosted, d1egoaz, dotneter-, dptd, dsdshcym, dvcrn, + eagleflo, ernestas, FlashYoshi, Immortalin, jrk, justbur, masukomi, + MaxWofford, mbertheau, mineo, mijoharas, mkollaro, nashamri, pbzdyl, + person808, robbyoconnor, scloudyy, shishkin, swaroopch, TheBB, Treri, + vijaykiran, xfq, xtian, ZachLiss) +*** Core team members +- Sylvain Benner (syl20bnr) +- Eivind Fonn (TheBB) +- Fabien Dubosson (StreakyCobra) +- Justin Burkett (justbur) +* Release 0.104.x +** 0.104.8 (2015/12/16) +*** Hotfix +- Revert removal of fancy battery mode-line indicator. +** 0.104.7 (2015/12/15) +*** Distribution layer changes +**** Spacemacs +- Remove fancy battery custom mode-line (moved to spaceline) (thanks to TheBB) +*** Layers changes +**** Eyebrowse +- Eyebrowse doesn't have a lighter anymore (thanks to myrjola) +**** Haskell +- Replace obsolete function =haskell-process-load-or-reload= (thanks to + joehillen) +- Fix renamed command =hindent-reformat-decl= (thanks to lunaryorn) +**** Syntax-checking +- Add support for =flycheck-pos-tip-mode= (thanks to StreakyCobra, TheBB and + lunaryorn) +** 0.104.6 (2015/11/27) +*** Hotfix +- Fix void variable error =smartparens-strict-mode= (thanks to TheBB) +** 0.104.5 (2015/11/22) +*** Distribution layer changes +**** Spacemacs +- Use version 7.1 of =evil-lisp-state=, the version 8 is supported + in version 105 of Spacemacs only. +** 0.104.4 (2015/11/04) +*** Layer changes +**** Scala +- Fix Ensime test commands to reflect the changes in the recent versions + of the package (thanks to lunaryorn) +**** Vagrant +- Replace obsolete function =vagrant-tramp-enable= by the function + =vagrant-tramp-add-method= (thanks to joehillen) +*** Core +- Prevent bootstrap packages from being automatically uninstalled + (thanks to TheBB) +** 0.104.3 (2015/11/01) +*** Layer changes +**** Evil-snipe +- Update =evil-snipe= minor mode name to match latest release of + the package (thanks to person808) +**** Haskell +- Remove indentation guides to comply with latest =haskell-mode= + (thanks to PierreR) +** 0.104.2 (2015/09/29) +*** Hotfixes +- Fix error =void-variable warning-minimum-level= on Emacs 24.3 + (thanks to syohex) +*** Layer changes +**** Markdown +- Fix ~SPC m c r~ binding (thanks to tko) +*** Core +- Silence =ad-handle-definition= about advised functions getting redefined +- Improve evilification rules, now ~:~ is rebound to ~|~, ~/~ is rebound to ~\~ + and ~SPC~ is rebound to ~​'​~ +*** Other fixes and improvements +- Add FAQ entry on the difference between available distributions (thanks to + robbyoconnor) +- Delete obsolete =.gitmodules= file (thanks to robbyoconnor) +- Improve convention documentation for evilified buffers +- Typos and documentation improvements (thanks to CarlQLange) +** 0.104.1 (2015/09/28) +*** Dotfile changes +- New variable =dotspacemacs-remap-Y-to-y$=, when non nil ~Y~ is remapped to + ~y$~. Default value is =t=. +*** Distribution layer changes +**** Spacemacs +- Add ~SPC t h a~ to toggle automatic highlighting of symbol under point. +*** Layer changes +**** React +- Force -jsx= content type (thanks to dvcrn) +*** Other fixes and improvements +- Typos and documentation improvements (thanks to k4rtik, robbyoconnor, tko, xfq) +** 0.104.0 (2015/09/28) +*** IMPORTANT - Breaking changes +- =org-plus-contrib= is now installed from org ELPA repository, you may + encounter strange behaviours from Org. In this case delete the =org= directory + in the =elpa= directory and restart Emacs. +- =Helm= key bindings have been slightly adjusted: + - in =helm-find-files= (~SPC f f~): now ~C-h~ move up a directory and ~C-l~ + enter the selected directory. =describe-key= command is available on ~C-S-h~ + - in other =helm= buffers ~C-h~ is used to go to the next source and ~C-l~ + is the same as ~RET~. =describe-key= command is also available on ~C-S-h~. +- ~Y~ has been remapped to ~y$~ +- The =bookmark= saved file has been moved to the =.cache= directory, if + you have a bookmark file =~/.emacs.d/bookmarks= then you'll have to move it + to =~/.emacs.d/.cache/bookmarks= +- =Ruby on Rails= framework has now its own layer called =ruby-on-rails=, + be sure to add this layer to your dotfile if you use RoR. +- =Django= framework has now its own layer called =django=, + be sure to add this layer to your dotfile if you use it. +- =guide-key= has been replaced by =which-key=, you may encounter issues + if you have some =guide-key= custom configuration, remove any =guide-key= + configuration and check the options offered by =which-key=. +*** Other important notes +- All layers have been moved to =layers= directory +- Category folder prefix has been changed to =+= (was =!=) +- =spacemacs= layer has been moved to the =layers= directory in the + category =+distribution= +- All =extensions= directories have been renamed to =local=. =extensions= + directories will be deprecated in 0.105.0. +- =tromey= ELPA repository has been removed (thanks to robbyoconnor) +*** Hot new features +- Enhanced layer package lists which merge old extension lists and package + lists. Keywords can be associated with packages. The supported keywords + are =:location=, =:step= and =:excluded=. + =extensions.el= files and =-excluded-packages= variables are now + optional and will be deprecated in the next version 0.105.0. +- New =distribution= concept: you can now choose between two distributions: + =spacemacs= or =spacemacs-base=. =spacemacs-base= contains only + a minimal set of packages whereas =spacemacs= is the full Spacemacs + experience. Set the distribution with =dotspacemacs-distribution= variable. +- Add support for =Quelpa= which allows to use =Melpa= recipes to install + packages directly from source (i.e. one can now install a package directly + from a Github repository). +- New editing style: =hybrid=. This style is similar to Vim style except that + all Emacs key bindings are available in hybrid (insert) state instead of Vim + key bindings. Also in this state, the buffers are evilified like in Vim style. +- The default theme of Spacemacs is now =spacemacs-dark=. The Spacemacs themes + (=spacemacs-dark= and =spacemacs-light=) become the official themes of + Spacemacs (thanks to nashamri) +- Recovery mode when there is an error in the user dotfile. Now even when your + dotfile cannot be loaded, Spacemacs will be operational with a minimal set + of packages available (thanks to cmccloud) +- Add support for dotdirectory =~/.spacemacs.d= which behaves like the Emacs + dotdirectory (i.e. =~/.spacemacs.d/init.el= is evaluated instead of + =~/.spacemacs= if the former exists and the latter does not) (thanks to + justbur) +- Guide-key is replaced by =which-key= which provides an enhanced and better + live key bindings browsing experience. (thanks to justbur) +- New API to manage the =powerline= mode-line. It is now possible to easily + define segments and arrange them (thanks to TheBB) +- New web gallery to browse themes in =themes-megapack=, URL: [[http://themegallery.robdor.com][theme gallery + ]] (thanks to robmerrell) +- New test framework supporting layer specific tests (thanks to TheBB) +- New interactive function =dotspacemacs/test-dotfile= testing the integrity + of the =.spacemacs= file. This function will detect any unknown layers and + bad dotspacemacs variable values (thanks to justbur) +*** New conventions +- Add spacing conventions for org files (thanks to person808) +- Move ~SPC m T x~ conventions for executing tests in debug to ~SPC m t X~ +- Add conventions for toggles which are under ~SPC t~, ~SPC T~ and ~SPC C-t~. + For major mode specific toggles only ~SPC m T~ is available. +- Add ~SPC m g b~ to go back to previous location after a ~SPC m g g~. +- Reserve ~SPC m o~ for users (thanks to TheBB) +*** New Layers +- asciidoc (thanks to hijarian) +- chinese (thanks to andyque) +- cscope (thanks to bmag) +- common-lisp (old slime layer renamed) (thanks to kingcons) +- django (split from python layer) +- elm (thanks to usharf) +- idris (thanks to zmthy) +- jabber (thanks to toshism) +- java (thanks to kleewho) +- nim (thanks to Gonzih) +- nixos (thanks to CestDiego) +- ranger (thanks to ralesi) +- sml (thanks to Devagamster) +- spell-checking (split from syntax-checking) (thanks to justbur) +- terraform (thanks to BrianHicks) +- react (thanks to axyz) +- ruby-on-rails (split from ruby layer) +- scheme (thanks to kingcons) +- vinegar (thanks to ralesi) +- unimpaired (thanks to ralesi) +- wakatime (thanks to CestDiego) +- yaml (split from ruby) +*** Dotfile changes +- New variable =dospacemacs-distribution= allowing to choose the default + packages installed by Spacemacs. +- New function =dotspacemacs/user-init=. Now =dotspacemacs/init= function + is reserved for dotspacemacs variable exclusively. +- New value =any= for =dotspacemacs-highlight-delimiters=, when set to + =any=, all the delimiters are highlighted via =rainbow-mode=. +- New variable =dotspacemacs-helm-resize=. If non nil then =helm= windows + will be automatically resized depending on the number of candidates (thanks + to ralesi) +- New variable =dotspacemacs-helm-no-header=. If non nil then the helm header + is hidden when there is only one source in the helm buffer (thanks to ralesi) +- New variable =dotspacemacs-helm-position= which can be =bottom=, =top=, + =left= or =right= (thanks to ralesi) +- Add new =:disabled-for= keyword for =dotspacemacs-configuration-layer= which + allow to deactivate a layer for a set of layers. For instance + =(auto-completion :disabled-for org git)= will disable auto completion for + both org and git layers. +- Rename function =dotspacemacs/config= to =dotspacemacs/user-config=. The + old function =dotspacemacs/config= will be deprecated in 0.105.0. +*** Distribution layer changes +**** Spacemacs-base +- New navigation key bindings for =helm-find-files= (~SPC f f~), now + ~C-h~ move up a directory and ~C-l~ enter the selected directory. + =describe-key= command is available on ~C-S-h~. +- In =helm= buffers ~C-h~ is used to go to the next source and ~C-l~ + is the same as ~RET~. =describe-key= command is available on ~C-S-h~. +- Add =copy file= key binding on ~SPC f c~ (thanks to cpaulik) +- Add transparency micro-state (thanks to person808) +- Add ~SPC i u~ key binding to insert unicode symbols with helm (thanks to + robbyoconnor) +- Add ~SPC x l s~ and ~SPC x l u~ to sort and uniquify lines in a buffer + (thanks to oppenlander) +- In buffer not visiting a file ~SPC f s~ now asks for a filename (thanks to + cpaulik) +- Add ~SPC f l~ to visit a file literally which means that the file will be + opened in =fundamental mode= (thanks to sooheon) +- Add support for automatic recompilation of =.el= files on save (thanks to + ralesi) +- Add ~SPC f C d~ and ~SPC f C u~ to quickly convert Unix encoding to DOS + encoding and vice versa (thanks to ralesi) +- New key bindings to toggle editing styles: ~SPC t E e~ to toggle =emacs= + style and ~SPC t E h~ to toggle =hybrid= style +- Add support for arrow keys in windows micro-state (thanks to mbertheau) +- Fix paste micro-state undo +- Fix ~SPC i K~ (insert empty line above point) which now works + as expected when used from the first line of a buffer (thanks to + travisbhartwell) +- Fix windows micro-state by using the minibuffer (thanks to person808) +- Fix broken alignment functions on ~SPC x a~ (thanks to justbur) +- Don't jump if only one match in =helm-imenu= (thanks to tuhdo) +- Remove =wS= from prefix list in =config.el= (thanks to justbur) +- Properly close frame when running a client from terminal (thanks to drewkett) +- Add chocolate color for the =replace= state (thanks to TheBB) +- Make ~Y~ equivalent to ~y$~ (thanks to person808) +- Sync =visual-line-mode= and =evil-visual-xxx= functions. Now ~SPC t L~ + correctly enables =visual-mode-line= _and_ change Evil to visual + navigation accordingly. Use ~SPC t l~ to disable truncated lines while + keeping default Evil behavior. +- Reduce autosave interval for evil-jumper (thanks to ralesi) +- Improve evil configuration for cursors and colors (thanks to justbur) +- Fix called function name for ~SPC h b~ binding. Helm removed + =helm-pp-bookmarks= in the latest update and replaced it with + =helm-filtered-bookmarks= (thanks to sgepigon) +- Add ~SPC f L~ for =helm-locate= (thanks to ralesi) +- Add text object ~g~ for entire buffer (thanks to ralesi) +- helm-spacemacs: load layers only once. +- helm-spacemacs: show description of toggle functions (thanks to person808) +**** Spacemacs +- New API for the powerline (thanks to TheBB) +- Add package =define-word= on ~SPC x w d~ (thanks to swaroopch) +- Set =projectile-indexing-method= to =alien=. This settings will use available + tooling to speed up the build of the cache, should greatly improve the + performance on Windows (provided you have the required tools) +- Fix =projectile-generic-command= on Windows using =find= (thanks to TheBB) +- Fix =neotree= bug with window number 0 (thanks to jaypei) +- Fix search direction consistency for =auto-highlight-symbol= micro-state + (thanks to herbertjones) +- Add VCS integration to =neotree= +- Focus current file when opening Neotree in project's root with ~SPC p t~ + (thanks to StreakyCobra) +- Set =sp-show-pair-delay= to 0.2 instead of 0. Should fix some slowness in +- Set =highlight-parentheses= delay to 0.2 +- Enable =highlight-parentheses= when =dotspacemacs-highlight-delimiters= is + set to =all= (thanks to tuhdo) +- Hide lighter for =highlight-parentheses= +- Better diminished lighters for =highlight-indentation-mode= (thanks to + robbyoconnor) +- Prevent iedit from adding global key binding (thanks to justbur) +- Temporarily exclude the package =hl-anything= waiting for an overlay bug + to be fixed +- Correctly enable =powerline= only if it is used (thanks to sooheon) +- Make =golden-ratio= work after avy-word-jump (thanks to synic) +- Exclude =helm= windows from =golden-ratio= (thanks to ralesi) +- Don't automatically select *compilation* buffer (thanks to jasminpatry) +- Define explicit functions to inverse comments for =evil-nerd-commenter= + (thanks to endrebak) +- Use TheBB fork of =evil-indent-textobject= which has working text objects + based on the indentations (thanks to TheBB) +- Exclude package =evil-terminal-cursor-changer= since it is buggy in some + terminals (thanks to TheBB) +*** Layer changes +**** Agda +- Move ~SPC m o~ to ~SPC m h~ since ~SPC m o~ is now reserved for users + (thanks to TheBB) +**** Auto-completion +- Add new layer variable =auto-completion-private-snippets-directory= which + allows to specify a custom private snippet directory (thanks to justbur) +- Improve yasnippet loading robustness (thanks to myrjola) +- Fix showing snippets in company popup (thanks to person808) +**** Better-defaults +- Add =backward-kill-word-or-region= on ~C-w~ (thanks to justbur) +**** C/C++ +- Fix key bindings for cscope (thanks to bmag) +- Add =disaster= package to disassemble c/c++ code on key binding ~SPC m D~ + (thanks to jb55) +- Fix error with =company-mode/more-than-prefix-guesser= (thanks to TheBB) +**** Chinese +- Remove "symbol" from list of changed charsets, this prevents minor mode + lighters from being displayed in the Chinese font (thanks to louy2) +**** Clojure +- Add cider error buffer to popwin (thanks to cmccloud) +- Add cider-doc buffer to popwin (thanks to cmccloud) +- Add key bindings for =ein:traceback-mode= (thanks to toshism) +- Add ~SPC m s x~ key binding for =cider-refresh= (thanks to sooheon) +- Stop using deprecated =cider-jump-to-var= and use =cider-find-var= + instead (thanks to lukbock) +- Add ~SPC m T i~ to toggle indentation style in =clojure-mode= + (thanks to lukbock) +- Add ~SPC m T p~ key binding to toggle pretty printing in the REPL + (thanks to luxbock) +- Add new key bindings to evilified buffer =cider-inspector-mode= + (thanks to luxbock) +- Add ~C-j~ and ~C-k~ for browsing history in the REPL (thanks to luxbock) +- Add more =clj-refactor= key bindings (thanks to luxbock) +- Add more key bindings to =cider-stacktrace-mode= (thanks to luxbock) +- Add interactive function =spacemacs/cider-toggle-repl-font-locking= to + toggle font-locking in the REPL (thanks to luxbock) +- Activate clojure-mode for *.boot files (thanks to usharf) +- Enable =fancify-symbols= for =clojurescript-mode=, =clojurec-mode= and + =clojurex-mode= (thanks to Xcix) +- Setup indentation rules for common clojure vars (thanks to jcf) +- Evilify =cider-test-report-mode= buffers (thanks to luxbock) +- Enable =clj-refactor= key bindings in the REPL (thanks to luxbock) +- Enable clojure key bindings in the REPL (thanks to luxbock) +- Fix bug in =spacemacs//cider-eval-in-repl-no-focus=: + - Move to point-max before inserting text + - Only indent the newly inserted form instead of the whole buffer. + (thanks to luxbock) +- Fix key bindings conflict in =cider-debug-mode= (thanks to luxbock) +- Rename old function =clfr-rename-file-or-dir= to new function + =cljr-rename-file= (thanks to luxbock) +- Remove ~SPC m d b~ =cider-debug-defun-at-point= in REPL (It doesn't do + anything other than messing up the buffer) (thanks to luxbock) +- Gives faster access to display the last error buffer with ~SPC m d e~ + (thanks to luxbock) +**** CSharp +- Set =omnisharp-auto-complete-want-documentation= to =nil= to work-around + a bug in standard Omnisharp server built in Release configuration. +- Add prefix command documentation (thanks to d12frosted) +**** Dash +- Add support for =zeal= on Linux and Windows (thanks to CestDiego) +**** Deft +- Replace deprecated =deft-extension= by new =deft-extensions= + (thanks to mclearc) +**** Elixir +- Remove flycheck due to a security issue in the Elixir compiler + (thanks to gilbertkennen) +- Add support for popwin for =mix= buffers (thanks to rhalukongor) +- Re-enable =magit-gitflow= since it is now compatible with Magit 2.1 + (thanks to gilbertkennen) +**** Emacs lisp +- Make =flycheck= aware of =loadpath= (thanks to CestDiego) +- Define =emacs-lisp-mode= key bindings for =lisp-interaction-mode= + (thanks to justbur) +- Fix ~SPC m e c~ to evaluate current form (thanks to justbur) +- Add ~SPC m e s~ to evaluate symbol under point (thanks to justbur) +**** ERC +- Add =ERC-SASL= for SASL authentication (thanks to CestDiego) +- Fix check for =dbus= availability on OS X (thanks to cmccloud) +**** ESS +- Change default value of =ess-enable-smart-equals= to nil (thanks to + izahn) +- Fix =company= back-end declaration (thanks to jcpetkovich) +**** Evil-commentary +- Add ~SPC ;~ for comment operator +**** Extra-lang +- Add =Stan= modeling language (thanks to alexanderrich) +**** Eyebrowse +- Add ~s~ for =switch-to-window-config= (thanks to rphillips) +- Add ~gt~ and ~gT~ key bindings to switch between workspaces + (thanks to joehillen) +**** Fsharp +- Allow fsharp-mode to determine build path (thanks to bsermons) +**** Git +- Make sure that git-commit is initialized so that Emacs can be used as + $GITEDITOR (thanks to thrnio) +- Remove some deprecated code (thanks to tko) +- Add documentation about =magit-push-always-verify= variable (thanks to + sooheon) +- Add ~escape~ key binding to =gitmessenger= (thanks to mijoharas) +- Add ~#f~ key binding in =magit-status= for =magit-gitflow-popup= (thanks to + gilbertkennen) +- Use =MELPA= version of =magit-gh-pulls= and fix its configuration (thanks to + cmccloud) +- Evilify =magit-hunk-section-map= (thanks to ralesi) +- Evilify =magit-stash-mode= (thanks to nixmaniack) +**** Github +- Properly evilify =gist-lists= buffer (thanks to cmccloud) +**** Gnus +- Move ~SPC m o~ to ~SPC m M~ since ~SPC m o~ is now reserved for users + (thanks to TheBB) +- Movw ~SPC m H~ to ~SPC m m~ (thanks to robbyoconnor) +**** Go +- Use exec-path-from-shell-copy-env to set =GOPATH= (thanks to jenanwise) +- Fix multiple paths support in =GOPATH= on Windows (thanks to galaxian) +- Move all oracle key bindings under ~SPC m o~ to ~SPC m r~ since ~SPC m o~ + is now reserved for users (thanks to TheBB) +- Adapt key bindings to conventions, ~SPC m b~ is now ~SPC m e~ and ~SPC m d~ + is now ~SPC m h~ (thanks to bogdanteleaga) +- Move ~SPC m r~ to ~SPC m r n~ which conflicted with oracle key bindings + (thanks to bogdanteleaga) +**** Gtags +- Fix eldoc configuration (thanks to thudo) +**** Haskell +- Make =ghc-mod= optional (thanks to michelk) +- Disable line highlighting when shm is enabled (thanks to d12frosted) +**** Html +- Add for CSS files ~SPC m z c~ and ~SPC m z o~ to contract and expand CSS + blocks (thanks to ralesi) +- Add ~SPC m g h~ (helm-css-scss) to =css-mode= (thanks to TheBB) +- Add support for =jade= files (thanks to robbyoconnor) +- Add flycheck for =slim= and =haml= modes (thanks to robbyoconnor) +- Add rainbow delimiters for =haml=, =jade= and =slim= modes + (thanks to robbyoconnor) +- Add =.eex= extension to =web-mode= (thanks to gilbertkennen) +- Add =.ejs= files to =web-mode= (thanks to robbyoconnor) +- Add =.twig= files to =web-mode= (thanks to axyz) +- Add =.asp= files to =web-mode= (thanks to TheBB) +- Add ~gj~ and ~gk~ key bindings to go to siblings elements in web micro-state + (thanks to TheBB) +- Enable =smartparens= in CSS like modes (thanks to TheBB) +- Fix extra space in declared pair <%= %> (thanks to dsdshcym) +- Fix ~r~ key bindings in web micro-state (thanks to CestDiego) +- Fix smartparens configuration (thanks to TheBB) +**** Ipython-notebook +- Move ~SPC m o~ and ~SPC m O~ to ~SPC m i~ and ~SPC m I~ since + ~SPC m o~ is now reserved for users (thanks to TheBB) +**** Java +- Diminish =eclim= minor mode lighter (thanks to Devagamster) +**** Javascript +- Add =json-snatcher= on ~SPC m h p~ (thanks to CestDiego) +**** Markdown +- Fix backticks and single quotes insertion (thanks to x-ji) +- Fix =smartparens= configuration (thanks to fintelkai) +- Move ~SPC m o~ to ~SPC m f~ since ~SPC m o~ is now reserved for users + (thanks to TheBB) +**** Org ++ Install =org-plus-contrib= from org ELPA repository ++ Add table related key bindings on =SPC m t= (thanks to JP-Ellis) ++ Add defer loading for =toc-org=. ++ Add =gnuplot= package to plot data from tables (thanks to JP-Ellis) ++ Add =org-mime= (moved from =gnus= layers) ++ Add new key bindings to move whole subtrees up/down/right/left with ~SPC m S~ + prefix (thanks to katshinka) ++ Add new key bindings to move between complex TODO sets with ~SPC m C-S~ + prefix (thanks to katshinka) ++ Add more cycling options for time-stamps, headlines, items, properties with + ~SPC m L~, ~SPC m K~, etc... (thanks to katshinka) ++ Add key bindings ~SPC m .~ to insert time-stamps (thanks to katshinka) ++ Set =toc-org-max-depth= to 10. ++ Move ~SPC m o~ to ~SPC m l~ since ~SPC m o~ is now reserved for users + (thanks to TheBB) ++ Ensure that =org-directory= exists on load (thanks to ralesi) ++ Fix ~SPC m l~ by calling =org-open-at-point= instead of =evil-org-open-links= + (thanks to TheBB) ++ Fix org-repo-todo loading (thanks to TheBB) +**** Osx +- Re-factor and expand support for trash can (thanks to usharf) +- Add support for =launchctld= (thanks to usharf) +- Add new key binding to toggle fullscreen which should fix the usage + of left command key for this command (thanks to sooheon) +- Change obsolete =new-frame= function to =make-frame= (thanks to fintelkai) +**** Pandoc +- Add =ox-pandoc= package (thanks to jcf) +**** Php +- =php-extras= is not correctly installed +- Enable flycheck (thanks to rakyi) +**** Puppet +- Enable =flycheck= support (thanks to tko) +**** Python +- Apply new conventions for test key bindings +- Fix =anaconda-mode= key bindings for latest version of =anaconda-mode= + package (thanks cpaulik) +- Fix =py-yapf= for =yapf= >= 0.3.0 (=yapf= now returns 2 if source code was + changed) (thanks to a-sk) +- Use =quit-window= to close documentation popup (thanks to cpaulik) +- Enable =evil-matchit= (thanks to robbyoconnor) +- Move anaconda server cache files to =.cache= directory (thanks to person808) +**** Racket +- Enable insert state after ~SPC m s B~ accordingly to the conventions + (thanks to jmiven) +**** Ranger +- Fix =ranger-up-directory= key binding on ~-~ (thanks to ralesi) +**** Ruby +- Use =enh-ruby-mode= on interpreter-detected ruby files. This makes + ruby files that start with shebang ruby directives use =enh-ruby-mode= + (thanks to jenanwise) +- Add some =ruby-tools= key bindings (thanks to chrismcg) +- Enable =evil-matchit= (thanks to robbyoconnor) +**** Ruby-on-rails +- Activate =projectile-rails= mode for any type of files in a rails + project (thanks to liuxiang) +**** Rust +- Add =racer= package (thanks to cdlm) +**** Salt +- Add =salt-mode= package (thanks to beardedprojamz) +**** Scala +- Add binding for =ensime-pop-find-definition-stack= on ~SPC m g p~ + (thanks to alexanderkjeldaas) +- Remove key binding ~SPC m ?~ (thanks to Profpatsch) +**** Scheme +- Add support for Geiser (thanks to kingcons) +**** Search-engine +- Add Bing (thanks to Devagamster) +- Add Spacemacs Pull Requests +**** Shell +- Add =eldoc= support in eshell (thanks to ppold) +- Add a better prompt via =eshell-prompt-extras= for eshell (thanks to ppold) +- Add visual commands to eshell (thanks to ppold) +- Add support for =smart eshell= in eshell via the layer variable + =shell-enable-smart-eshell= (thanks to ppold) +- Add auto-completion support for eshell (thanks to trishume) +- Automatically jump to prompt in insert state in eshell buffers (thanks to + trishume) +- Add support for leader in =multi-term= (thanks to martinmr) +- Deactivate eshell automatic auto-completion popup for remote path since it + can be slow, the popup must be called manually in remote paths + (thanks to myrjola) +- Fix =magit-status= alias for =eshell= (thanks to myrjola) +- Protect the =eshell= prompt from deletion with evil commands. A new + layer variable =shell-protect-eshell-prompt= allows to opt-out this behavior + (thanks to myrjola). +**** Syntax-checking +- Add ~SPC e l~ to toggle error list buffer (thanks to bmag) +- Add ~SPC e v~ to verify the flycheck setup (thanks to bmag) +- Add ~SPC e h~ to describe the flycheck checkers (thanks to bmag) +**** Vinegar +- Show symlink paths (thanks to ralesi) +**** Wakatime +- Add ~SPC a W~ to open the Wakatime dashboard in the browser + (thanks to CestDiego) +*** Core changes +- Add =with-eval-after-load= backport (thanks to justbur) +- Add new key bindings to evilified buffers: ~g~, ~GG~, ~C-b~, ~C-f~, ~C-d~ + and ~C-u~ (thanks to sooheon) +- Add ~C-z~ in =evilified-state= to switch to =emacs-state= for the next + command (thanks to justbur) +- Add =:eval-after-load= keyword to =spacemacs|evilify-map= macro +- Remove ~y~ from evilified state keymap, use a visual selection instead. +- Fix visual state key bindings in evilified buffers +- Prevent auto-evilification of buffers from overwriting ~C-g~ +- Rewrite on =evilify-map= macro which is now simpler and more robust +- Add on and off functions to toggles (thanks to TheBB) +- Add new function =spacemacs/describe-system-info= which put useful + information in the clipboard, ready to be pasted in an IRC channel for + instance (thanks to swaroopch) +- Add new functions =configuration-layer/declare-layer= and + =configuration-layer/declare-layers= which can be used in =config.el= files + of a layer to add required layers. +- Add macro =dotspacemacs|symbol-value= with new special variable value + =display-graphic-p=. This variable will evaluate =(display-graphic-p)= + when called with =dotspacemacs|symbol-value=. Use this special value + to be able to have unicode symbol in GUI client but not in terminal + clients. +- Add missing =spacemacs/= function prefix (thanks to person808) +- Add choice of distribution on install (thanks to justbur) +- Add distribution name in home buffer +- Add distribution to =spacemacs/describe-system= (thanks to TheBB) +- Rewrite evil-leader keys handling to make ~M-m~ work correctly + (thanks to justbur) +- Replace =after-init-hook= with better hook =emacs-startup-hook= + (thanks to vkz) +- Fix some crashes when a package cannot be updated and warn about such + packages when updating (thanks to bmag) +- Fix ~SPC u~ not repeating universal-argument (thanks to luxbock) +- Fix Spacemacs Home Buffer to jump to bookmarks (thanks to travisbhartwell) +- Fix =ace-link= in spacemacs buffer (thanks to avoine) +- Fix an issue with Emacs 25 in =init.el= (not yet officially supported) + (thanks to justbur) +- Fix ~return~ binding in terminal in home buffer(thanks to d12frosted) +- Fix custom banner path (thanks to d12frosted) +- Fix inconsistent detection of orphaned packages to delete +- Set =gc-cons-threshold= to 100MB and define it in =init.el= +- Use =package-alist= to resolve orphans +- Better indentation for =spacemacs|add-toggle= macro (thanks to TheBB) +- Remove some dead code for =use-package= (thanks to TheBB) +- Remove =tooltip-use-echo-area= usage which is obsolete since Emacs 24.1 + (thanks to xfq) +- Remove duplicate call to =dotspacemacs/init= (thanks to sooheon) +- Display home buffer links even when no banner are displayed + (thanks to sooheon) +- Better centering of text in the home buffer +*** Other fixes and improvements +- Add contribution guidelines =CONTRIBUTE.md= (thanks to robbyoconnor) +- New documentation on layers (thanks to TheBB) +- Suppress byte compiler warnings on startup (thanks to justbur) +- Reactivate prefix command names since they are working correctly with + =which-key= (were also working with =guide-key=) (thanks to martinmr) +- Delete deprecated =!user= contrib directory. +- Removed lasts git submodules, Spacemacs is now submodule free! +- Typos and documentation improvements (thanks to agzam, alexanderkjeldaas, + andyque, benwooth, BrianHicks, catern, cgrinds, d12frosted, Devagamster, + gleber, Immortalin, jgertm, JinweiClarkChao, jmiven, JorisE, JoshTGreenwood, + justbur, luxbock, mbertheau, mortonfox, nwolfe, oneeman, person808, rakyi, + sotte, robbyoconnor, robmerrell, screamish, sooheon, srid, swaroopch, syohex, + travisbhartwell, x-ji, xfq, zmthy) +* Release 0.103.x +** 0.103.6 (2015/08/30) +*** Core +- Fix error with ~SPC h b~ (bookmarks) (thanks to sgepigon) +** 0.103.5 (2015/08/09) +*** Layer changes +**** Osx +- Fix initialization of =reveal-in-osx-finder= (thanks to fintelkai) +*** Core +- Temporarily switch to HTTP instead of HTTPS to communicate with + elpa.gnu.org (thanks to robbyoconnor) +** 0.103.4 (2015/08/07) +*** Layer changes +**** Clojure +- Fix key bindings for new Clojure major modes: =clojurec-mode=, + =clojurescript-mode= and =clojurex-mode= (thanks to benalbrecht) +** 0.103.3 (2015/08/04) +*** Layer changes +**** Osx +- Rename =reveal-in-finder= to its new name =reveal-in-osx-finder= + (thanks to syohex) +** 0.103.2 (2015/07/04) +*** Layer changes +**** Git +- Fix =magit-repository-directories= variable name (thanks to travisbhartwell) +- Fix =magit-blame= key binding (thanks to jenanwise) +- Use =magit-log-all= instead of =magit-log= on ~SPC g l~ (thanks to tuhdo) +*** Other fixes and improvements +- Typos and documentation improvements (thanks to cscorley, dstcruz, h3dkandi, + kccai, MadAnd, person808, Profpatsch, stnly, stormpat, xfq, zachlatta) +** 0.103.1 (2015/07/02) +*** Layer changes +**** Git +- Fix ~F~ in Vim style in =Magit= status buffer, now ~F~ is correctly + bound to =pull= popup menu +- Fix intermittent erroneous ~k~ key binding in =Magit= status buffer. +*** Core +- Fix mandatory dependency on =evil-escape= +- Fix evilification of =evil-escape= starter key +** 0.103.0 (2015/07/01) +*** IMPORTANT: Breaking changes +- Spacemacs is now compatible only with =Magit 2.1= and later, be + sure to update your packages. +- =auctex= layer has been renamed =latex=, be sure to update your + dotfile if you use this layer. +- =erlang/elixir= layer has been split into two layers =erlang= and + =elixir=, be sure to update your dotfile if you use these layers. +- =git= layer has been split into two layers: =git= and =github= so + the layer variable =git-enabled-github-support= is deprecated, you + have to add the layer =github= in your dotfile. +- =git-gutter= has been replaced by =diff-hl=. This package is in + the new layer =version-control=, be sure to add this new layer to + your dotfile. +- Projectile key bindings changes: + ~SPC p e~ is now ~SPC p r~ (recent files) + ~SPC p R~ is now ~SPC p G~ (regenerate tags) + ~SPC p r~ is now ~SPC p R~ (replace) +*** Hot new features +- Add support for Magit 2.1! +- Helm now uses its header to display the input pattern. +- Use Flycheck default configuration to check the current buffer in + "real time" (yes this is a hot new features :-)) +- New interactive function =spacemacs/switch-to-version=, it will ask + for a version number and warn if the current branch is not =master=. + Users on =develop= branch cannot use this function (it has no effect). +- Clicking on the up arrow in the mode-line will now update Spacemacs. + A prompt asks for confirmation before updating. +- New "tool assisted" search and replace interface supporting =ag=, =pt=, + and =ack= with a new key binding scheme. Check the documentation for + =searching with an external tool=. +*** New Layers +- elixir (split from =erlang-elixir=) +- erlang (split from =erlang-elixir=) +- github (split from =git=) +- ipython-notebook (ein) (thanks to CestDiego) +- latex (renamed from =auctex=) +- version-control +*** Dotfile changes +- New variable =dotspacemacs-auto-save-file-location= which enable or + disable auto-saving of modified files. Possible values are =original= to + auto-save the file in-place, =cache= to auto-save the file to another + file stored in the cache directory and =nil= to disable auto-saving. + Default value is =cache=. +*** Layer changes +**** Spacemacs +- Add text alignment key bindings on ~SPC x a~ prefix (thanks to justbur and + TheBB) +- Remove the kill ring from =savehist-additional-variables= to avoid an issue + with abnormal high size of =savehist= file (thanks to tuhdo) +- Add documentation files to =helm-spacemacs= (thanks to person808) +- Add support for =.org= files in =helm-spacemacs= (thanks to tuhdo) +- Add explicit titles for documentation files in =helm-spacemacs= + (thanks to tuhdo) +- Remove the dependency on =f= library in =helm-spacemacs= + (thanks to person808) +- Revert ~C-o~ in =holy-mode= since it shadows too many packages key bindings + (thanks to tuhdo) +- Evilify =helm-ag= and =helm-grep= buffers (obtained by pressing ~f3~ in + the helm buffer while searching) (thanks to cpaulik) +- Search with =ag=, =pt= and =ack= are done with the same interface based on + =helm-ag= +- Add search integration in =expand-region= and =auto-highlight-symbol= + (thanks to justbur) +- Update search with =grep= to match the new search interface + (thanks to justbur) +- Quote input when default text is used in search (thanks to justbur) +- =smart-search-project= on ~SPC /~ now fallback to searching files in current + directory when there is no project (thanks to justbur) +- Replace =dired-goto-file= with =helm-find-files= in Dired (thanks to tuhdo) +- Add support for .org files to ~SPC s l~ key binding, it allows to quickly + jump to file headers using Helm (thanks to tuhdo) +- Re-enable =auto-save= mode (thanks to tuhdo) +- Set =:defer 1= in =helm= initialization (which means that helm will be + auto-loaded automatically after 1 second of idle time) +- Fix =helm-resume= opening window in half of split screen (thanks to sooheon) +- Use =helm= header to display the input pattern (thanks to tuhdo) +- Fix =open-in-external-app= when the buffer is not visiting a file + (thanks to travisbhartwell) +- Prevent paste micro-state to be triggered by ~C-r~ in =insert state= +- Projectile key bindings changes: + ~SPC p e~ is now ~SPC p r~ (recent files) + ~SPC p R~ is now ~SPC p G~ (regenerate tags) + ~SPC p r~ is now ~SPC p R~ (replace) +- Remove =comint-delchar-or-maybe-eof= on ~C-d~, it fixes ~C-d~ scroll down + behavior in =normal state=, user has to press the stock binding ~C-c C-d~ + to send an =EOF= (thanks to kini) +**** Auto-completion +- Yasnippet: Default =helm-yas-display-key-on-candidate= to =t= (thanks to + BrianHicks) +- Yasnippet: Disable =smartparens= while expanding to fix a bug with + =hippie-expand= (thanks to tuhdo) +- New layer variable =auto-completion-enable-snippets-in-popup= to add + snippets directly to auto-completion popup (thanks to person808) +**** Autohotkey +- Fix =.ahk= file extension declaration (thanks to ralesi) +**** C/C++ +- Add package =gdb-mi= (gdb-many-windows) which enables an IDE like debugger + frontend for Emacs (thanks to tuhdo) +**** Clojure +- Add ~SPC e w~ to eval last sexp and replace it with the result (thanks to + DayoOliyide) +- Evilify Cider inspector (thanks to ppold) +**** Elixir +- List all Elixir key bindings in README +- Update configuration to support new =alchemist= 1.0 feature (thanks to tonini) +- Enable auto-completion support +**** Emacs Lisp +- Add new Spacemacs snippets =micro-state= and =new-package= (thanks to + CestDiego) +- Add (f)ielm-indent-line for =ielm= mode (thanks to BlinkD) +**** Emoji +- Remove the extension and use the MELPA package +**** ERC +- Use =erc-yank= on ~p~ in normal state if =gist= package is available + (thanks to CestDiego) +**** Evil-snipe +- Update configuration to support last upstream changes (thanks to hlissner and + MadAnd) +**** Extra-langs +- Enable =QML= mode for =.qml= files (thanks to bennofs) +**** Eyebrowse +- Add support for workspace labels (thanks to rphillips) +**** Finance +- Evilify =ledger-report-mode= (thanks to darkfeline) +**** Git +- Replace =git-gutter= by =diff-hl= (thanks to tuhdo) +- Remove =gc= prefix command as unused from guide-key (thanks to tko) +- Add =magit-diff= key binding on ~SPC g d~ (thanks to kevinushey) +- Evilify =magit-diff= buffer +- Implement fullscreen for =Magit= without advices (thanks to tarsius) +- Fix whitespace toggles for =Magit= (thanks to tarsius) +- Remove deprecated =magit-last-seen-setup-instructions= (thanks to tarsius) +- Move whitespace toggle in =Magit= to ~C-S-w~ +- Add ~SPC g L~ to display the log for the current file (thanks to tko) +**** Go +- Add ~SPC m g a~ to switch between tests and implementation (thanks to + jenanwise) +**** Gtags +- Enable =helm-gtags= for =compilation-mode= and =shell-mode= (thanks to tuhdo) +**** Haskell +- Add =company-cabal= support for auto-completion in =.cabal= files (thanks + to bjarkevad) +- Fix error with =electric-indent-local-mode= in some versions of Emacs + (thanks to jeremyjh) +**** iPython-notebook (ein) +- Add key bindings on major-specific leader (thanks to cpaulik) +- Add ~C-RET~ and ~S-RET~ key bindings to behave like the =ein= web interface + (thanks to cpaulik) +- Bind ~SPC f s~ to save the notebook (thanks to cpaulik) +**** LaTeX +- Add support for =RefTeX= (thanks to JP-Ellis) +- Add support for =LatexMk=, to enable it set the layer variable + =latex-build-command= to ="LatexMk"= (thanks to JP-Ellis) +- Use =auto-fill-mode=, with an environment-aware auto-fill function, you + can enable =auto-fill= support by setting the layer variable + =latex-enable-auto-fill= to =t=. You can also inhibit it in some environments + with the variable =latex-nofill-env= (thanks to JP-Ellis) +- Remove =build-view= in favour of just =build= as it seemed to be + broken and introduce ~SPC m v~ to view (thanks to JP-Ellis) +- General settings should now be easier to override in =dotspacemacs/config= +- Fix errors due to layer renaming (thanks to JP-Ellis and autosquid) +**** Markdown +- Add font-locking for code blocks (thanks to kennethlove) +- Add support for a bunch of languages for code blocks (thanks to dexafree) +**** Ocaml +- Don't auto-close backticks (thanks to edwintorok) +**** Org +- Fontify code blocks (thanks to tuhdo) +- Add =toc-org= package (thanks to CestDiego) +- Tweak org-pomodoro mode-line integration (Add missing leading space) +- Move =org-clock-save.el= to cache folder (thanks to BlinkD) +- Add key binding ~SPC m :~ for =org-set-tags= (thanks to cpaulik) +**** Osx +- New variable =osx-use-option-as-meta= allowing to enable or disable the + mapping of =option= key to =meta= key. This is especially useful for some + European keyboard layouts like Finish or Swedish (thanks to tko) +- Add ~⌘ +~ and ~⌘ -~ key bindings to scale text (thanks to JoshTGreenwood + and zimbatm) +- Only update =dired-use-ls-dired= if =gls= was found on path (thanks to + usharf) +- Add reveal in finder on ~C-⌘ f~ (thanks to usharf) +- Add key bindings ~⌘ a~ (select all) ~⌘ W~ (close frame) and ~⌘ n~ (new frame) + (thanks to mveytsman) +- Fix ~⌘ v~ paste behavior (thanks sooheon) +**** Powershell +- Add ~SPC a s p~ to start a =powershell= buffer (thanks to ralesi) +- Add ~SPC m r r~ for =powershell-regexp-to-regex= (thanks to ralesi) +- Add =$(= text object (thanks to ralesi) +**** Puppet +- Add Puppetfile support (thanks to nwolfe) +**** Python +- New supported test runner: =pytest= (thanks to cpaulik) +- New layer variable =python-test-runner= to choose between =nose= and + =pytest= +- Set =indent-tabs-mode= to =t= in REPLs, should fix indent errors (thanks to + tuhdo) +- Fix a loading bug due to a typo in =latex= layer (thanks to cpaulik) +**** Racket +- Fix not working =electric-pair-skip= (thanks x-ji) +**** Ruby +- Fix some annoyance with deep indentations (thanks to trishume) +**** Rust +- Add support for =flycheck= (thanks to swaroopch) +- Add support for auto-completion via =racer= (thanks to JP-Ellis) +- Use =compile= instead of the shell for =cargo=. This allow Emacs to parse the + output, including all the errors (thanks to JP-Ellis) +**** Scala +- Set classpath directory of =ensime= to =.cache/ensime= (thanks to cyrillk) +**** Slime +- Add a bunch of key bindings (thanks to spigo900) +**** Syntax-checking +- Now use the =flycheck= default configuration to trigger checks. Checks + are now performed live (thanks to tuhdo and thrnio) +**** Theme +- Add spacemacs-theme! (WIP) (thanks to nashamri) +- Add tao theme (thanks to elais) +*** Core +- New interactive function =spacemacs/switch-to-version= +- Clicking on the up arrow will now update Spacemacs +- Add a link to Vimmers guide in quick help of startup buffer (thanks to + person808) +- Enable =use-package-verbose= when =dotspacemacs-verbose-loading= + is set to =t= +- Better name for placeholders in layer templates (thanks to kini) +- Beautify change log (thanks to tuhdo) +- Layers are now auto-discovered recursively which allow arbitrary + directory hierarchy. Directory names starting with =!= are categories. + (thanks to TheBB) +- Fix regression when =dotspacemacs-startup-banner= is set to =nil= + (thanks to ptb) +- Fix home buffer keys in terminal (thanks to tuhdo) +- Fix bookmark list in home buffer (thanks to fandag) +- Add support for =material-light= theme (thanks to cpaulik) +- Use SSL to contact elpa repositories when possible (thanks to zimbatm) +- Emacs 25 required the line =(package-initialize)= in the =init.el= + file (thanks to justbur) +- Add the possibility to call =configuration-layer/update-packages= in + batch mode (thanks to travisbhartwell) +*** Other fixes and improvements +- Conversion of all layer README.md files to .org (thanks to CestDiego + and cpaulik) +- Conversion of documentation files to .org (thanks to person808) +- Add a guide for Vimmers in =doc= directory (thanks to person808) +- Typos and documentation improvements (thanks to cloudbring, duerrp, dxnn, + dvberkel, fotoetienne, JoshTGreenwood, kccai, OliverM, MadAnd, person808, + robbyoconnor, royseto, swaroopch, travisbhartwell, tuhdo, xfq) +* Release 0.102.x +** 0.102.2 (2015/06/03) +*** Layer changes +**** Org +- Fix bug with =ox-gfm= by moving it to extensions +*** Core +- Fix detection of new versions by correctly fetch latest changes +** 0.102.1 (2015/06/01) +*** Layer changes +**** Org +- Fix lazy-loading of =ox-gfm= package. +*** Core +- Catch layer variables syntax errors +** 0.102.0 (2015/05/31) +*** IMPORTANT: Breaking changes +- All Emacs Lisp related configuration has been moved to its own layer + called =emacs-lisp=, be sure to add this layer to your dotfile. +- All shell related configuration has been move to its own layer called + =shell=, be sure to add this layer to your dotfile if you use a shell + inside Emacs. +- Key binding to reload the dotfile is now ~SPC f e R~ instead of + =C-c C-c= or ~SPC m c c~. Note that ~SPC f e R~ can be triggered + anywhere (it is not restricted to the dotfile anymore). +- Key binding to switch buffer is now ~SPC b b~ instead of ~SPC b s~. +- ~SPC f f~ now uses =helm-find-files= instead of =ido=, use the new + dotfile variable =dotspacemacs-use-ido= to get the old behavior back. +- Helm ~TAB~ and ~C-z~ key bindings have been *swapped*. +- By default *single space* sentence delimiter is defined. +- Layer variable values set with =:variables= keyword need to be quoted + like in a regular =setq= expression. +*** New Layers +- Agda (thanks to ocharles) +- Chrome (thanks to beardedprojamz) +- D (thanks to trishume) +- Deft (thanks to trishume) +- Emacs-lisp +- Emoji +- Eyebrowse +- Games (thanks to nashamri) +- Gnus (thanks to cpaulik) +- Gtags (thanks to tuhdo) +- iBuffer (thanks to alex-glv) +- Pandoc (thanks to cpaulik) +- Prodigy (thanks to CestDiego) +- Purescript (thanks to kofno) +- Rust (thanks to mkaito) +- Salt (thanks to beardedprojamz) +- Search Engine (thanks to CestDiego) +- Semantic (thanks to tuhdo) +- Shell +- Spotify (thanks to BrianHicks) +- Sql (thanks to BrianHicks) +- TypeScript +- Vim-powerline +*** Dotfile changes +- New variable =dotspacemacs-search-tools= which is a list of search tool + executable names. Spacemacs uses the first installed tool of the list + with search related key bindings (~SPC /~, ~SPC s ...~). + Supported tools are =ag=, =pt=, =ack= and =grep=. +- New variable =dotspacemacs-highlight-delimiters= which selects a scope + to highlight delimiters. Possible value is =all=, =current= or =nil=. + Default is =all=. (thanks to tuhdo) +- New variable =dotspacemacs-additional-packages=. Adding packages to + this list will install them without needing them to be wrapped in a + layer. Ideal for quickly add a package. The package configuration + can be put in =dotspacemas/config=. +- New variable =dotspacemacs-use-ido=. If non nil then =ido= replaces =helm= + for some commands. For now only =find-files= (SPC f f) is replaced. +- New key binding ~SPC f e D~ to open an =ediff= buffer between the user + dotfile and the current template. +- Disable paste micro-state by default, i.e. set the variable + =dotspacemacs-enable-paste-micro-state= to =nil= in the dotfile template. +*** New conventions +- Add conventions for markup languages like =markdown= or =org= + (thanks to cpaulik) +*** Layer changes +**** Spacemacs +- Auto-indent when pasting use the universal argument to not auto-indent + (thanks to tuhdo) +- Fix =global-mode-string= for mode-line (thanks to 3marcusw) +- Display =guide-key= buffer at the bottom instead of the right so we get + more space. Also fix some issues with other popup interaction. +- Use single space sentence delimiter (thanks to roryk) +- Restore maximized frame state with =zoom-frm= (thanks to ralesi) +- Improve =golden-ratio= excluded buffers coverage (thanks to tuhdo) +- Add missing =evil-window-*= commands to =golden-ratio= managed commands + (thanks to riclima) +- Add CamelCase motion toggle to =subword-mode= (thanks to mkcode) +- Add =open-junk-file= package which allows to quickly create a junk file + in =.cache= directory. Bound to ~SPC f J~ (thanks to tuhdo) +- Add ~SPC T s~ to toggle semantic-stickyfunc (thanks to cpaulik) +- Add ~SPC b Y~ and ~SPC b P~ to copy/paste whole buffer (thanks to swaroopch) +- Add ~SPC h d b~ to =describe-bindings= (thanks to mkcode) +- Add toggle to hide/show the mode line on ~SPC t m t~ (thanks to jupl) +- Add =move-text= micro-state +- Add =highlight-parentheses= package which can activated by setting + =dotspacemacs-highlight-delimiters= to =current= (thanks to tuhdo) +- Add =clean-aindent-mode= package to cleanly delete virtual indentation + (thanks to tuhdo) +- Move =yasnippet= and =hippie-exp= to =auto-completion= layer. +- Move =multi-term= and shell packages to new =shell= layer +- Move =flyspell= and =helm-flyspell= to =syntax-checking= layer +- Move ~SPC b r~ to ~SPC f R~ (rename file) +- Move some toggles key bindings which are now: + - ~SPC t s~ for syntax checking + - ~SPC t S~ for spelling checking + - ~SPC t f~ for fill column + - ~SPC t F~ for auto-fill + - ~SPC t c~ for camelcase +- Move =sp-local-pair= to =:config= of =smartparens= so user can override + them (thanks to person808) +- Remove ~SPC b 0~ and ~SPC b $~ redundant key bindings (thanks to tuhdo) +- Remove all themes from the layer (since now themes are not + automatically uninstalled). +- Don't use the minibuffer for =scroll= micro-state +- Don't close compilation buffer after success (thanks to TheBB) +- Make =trailing-whitespace= face more subtle (thanks to tuhdo) +- Beautify whitespace highlighting (thanks to tuhdo) +- Make inactive window face of mode-line compatible with more themes + (thanks to tuhdo) +- Fix the =recentf-exclude= variable, now cache folder is correctly excluded + (thanks to rcherrueau) +- Fix global toggle for whitespace. +- Fix for new line insertions with ~SPC i~ (thanks to nashamri) +- Fix =spray= cursor issue when quitting. +- Tweak =fci-mode= face color, should be better in most themes + (thanks to tuhdo) +- Improve =smooth-scroll= configuration (thanks to sooheon) +- Refactor =spacemacs/init-evil-lisp-state= to use =use-package= + (thanks to mveytsman) +***** Helm +- Switch commands for ~Tab~ and ~C-z~ in Helm (thanks to darkfeline) +- Remove Helm header line to make it clearer (thanks to tuhdo) +- Manually manage =popwin= to improve popup window interactions (thanks to + tuhdo) +- Enable fuzzy matching in Helm (thanks to ralesi) +- Turn on colors in =helm-swoop= (thanks to danielwuz) +- Render README.md file of layers with =Open README= action of + =helm-spacemacs=, use the universal argument ~C-u~ to open + the file without rendering it (thanks to tuhdo) +- Add dotfile variables helm source to =helm-spacemacs= +- Add support for extensions in =helm-spacemacs= +- Use =helm-pp-bookmarks= instead of =helm-bookmarks= (thanks to darkfeline) +- Move ~C-SPC~ on ~M-SPC~ and ~S-M-SPC~ for =helm= and =ido= micro-states. +- Make =helm-find-files= =backspace= key behave like =ido= (thanks to tuhdo) +- Fix aggressive manipulation of =face-remapping-alist= in =helm= and =ido= +- Automatically create directories if needed when renaming a file (thanks to + env0der) +- Replace =helm-projectile-vc= (which does not exist) by =projectile-vc= + (thanks to swaroopch) +- Fix =toggle-maximize-buffer= (thanks to tuhdo) +***** Evil +- Use non-visual lines for j/k navigation (thanks to mlsteele) +- Enable =evil-execute-in-normal-state= in =holy-mode= +- Better default face for =evil-search-highlight-persist-highlight-face= + (thanks to tuhdo) +- Add visual state mapping for =<= and =>= to =gv= respectively + (allow to indent a region several times). +- Add =spacemacs/smart-goto-definition= which attempts to call + ~SPC m g g~ and falls back to =evil-goto-definition= if that fails + (thanks to luxbock) +- Replace ~C-o~ with ~M-o~ in =dired= buffer since ~C-o~ is replaced with + =evil-execute-in-normal-state= (thanks to tuhdo) +- Make =evil-smart-*= functions respect the leader key (thanks to person808) +- Advice =evil-jump-to-var= with =evil-set-jump= (thanks to luxbock) +- Temporary hack to speed up =ace-jump-line= (~SPC l~) as an evil motion. +**** Auctex +- Add =RefTeX= package (thanks to rpglover64) +- Add =flycheck= support +- =build-view= always recompile TeX (thanks to kvelicka) +**** Auto-completion +- New variables: + - =auto-completion-return-key-behavior= set the action to perform when the + ~RET~ key is pressed, the possible values are =complete= and =nil=. + - =auto-completion-tab-key-behavior= set the action to perform when the + ~TAB~ key is pressed, the possible values are =complete=, =cycle= and =nil= + - =auto-completion-complete-with-key-sequence= is a string of two characters + denoting a key sequence that will perform a =complete= action if the + sequence has been entered quickly enough. If its value is =nil= then the + feature is disabled. + - Default values are ~RET~ -> =complete=, ~TAB~ -> =cycle= and sequence is + =nil= +- Rename =auto-completion-enable-company-help-tooltip= to + =auto-completion-enable-help-tooltip= +- Add support for =company-statistics=, to activate it set the layer variable + =auto-completion-enable-sort-by-usage= to =t= (thanks to person808) +- Add =auto-yasnippet= package on ~SPC i S~ (thanks to tuhdo) +- Disable =company-tooltip-flip= (thanks to tuhdo) +- Allow a snippet to wrap around a selected region when expanded, + press ~C-x C-x~ to go to the original mark and run =yas-expand= + to wrap the selected region in expanded snippet. (thanks to tuhdo) +- Allow =hippie-expand= to expand snippets (thanks to tuhdo) +- Remove =company-yasnippet= backends use ~SPC i s~ and ~C-p~ +- Fix =company= and =fci-mode= incompatibility (thanks to tuhdo) +- Fix wrong creation location for new snippets with =yas-new-snippet= (thanks + to CestDiego) +- ~SPC t a~ now correctly toggle =company= by default. +- Remove unneeded =yasnippet-snippets= submodule (thanks mkcode) +- Better lazy-loading of =yasnippet= (thanks to tuhdo) +**** Autohotkey +- Use MELPA package (thanks to ralesi) +**** C/C++ +- New layer variable =c-c++-enable-clang-support= +- New layer variable =c-c++-default-mode-for-headers= (thanks to ceales) +- Remove unnecessary =auto-mode-alist= (thanks ceales) +- Add =clang-format= support (thanks to gnzlbg) +**** Chrome +- Add better integration with edit-server package (thanks to CestDiego) +- Added Gmail messages support with =ham= mode (thanks to CestDiego) +**** Clojure +- Add binding to connect to REPL in Cider on ~SPC m s c~ (thanks to jcsims) +- Add ~SPC m t a~ to reload test namespace before running all tests (thanks to + voxdolo) +- Add ~SPC m t r~ to reload test namespace and re-run failed tests (thanks to + voxdolo) +- Add ~SPC m t t~ to reload test namespace and run focused test (thanks to + voxdolo) +**** Colors +- Add =rainbow identifiers= color profiles for =gotham= and + =material= themes. +- Add colorization of keywords and function names for + =rainbow identifiers=. +- New variable =colors-theme-identifiers-sat&light= to set default + lightness and saturation for a given theme. +**** Emacs-lisp +- Move ~SPC m f~ bindings for code formatting to ~SPC m =~ +- Add =macrostep= package with a micro-state on ~SPC m d m~ + (thanks to person808) +**** Erc +- Add ERC channels to mode-line (thanks to swaroopch) +- Add ~SPC a i i~ key binding to switch to active ERC channels (thanks + to swaroopch) +- Highlight nicks using =erc-hl-nicks= (thanks to CestDiego) +- Image inline support using =erc-image= (thanks to CestDiego) +- Logging to ~/.emacs.d/.cache/erc-logs (thanks to CestDiego) +- =ViewLogMode= for viewing logs (thanks to CestDiego) +- YouTube videos Thumbnails inline using =erc-yt= (thanks to CestDiego) +- Social Graph for ERC messages using =erc-social-graph= (thanks to CestDiego) +**** ESS +- Fix lazy-loading of packages (thanks to jcpetkovich) +- Update to take care of the merge of =company-ess= in =ess= + (thanks to jcpetkovich) +**** Extra-langs +- Add =matlab= package (thanks to TheBB) +**** Git +- Make =git-gutter= key bindings work with or without the fringe (thanks + to person808) +- Fix =git-gutter= and =linum-mode= integration (thanks to person808) +- Fix =s= key binding to stage item in visual state. +- Replace =with-eval-after-load= by =eval-after-load= (compatible with 24.3) + (thanks to person808) +- Disable =evil-snipe= in =magit-status-mode= (thanks to person808) +- Enable =fci-mode= (fill column) in =git-commit-mode= (thanks to tuhdo) +- Add =helm-gitignore= package on ~SPC g I~ (thanks to jupl) +**** Gtags +- Add =helm-gtags-dwim-other-window= on ~SPC m g G~ (thanks to mijoharas) +**** Haskell +- ensure =haskell-indentation= is loaded before calling members (thanks + to chrisbarrett) +- fix misspelled references to keymaps (thanks to chrisbarrett) +- fix function names =identation= instead of =indentation= (thanks + to chrisbarrett) +- Fix =haskell-indentation= =eval-after-load= (thanks to chrisbarrett) +- Fix =ghci-ng= key bindings being overridden (thanks to bjarkevad) +- Use new package =haskell-snippets= +- Use =ghci-ng= for function =haskell-process-do-type-on-prev-line= (thanks to + bjarkevad) +**** Html +- Improve =web= micro-state key bindings (thanks to CestDiego) +- =emmet= key bindings fixes (thanks to louy2 and mkcode) +- Use only =smartparens= in =web-mode= (thanks to louy2 and mkcode) +- Add =eco= to =web-mode= =auto-mode-alist= (thanks to louy2 and mkcode) +- Fix buggy =T= key with =emmet= +- Add =company-web= package (thanks to CestDiego) +- Add a bunch of new pairs to =sp-local-pair= (thanks to CestDiego) +- Turn on =rainbow-delimiters= for =LESS= and =SCSS= (thanks to jupl) +**** Javascript +- Add =js-doc= package (thanks to geksilla) +- Add =web-beautify= package on ~SPC m =~ (thanks to elliotec) +- Apply key bindings conventions to some =tern= key bindings. +**** Lua +- Add support for auto-completion (thanks to mijoharas) +**** Markdown +- Add a bunch of new key bindings to improve consistency of key bindings + for markup languages, see [[https://github.com/syl20bnr/spacemacs/commit/7b6678efd6cece5bbb3419579590b843943f9e13][commit]] (thanks to cpaulik) +- Add markdown render buffer command on ~SPC m c r~ (thanks to CarlQLange) +- Add ~SPC m i k~ to insert =...= pairs (thanks to CestDiego) +**** Ocaml +- Add REPL using =utop= (thanks to edwintorok) +- Auto-indentation using =ocp-indent= (thanks to edwintorok) +- Add support for =company= auto-completion (thanks to edwintorok) +- Add support for =flycheck= syntax checking (thanks to edwintorok) +- New =merlin= key bindings (thanks to edwintorok) +**** Org +- Add a bunch of new key bindings to improve consistency of key bindings + for markup languages, see [[https://github.com/syl20bnr/spacemacs/commit/7b6678efd6cece5bbb3419579590b843943f9e13][commit]] (thanks to cpaulik) +- Use =org-startup-indented= instead of a hook so users can easily +remove =org-indent-mode= (thanks to darkfeline) +- Add support for =org-pomodoro-clock= to mode-line (thanks to swaroopch) +- Add =org-present= package (thanks to swaroopch) +- Add ~SPC m j~ for =helm-org-in-buffer-headings= (thanks to swaroopch) +- Add ~SPC m n~ for =org-narrow-to-subtree= (thanks to mattly) +- Add ~SPC m N~ for =widen= (thanks to mattly) +- Add ~SPC m i k~ to insert =...= pairs (thanks to CestDiego) +- Add =htmlize= package to enable syntax highlight in export HTML + (thanks to tetsusoh) +- Fix error with =org-async= (thanks to justbur) +**** Osx +- Make ~Command-s~ work with other modes (thanks to linktohack) +- Make =dired= use =coreutils gls= if installed (thanks to usharf) +**** Perforce +- Add a bunch of key bindings see [[https://github.com/syl20bnr/spacemacs/commit/6793eda4a90ee3a6c19c433b8676d5d9d8c3de76][commit]] (thanks to snandan) +**** Puppet +- Add =auto-completion= support (thanks to PierreR) +**** Python +- Add YAPF extension for buffer formatting (thanks to kennethlove) +- =nose.el= is now compatible with =virtualenv= (thanks to danielwuz) +- Add a function to remove unused imports =python-remove-unused-imports= + on ~SPC m c i~ (thanks to danielwuz) +- Add =pip-requirement= package (thanks to CestDiego) +- Enable =company= in Python REPL for code completion (thanks to tuhdo) +- Fix wrong extra parenthesis when inserting a breakpoint + (thanks to CestDiego) +- Don't enable Vim key bindings in REPL if =holy-mode= is active (thanks to + tuhdo) +- Fix Python and Semantic integration when no =python= executable can be + found on the system (thanks to tuhdo) +**** Rcirc +- Add =rcirc-track-minor-mode= to the =rcirc-mode-hooks= (thanks to + luxbock) +**** Ruby +- Fix =ruby-test-mode= initialization +- Fix auto-completion (thanks to trishume) +- Fix Rails mappings showing up in non rails projects (thanks to horrorvacui) +- Add =:A= ex-command which switches between implementation and test + (thanks to naliwajek) +- Remove overloading of function =erm-darken-color= +**** Rust +- Add key bindings for cargo build, run, test (thanks to swaroopch) +**** Scala +- Add ~SPC m d A~ to attach to remote debugger (thanks to siegelzero) +**** Semantic +- Create directory for =semanticdb= if it doesn't exist (thanks to CestDiego) +**** Shell +- Use =shell-pop= to toggle shell/eshell and terminals (thanks to tuhdo) +- Add binding for EOF (^D) in =term= (thanks to darkfeline) +- Bind =term-send-tab= only in insert state (thanks to darkfeline) +- =up= and =down= in shell to cycle through previous commands (thanks to + ralesi) +- Fix for =paste= command in =multi-term=. +- Add ~SPC p $ t~ to run =multi-term= at project root +**** Slime +- Disable =smartparens= in SLIME REPL (thanks to tuhdo) +**** Smex +- Fix =smex= prompt whitespace (thanks to TheBB) +**** Syntax-checking +- New variable =syntax-checking-flycheck-pos-tip= to enable or disable + documentation popup (thanks to beardedprojamz) +**** Themes +- Add =apropospriate-theme= to megapack +- Add =jazz-theme= to megapack (thanks to matDobek) +- Fix theme-to-package rules for =base16= (thanks to mkaito) +**** Tmux +- Add support for motion state (thanks to rphillips) +**** Vim-empty-lines +- Update with last patches (thanks to person808) +- Exclude terminal modes (thanks to tonylotts) +**** Ycmd +- Move C/C++ related configuration to =c-c++= layer. +*** Core +- Add support for =use-package= injected hooks (not yet documented) +- It is now possible to create a layer directly in a known configuration + layer path. A helm buffer will ask for a known path or a new path + (thanks to justbur) +- The =:variables= keyword now behaves like regular =setq=. +- Add org elpa repository +- Use =archive= instead of =package-alist= to detect orphans + (fix false orphan positives when the dependencies of a package change) +- Improve support for images in Spacemacs banner, it is now possible to use + any image format supported by Emacs (thanks to jupl) +- Prefix all category folders in =contrib= with =!= (thanks to trishume) +- Smarter buffer switching which tries to avoid special buffers, you can + customize =spacemacs-useless-buffers-regexp= to define other buffers to + avoid (thanks to person808) +- Warn about duplicated layers +- Improvements to home buffer: Quick Help, Content toggles, + link faces, better key bindings (thanks to tuhdo) +- =dotspacemacs/location= now respect =dotspacemacs-filepath= value + (thanks to coldnew) +- Avoid conflict with hydra's =lv.el= (thanks to edwintorok) +- Update layer templates to use =setq= instead of =defvar= (thanks to + person808) +*** Other fixes +- Replace =defvar= with =setq= for variable definition =-packages=, + =-pre-extensions= and =-pre-extensions=. +- Themes in =dotspacemacs-themes= are not considered orphans anymore +- Fix "Unable to check for new version." if =.emacs.d= is a symlink + (thanks to louy2) +- Fix non unicode number spacing in mode-line +- Typos (thanks to Andrea, atamis, CarlQLange, charl, ctjhoa, Devagamster, + dguilak, edwintorok, fhzerorubigd, jackwilsonv, jupl, kini, latkins, MadAnd, + mlsteel, mosic, person808, skwuent, srid, swaroopch and zimbatm) +* Release 0.101.x +** Hot new features +*** Choose your own editing style +Thanks to the new =holy-mode= Spacemacs can now be used by Vim users +or Emacs users by setting the =dotspacemacs-editing-style= variable to +='vim= or ='emacs= in the dotfile. In =Emacs= style the leader is +available on =M-m=. It is possible to dynamically switch between the +two style with ~SPC P tab~. +*** Mandatory init function and new Pre and Post init functions +A package is now considered to be used only if there is a corresponding +=/init-= function explicitly defined. +There is now two new functions to initialize a given package: +- =/pre-init-= which is called before the init function +- =/post-init-= which is called after the init function +Even if a =pre= or =post= function exist for a given package, an =init= +function is still required to consider the package to be used. +*** Auto-completion +Spacemacs now officially support auto-completion. The old layer +=company-mode= has been removed and =auto-complete= has been removed +from the spacemacs layer. +They are now part of a new layer called =auto-completion=. +You'll have to this add layer to your dotfile to enable auto-completion. +*** Syntax checking +Flycheck has been removed from the Spacemacs layer and moved to a new +layer called =syntax-checking=. +You'll have to add this layer to your dotfile to enable the fly syntax +checking. +*** Org +Org packages have been removed from Spacemacs layer and moved to a new +=org= layer. +You'll have to add this layer to your dotfile to enable the Org +configuration of Spacemacs. +*** New shortcuts in startup buffer +Recent files, project and bookmarks can be displayed on the startup +buffer. Check for the new dotfile variable =dotspacemacs-startup-lists=. +(thanks to CarlQLange) +*** New lighter in the mode line +Lighter letters have been updated, now the letter corresponds to the +key binding to toggle the associated mode. For instance auto-completion +is on ⓐ and thus can be toggled with ~SPC t a~. +*** Better package update +The package update should now prevent even more errors when upgrading +a batch of packages. +** Initial Release (2015/04/13) +*** New layers +- evil-commentary: Alternative to =evil-nerd-commenter= + (thanks to person808) +- better-defaults: layer providing better defaults for Emacs commands, + rather empty for now. (thanks to tuhdo) +- ERC: an IRC client (thanks to swaroopch) +- Racket: a lisp dialect (thanks to trishume) +- xkcd: browse for XKCD in Emacs (thanks to CestDiego) +- shell-scripts: layer containing shell specific modes like =fish-mode= +- editorconfig: add support for EditorConfig (thanks to jupl) +*** New dotfile variables: +- =dotspacemacs-editing-style= can be either =vim= or =emacs=. +- =dotspacemacs-verbose-loading= if non nil the loading prints logs in + the =*Messages*= buffer. Default value is =nil=. +- =dotspacemacs-startup-lists= is a list of symbols to display recent + items in the startup buffer, possible values are: =recents=, + =bookmarks= and =projects= (thanks to CarlQLange) +*** Auto-complete +- Move to =auto-completion= layer +*** C/C++ +- Add key bindings ~SPC m g a~ and ~SPC m g A~ for open alternate file + (thanks to mijoharas) +*** Clojure +- Add ~SPC m e f~ eval function at point +- Add =cider-eval-sexp-fu= +- Fix for =cider-send-function-to-repl= (thanks to nashamri) +- Replace =auto-complete= by =company= for auto-completion +- Move ~SPC d~ commands on ~SPC h~ to meet Spacemacs conventions (thanks to + cpaulik) +- Open =cider-doc= without asking for symbol, close it with =q= (thanks to + cpaulik) +*** Company +- Move to =auto-completion= layer +- Refactoring of =company= configuration, it is now lazy-loaded and the + =company-backends= list is now a buffer local variable. =company= is + not enabled globally anymore. +- Set =company-delay= to 0.2 instead of 0 +- Ignore =company-quickhelp= for Emacs version < 24.4 +- Add support for =company= in various languages (thanks to trishume) +*** Emacs Lisp +- Add =eval-sexp-fu= (thanks to tuhdo) +- Enable eldoc in eval-expression and IELM (thanks to tuhdo) +- New key bindings ~SPC m e b~, ~SPC m e c~ and ~SPC m e r~ to evaluate + the buffer, the current form starting by =set= or =def= and the region + respectively (thanks to ralesi) +*** Ess +- Fix loading of =ess-R-object-popup= and =ess-R-data-view= + (thanks to jcpetkovich) +*** Extra-Lang layer +- Add =Nim= language (thanks to trishume) +*** Flycheck +- Move to =syntax-checking= layer +- Add =flycheck-pos-tip= (thanks to tuhdo) +- Enable flycheck for =lua= files (thanks rphillips) +*** Git +- Add =gitconfig-mode= and =git-commit-mode= (thanks to ralesi) +- Add =gitattributes-mode= and =gitignore-mode= (thanks to r4ts0n) +- Add key bindings in rebase mode +- Add =git-link= package (thanks to CestDiego) +- Enable Magit authentication on Windows (thanks to tuhdo) +- Loads =magit-gh-pulls= only after requesting it (thanks to cpaulik) +*** Go +- Add =run-package-tests= command on ~SPC m t p~ (thanks to robmerrell) +- Fix path to =go-oracle= (thanks to Pursuit92) +*** Haskell +- Move ~SPC m t~ and ~SPC m i~ under ~SPC m h~ +- Remove =hi2= (it is now integrated in =haskell-mode=) +- Disable =eletric-indent-mode= +- Fix =flycheck-haskell= autoload (thanks to jcpetkovich) +- Fix =flycheck= loading +- Move ~SPC m t~ to ~SPC m h t~ according to Spacemacs conventions (thanks + to jeremyjh) +- Add C-- =cmm-mode= (thanks to bgamari) +*** Helm +- Add =helm-colors= key binding on ~SPC C l~ (thanks to tuhdo) +- Make =helm-ff-doted-directory= consistent (thanks to tuhdo) +- Disable popwin-mode when a Helm session is active (thanks to tuhdo) +- Fix lazy-loading of helm for describe commands +- Add support for =pt= the platinum searcher (thanks to ralesi) +- Add support for =helm-ag-edit= +- Add function =spacemacs/helm-projectile-search-dwim= which select the + first available external search tool (pt, ag, ack or grep) (thanks to + ralesi) +- Enable =helm-descbinds= globally (thanks to tuhdo) +- Add key bindings for useful Helm commands: =helm-info-at-point=, + =helm-man-woman=, =helm-locate-library= and =helm-minibuffer-history= + (thanks to tuhdo) +- Add key bindings for searching the web using =helm-suggest= (thanks to + cpaulik) +*** Holy-mode +- New package providing Emacs edition style to Spacemacs +*** IRC +- rcirc: Create rcirc logging directory during init + (thanks to jcpetkovich) +- New ERC layer (thanks to swaroopch) +- Add ERC keybindings (thans to cpaulik) +- Move startup key bindings to prefix ~SPC a i~ +*** Markdown +- Associate =.mkd= with =markdown-mode= (thanks to bgamari) +*** Org +- Move to =org= layer +- Bind evil-leader in org-agenda-map (thanks to luxbock) +- Add =org-pomodoro= on ~SPC m p~ (thanks to swaroopch) +- Add key bindings for =org-clock-cancel= on ~SPC m q~, + and =org-set-effort= on ~SPC m f~ (thanks to swaroopch) +- Fix diminish of =org-indent= +*** Perspective +- Rebind =spacemacs/persp-switch-project= to ~SPC p p~ + (thanks to CestDiego) +*** Projectile +- Move projectile switch project from ~SPC p S~ to ~SPC p p~ +*** Python +- Add helm-pydoc on ~SPC m h d~ (thanks to danielwuz) +- Fix =pylookup= configuration +*** Racket +- Add key bindings for REPL interaction +*** Ruby +- Lazy-load =projectile-rails= +- Remove mode-line lighter for =robe= +*** Scala +- Do not enable ensime in non-file buffers (thanks to chrisbarrett) +*** SLIME +- Use slime for indentation (thanks to tuhdo) +- Add extension for SBCL (thanks to tuhdo) +- Allow to create a common lisp scratch buffer with slime-scratch + (thanks to tuhdo) +- Enable fuzzy completion with score (thanks to tuhdo) +- Don't enable SLIME in Emacs Lisp (thanks to tuhdo) +*** Smartparens +- Enable smartparens in eval-expression (thanks to tuhdo) +*** Themes +- Fix =themes-megapack= layer where themes could not be browsed in Helm. +- Add =material= theme (thanks to cpaulik) +- Add =darktooth= theme (thanks to person808) +- Add =gotham= theme (thanks to person808) +*** ycmd +- Set global config only if not already set (thanks naseer) +*** Web +- Add =sass-mode= (thanks to ryanartecona) +- Ensure that less gets loaded (thanks to mijoharas) +*** Various Improvements and Changes +- New =evil= state called =evilified= which is used in _evilified_ + buffers. +- Remove the following packages from Spacemacs layer: =dired+=, + =fancy-narrow=, =string-edit=, =visual-regexp-steroids= and =wdired= +- Rename =*-declarep= functions to =*-usedp= functions +- Display block selection info in the mode line + (thanks to emmanueltouzery) +- Bind =K= in normal state to ~SPC m h h~ if it exists + (thanks to person808) +- Add key binding for balancing windows on ~SPC w =~ (thanks to kini) +- Add key binding to indent region on ~SPC j =~ (thanks to tuhdo) +- Add key binding ~SPC w SPC~ for =ace-window= (thanks to ralesi) +- Add key binding ~SPC b h~ to open the startup buffer (thanks to ralesi) +- Add key binding ~SPC t ~~ to toggle Vim tildes +- Add adaptive wrap which appropriately indents wrapped lines (thanks to + person808) +- Add mouse support to line number column (thanks to ralesi) + - single click selects line + - double click selects text block + - drag across lines selects all lines dragged across +- Add =highlight-numbers= (thanks to tuhdo) +- Add =highlight-indentation= on ~SPC t h i~ and ~SPC t h c~ (thanks to + cpaulik) +- Add ace-link package to spacemacs layer (thanks to danielwuz) +- Add =indent-guide= on ~SPC t i~ (thanks to ralesi) +- Add link to cpaulik tutorial to use the Spacemacs icons in Ubuntu Unity +- Add C-w and brackets [] to guide-key-sequence (thanks to ralesi) +- Add =info+= to improve Info reading experience (thanks to tuhdo) +- Add default layers to dotfile template: =auto-completion=, + =better-defaults=, =git=, =markdown=, =org= and =syntax-checking= + (thanks to CarlQLange) +- Move some toggles on ~SPC T~: fringe, menu bar, tool bar, + frame maximize, frame fullscreen, frame transparency +- Restore rectangle-mark-mode key binding (thanks to tuhdo) +- Make quit the isearch-mode like vim (thanks to dsdshcym) +- Enable goto-address-prog-mode which makes URL in code comments clickable + (thanks to tuhdo) +- Disable aggressive indent for ediff buffers (thanks chrisbarrett) +- Prevent cursor from moving into minibuffer prompt (thanks to tuhdo) +- Remove tildes in Spacemacs buffer and read-only buffers like Info and + help (thanks to tuhdo) +- Ask user editing style when creating .spacemacs file (thanks to tuhdo) +- Fix for persistent-server if server never got started (thanks to ralesi) +- Fix nyan cat starting rainbow on a light background +- Fix some double loading of some packages +- Fix double loading of =extensions.el= files +- Fix question for preferred coding systems on Microsoft Windows +- Properly enable saveplace (thanks to tuhdo) +- Don't bind ~C-d~ in =ido-completion-map= to =ido-delete-file-at-head= + (thanks to segv) +- Don't refer to ~/.emacs.d/ directly at various places + (thanks to jcpetkovich) +- Don't want paste-micro-state to pop up when pasting in ex command + prompt (thanks to ralesi) +- Don't cycle when press TAB in eshell (thanks to tuhdo) +- Don't insert extra quote in dotspacemacs-mode (thanks to tuhdo) +- Adapt some micro-states to the micro-state macro (thanks to ralesi) +- Improve smooth scrolling configuration (reduce some point jump) + (thanks to tuhdo) +- Improve =doge= banner grammar (thanks to mathpunk) +- New =HOTOWs.md= file in =/doc= +- Add =Buy A Drink= badge to README.md +- Typo and documentation updates (thanks to danielwuz, swaroopch, + CestDiego, IvanMalison, agevelt, nwolfe) +** Hot Fixes +*** Startup Buffer +- Don't display the release notes in the startup buffer when Emacs is restarted + after a fresh install +- Startup buffer: fix widget activation in =holy-mode= (thanks to tuhdo) +- Startup buffer: Don't fontify the startup buffer when =rainbow-identifiers= +*** Auto-completion +- Fix error when toggling auto-completion in some buffers +*** Haskell +- Add new =haskell-snippets= package (fixes error with required =haskell-yas=) +- Fix missing quote in =haskell-indentation= +*** Org +- Org layer: exclude ox-gfm since it seems problematic for some users. + package is used +*** Ruby +- Fix auto-completion activation. +*** Themes +- Fix conflict between official Spacemacs solarized theme and + =color-theme-solarized= declared in =themes-megapack= layer. +- Add rules for all base16 themes (thanks to mkaito) +*** Various Fixes +- revert back =ag= as the default search tool instead of =pt=, =pt= can + conflict with =pt= command line tool from TCL parser tools. +* Previous Releases +- See Github release page diff --git a/COMMUNITY.org b/COMMUNITY.org new file mode 100644 index 0000000..9e1f000 --- /dev/null +++ b/COMMUNITY.org @@ -0,0 +1,111 @@ +#+TITLE: Spacemacs Community + +* Spacemacs Community :TOC_4_gh:noexport: + - [[#philosophy][Philosophy]] + - [[#for-contributors][For Contributors]] + - [[#for-users][For Users]] + - [[#moderation][Moderation]] + - [[#guidelines][Guidelines]] + - [[#people][People]] + - [[#issues][Issues]] + - [[#pull-requests-and-commmits][Pull requests and Commmits]] + - [[#messages][Messages]] + - [[#interpretation][Interpretation]] + - [[#collaborators-privacy][Collaborators privacy]] + - [[#maintainer][Maintainer]] + - [[#log][Log]] + +* Philosophy +** For Contributors +- This community is a community of hackers based on meritocracy and + volunteering. Hackers strive for excellence to make the world a better place, + so does the Spacemacs community. +- Be good in what you bring to the project be it code, documentation, typo + fixes, art, humor, ideas, project management, web design, assurance quality, + mentorship, you name it! We like to award achievements to people making a + difference in a wide variety of domains and occasions, [[file:./doc/DOCUMENTATION.org#specials][see it for yourself]]. + Why not you? Make it happen, make history! +- Think you are not good enough? Find support and mentors by chatting on Gitter + with fellow Spacemacs users or just open an issue on GitHub, you will find + help to fulfil your desire of contribution. We welcome anyone with good + intentions. +- In a nutshell: Be good, positive and/or with good intentions and focused on + the project. +** For Users +- Any question related to the project is welcomed and encouraged, the worst + thing that can happen is that we redirect you to the documentation. +- The majority of the interactions with the community happens on GitHub via + issues and on Gitter via the official Spacemacs channel. There is also an + active official twitter account =spacemacs=. +- Any opinion on the project is valorized given it is constructive. + +* Moderation +We want the community to be judged based on its moderation actions instead of +telling people how to behave. The golden rules of the community are to have good +intentions and stay focused on the project, for anything else that requires +moderation any future user or contributor can refer to this section to know +about our past moderation actions. So readers won't find any example or +definition of what collaborators judge offending or outrageous, instead they +will find at the end of this section a log of all major moderation actions taken +by the collaborators since the beginning of the project which started officially +in August 2014. It should allow you to decide whether or not you want to be part +of this community. If you are not convinced then be assured that the only evil +part in Spacemacs is the evil mode :-) +** Guidelines +These guidelines apply to all collaborators of the project, namely @syl20bnr, +@TheBB, @d12frosted and @bmag. +*** People +- Collaborators cannot ban any GitHub user from the repository but they can ban + users from the official Gitter channel. +- A user can be banned if and only if all the collaborators agree to do so. +- The reasons of the ban are mentioned in the moderation actions log (see + below). +*** Issues +- Issues can be locked if their contents are judged _inappropriate_, _offending_ + or if they deviate _dangerously_ from the project. +*** Pull requests and Commmits +- Collaborators can push to the repository without making a PR. +- PR can be rejected. Rejected PR always go with a reason explicitly written + when closing the PR. +- Commits can be reverted if they compromise the stability of the project. The + reason is contained in the commit comments. +- Pull request are also issues, thus issue guidelines also apply to pull + requests. +*** Messages +- Only the form of a message can be edited, not its meaning, except if this + meaning is _outrageous_. +- Moderators can add information to a message to improve its accuracy without + altering its meaning, +- Any edition of a message is logged in the =edits log= located at the end of + the edited message with the following format: + #+BEGIN_EXAMPLE + EDIT: [@moderator] action (reason: xxx) + #+END_EXAMPLE +- The reason is added only when needed (for instance we won't add a reason for + formatting edits) +** Interpretation +Words used in these guidelines like _good_, _inappropriate_, _offending_, +_dangerously_ and _outrageous_ are used without any explanation, their meanings +and interpretations are left solely to the discretion of the collaborators who +are educated persons working in the interest of the community. +** Collaborators privacy +Life and actions of collaborators outside of the project (i.e. outside of the +Spacemacs GitHub repository, official Spacemacs Gitter channels and Twitter +official Spacemacs account timeline) are completely detached from their +activities and roles in the project. They are free to express any opinion on the +project or any other subjects and those opinions cannot be used to compromise +their roles in the project as long as they follow the moderation guidelines with +good intentions. +** Maintainer +- The maintainer @syl20bnr as a BDFL is free to demote a collaborator in extreme + situations. +- When there is no consensus on a subject, the BDFL can decide to impose his + view on the subject. +** Log +For transparency and future reference any major moderation actions are recorded +here. As of Sunday, April 10th 2016, 7200 issues have been opened and 2 major +moderation actions have been taken: +| Date | Moderator | Action | Issue | Reason | +|------------+-----------+--------+-------+-----------------------------------------------------------------| +| 2016/01/27 | syl20bnr | lock | #3484 | comments judged to be offending towards the Spacemacs community | +| 2016/01/27 | syl20bnr | unlock | #3484 | let's make it happen, i.e. this document | diff --git a/CONTRIBUTING.org b/CONTRIBUTING.org new file mode 100644 index 0000000..b6ee605 --- /dev/null +++ b/CONTRIBUTING.org @@ -0,0 +1,256 @@ +#+TITLE: Contribution guidelines +#+HTML_HEAD_EXTRA: + +Spacemacs is a volunteer effort. We encourage you to pitch in. The community +makes Spacemacs what it is. We have a few guidelines, which we ask all +contributors to follow. + +You can only consider reading the sections relevant to what you are going to do: +- [[#asking-for-help][Asking for help]] if you are about to open an issue to ask a question. +- [[#reporting-issues][Reporting issues]] if you are about to open a new issue. +- [[#contributing-code][Contributing code]] if you are about to send a Pull-Request. + +Thanks! :heart: :heart: :heart: + +* Content :TOC@2:noexport: + - [[#asking-for-help][Asking for help]] + - [[#reporting-issues][Reporting issues]] + - [[#contributing-code][Contributing code]] + - [[#general-contribution-guidelines][General contribution guidelines]] + - [[#contributing-a-layer][Contributing a layer]] + - [[#contributing-a-keybinding][Contributing a keybinding]] + - [[#contributing-a-banner][Contributing a banner]] + - [[#additional-information][Additional information]] + - [[#testing][Testing]] + - [[#credits][Credits]] + +* Asking for help +If you want to ask an usage question, be sure to look first into some places as +it may hold the answer: + +- [[doc/FAQ.org][The FAQ]]. Some of the most frequently asked questions are answered there. +- [[doc/DOCUMENTATION.org][The documentation]]. It's the general documentation of Spacemacs. +- You may also read the =README.org= of the [[layers/][relevant layer(s)]]. + +If your question is not answered there, then please come into our [[https://gitter.im/syl20bnr/spacemacs][gitter chat]] to +discuss it with us :relaxed:. We will direct you to a solution, or ask you to +open an issue if it is needed. + +* Reporting issues +Issues have to be reported on our [[https://github.com/syl20bnr/spacemacs/issues][issues tracker]]. Please: + +- Check that the issue has not already been reported. + - This can be achieved by searching keywords on the [[https://github.com/syl20bnr/spacemacs/issues][issues tracker]]. +- Check that the issue has not been fixed in the =develop= version of Spacemacs. + - This can be achieved by running Spacemacs on the =develop= branch and trying + to reproduce the bug here. You can also check at the [[https://github.com/syl20bnr/spacemacs/tree/develop][source code]] to see if + it has been changed/corrected. +- Try to use a clear title, and describe your problem with complete sentences. + See also [[https://github.com/syl20bnr/spacemacs/wiki/Debugging#how-to-make-a-great-bug-report][How to make a great bug report]] in the wiki. +- Include the following information in your issue: + - The output of =SPC h d s= (=M-m h d s= in Emacs style), which gives the + versions information about your installation. + - If relevant, include the mode in which the problem arise (e.g. javascript + files, =org-mode=, etc…). + - If possible, try to include details on how to reproduce it, like a step by + step guide. + +* Contributing code +Code contributions are welcome. Please read the following sections carefully. In +any case, feel free to join us on the [[https://gitter.im/syl20bnr/spacemacs][gitter chat]] to ask questions about +contributing! + +** General contribution guidelines + +*** License +The license is =GPLv3= for all parts specific to Spacemacs, this includes: +- The initialization and core files +- All the layer files. + +For files not belonging to Spacemacs like local packages and libraries, refer +to the header file. Those files should not have an empty header, we may not +accept code without a proper header file. + +*** Conventions +Spacemacs is based on conventions, mainly for naming functions, keybindings +definition and writing documentation. Please read the [[file:doc/CONVENTIONS.org][CONVENTIONS.org]] file +before your first contribution to get to know them. + +*** Pull-Request +Submit your contribution against the =develop= branch. You should not use +your =master= branch to modify Spacemacs, this branch is considered to be +read-only. + +You may want to [[https://github.com/syl20bnr/spacemacs/wiki/Beginner%27s-Guide-to-Contributing-a-Pull-Request-to-Spacemacs][read our beginner’s guide for Pull Requests]]. + +/PR = Pull-Request/ + +**** Ideally for /simple/ PRs (most of them): +- Branch from =develop= +- One topic per PR +- One commit per PR +- If you have several commits on different topics, close the PR and + create one PR per topic +- If you still have several commits, squash them into only one commit +- Rebase your PR branch on top of upstream =develop= before submitting + the PR + +Those PRs are usually /cherry-picked/. + +**** For complex PRs (big refactoring, etc): +- Squash only the commits with uninteresting changes like typos, syntax fixes, + etc... and keep the important and /isolated/ steps in different commits. + +Those PRs are /merged/ and explicitly /not fast-forwarded/. + +*** Commit messages +Write commit messages according to adapted [[http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html][Tim Pope's guidelines]]: + +- Use present tense and write in the imperative: “Fix bug”, not “fixed bug” or + “fixes bug”. +- Start with a capitalized, short (72 characters or less) summary, followed by a + blank line. +- If necessary, add one or more paragraphs with details, wrapped at 72 + characters. +- Separate paragraphs by blank lines. + +This is a model commit message: + +#+begin_EXAMPLE +Capitalized, short (72 chars or less) summary + +More detailed explanatory text, if necessary. Wrap it to about 72 +characters or so. In some contexts, the first line is treated as the +subject of an email and the rest of the text as the body. The blank +line separating the summary from the body is critical (unless you omit +the body entirely); tools like rebase can get confused if you run the +two together. + +Write your commit message in the imperative: "Fix bug" and not "Fixed bug" +or "Fixes bug." This convention matches up with commit messages generated +by commands like git merge and git revert. + +Further paragraphs come after blank lines. + +- Bullet points are okay, too + + - Typically a hyphen or asterisk is used for the bullet, followed by a + single space, with blank lines in between, but conventions vary here + + - Use a hanging indent +#+end_EXAMPLE + +[[https://github.com/magit/magit/][Git Commit]] and [[https://github.com/magit/magit/][Magit]] provide Emacs mode for Git commit messages, which helps you +to comply to these guidelines. + +** Contributing a layer +Please read the [[file:doc/LAYERS.org][layers documentation]] first. + +It is recommended to use the =configuration-layer/create-layer= command in order +to create a layer, as it will take care of using the files templates and will +also create the file headers correctly. + +Contributed configuration layers are stored in the =layers/= folder. The +=layers/= folder also contains categories prefixed with =+= to put your layers +in. For example a layer for a language would go in the =layers/+lang/= folder. + +Layer with no associated configuration will be rejected. For instance a layer +with just a package and a hook can be easily replaced by the usage of the +variable =dotspacemacs-additional-packages=. + +*** File header +The file header for =elisp= files should look like the following template: + +#+BEGIN_EXAMPLE + ;;; FILENAME --- NAME Layer packages File for Spacemacs + ;; + ;; Copyright (c) 2012-2016 Sylvain Benner & Contributors + ;; + ;; Author: YOUR_NAME + ;; URL: https://github.com/syl20bnr/spacemacs + ;; + ;; This file is not part of GNU Emacs. + ;; + ;;; License: GPLv3 +#+END_EXAMPLE + +You should replace =FILENAME= by the name of the file (e.g. =packages.el=) +and =NAME= by the name of the layer you are creating, don't forget to replace +=YOUR_NAME= and =YOUR_EMAIL= also. Some files already have a template inside +=core/templates/=, so look in there first. +Note that if you use =configuration-layer/create-layer=, spacemacs will prepare +files and headers for you, and for free :smile: ! + +*** Author of a new layer +In the files header, change the default author name (=Sylvain Benner=) to your +name. + +*** Contributor to an existing layer +If you are contributing to an already existing layer, you should not modify any +header file. + +** Contributing a keybinding +Keybindings are an important part of spacemacs. + +First if you want to have some personal keybindings, you can freely bind them +inside the ~SPC o~ and ~SPC m o~ prefixes which are reserved for the user. This +can be done from the =dotspacemacs/user-config= function of your =.spacemacs= +file and don't require any contribution to Spacemacs. + +If you think it worth contributing a new key bindings then be sure to read +the [[doc/CONVENTIONS.org][CONVENTIONS.org]] file to find the best key bindings, then create a +Pull-Request with your changes. + +*ALWAYS* document your new keybindings or keybindings changes inside the +relevant documentation file. It should be the layer's =README.org= file for +layer's keybindings, or =DOCUMENTATION.org= for general Spacemacs key +bindings. + +** Contributing a banner +The startup banner is by default the Spacemacs logo but there are also ASCII +banners available in the directory =core/banners/=. + +If you have some ASCII skills you can submit your artwork! + +You are free to choose a reasonable height size but the width size should be +around 75 characters. + +* Additional information +** Testing +Tests live in the =tests/= folder, with a folder structure corresponding to the +rest of the repository. + +To run tests locally, navigate to the relevant subfolder and run =make=. + +Spacemacs uses Travis CI to perform more comprehensive testing, where each +testable layer is enabled in turn. + +To add tests for a layer, do the following: + +1. Create a subfolder of =tests/= corresponding to the layer you want to test. +2. Write a file called =dotspacemacs.el= in that folder. It should be a minimal + dotfile that enables the layer in question (and other layers it may depend + on). +3. Write a number of files with tests. Please try to separate unit and + functional tests. Look at existing tests for clues. +4. Write a =Makefile= in that folder. It should define three variables. + - =LOAD_FILES= :: a list of additional files to load before testing (relative + to the root Spacemacs folder). This should typically be =init.el=. + - =UNIT_TEST_FILES= :: a list of unit test files in the current folder. + - =FUNC_TEST_FILES= :: a list of functional test files in the current folder. + See existing tests for examples. + #+begin_src makefile + TEST_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) + + LOAD_FILES = ... + UNIT_TEST_FILES = ... + FUNC_TEST_FILES = ... + + include ../../spacemacs.mk + #+end_src +5. Add the new test to list of tests in =travis/run_build.sh=. + +* Credits + +This =CONTRIBUTING.org= file is partially based on the [[https://github.com/rails/rails/blob/master/CONTRIBUTING.md][Rails Contribution +guidelines]] and [[https://github.com/flycheck/flycheck/blob/master/CONTRIBUTING.md][Flycheck Contribution guidelines]]. diff --git a/README.md b/README.md new file mode 100644 index 0000000..8555d27 --- /dev/null +++ b/README.md @@ -0,0 +1,455 @@ + +Made with SpacemacsTwitter
+*** +

Spacemacs

+

+philosophy +| +for whom? +| +screenshots +| +documentation +| +contribute +| +achievements +| +FAQ +

+*** +

+Gitter +Build Status +PR being merged +Donate +Donate +Recommend it +

+*** + +**Quick Install:** + + git clone https://github.com/syl20bnr/spacemacs ~/.emacs.d + + +**Table of Contents** + +- [Introduction](#introduction) +- [Features](#features) +- [Documentation](#documentation) +- [Getting Help](#getting-help) +- [Prerequisites](#prerequisites) + - [Emacs](#emacs) + - [Linux distros](#linux-distros) + - [macOS](#macos) + - [Windows](#windows) +- [Install](#install) + - [Default installation](#default-installation) + - [Alternate installations](#alternate-installations) + - [Modify HOME environment variable](#modify-home-environment-variable) + - [Modify spacemacs-start-directory variable](#modify-spacemacs-start-directory-variable) + - [Spacemacs logo](#spacemacs-logo) +- [Update](#update) + - [Automatic update (on master branch)](#automatic-update-on-master-branch) + - [Manual update (on master branch)](#manual-update-on-master-branch) + - [On develop branch](#on-develop-branch) + - [Revert to a specific version](#revert-to-a-specific-version) +- [Quotes](#quotes) +- [Contributions](#contributions) +- [Communities](#communities) +- [License](#license) +- [Supporting Spacemacs](#supporting-spacemacs) + + + +# Introduction + +Spacemacs is a new way to experience Emacs -- a sophisticated and +polished set-up focused on ergonomics, mnemonics and consistency. + +Just clone it, launch it, then press the space bar to explore the +interactive list of carefully-chosen key bindings. You can also press +the home buffer's `[?]` button for some great first key bindings to +try. + +Spacemacs can be used naturally by both Emacs and Vim users -- you can +even mix the two editing styles. Switching easily between input styles +makes Spacemacs a great tool for pair-programming. + +Spacemacs is currently in beta, and contributions are very welcome. + +![spacemacs_python](doc/img/spacemacs-python.png) + +# Features + +- **Great documentation:** access documentation in Emacs with +SPC h SPC. +- **Beautiful GUI:** you'll love the distraction free UI and its functional +mode-line. +- **Excellent ergonomics:** all the key bindings are accessible by pressing +the space bar or alt-m. +- **Mnemonic key bindings:** commands have mnemonic prefixes like +SPC b for all the buffer commands or SPC p for the +project commands. +- **Batteries included:** discover hundreds of ready-to-use packages nicely +organised in configuration layers following a set of +[conventions][CONVENTIONS.org]. + +# Documentation + +Comprehensive documentation is available for each layer by pressing +SPC h SPC. + +You can also check the [general documentation][DOCUMENTATION.org], +[quick start guide][QUICK_START.org] and the [FAQ][FAQ.org]. + +# Getting Help + +If you need help, ask your question in the [Gitter Chat][] and a member of the +community will help you out. + +If you prefer IRC, connect to the [Gitter Chat IRC server][] and join the +`#syl20bnr/spacemacs` channel. + +# Prerequisites + +## Emacs + +Spacemacs requires Emacs 24.4 or above. The development version of Emacs (at the +time of writing, this is 25.2) is not *officially* supported, but should +nevertheless be expected to work. + +Some modes require third-party tools that you'll have to install via your +favorite package manager. + +### Linux distros + +Install Emacs from the package manager of your Linux distribution. + +You should install the "emacs" package, not the "xemacs" package. +XEmacs is an old fork of Emacs. The X in its name is unrelated to X11. +Both Emacs and XEmacs have graphical support. + +**Note:** Ubuntu LTS 12.04 and 14.04 repositories have only Emacs 24.3 +available. You have to [build from source][build_source] Emacs 24.4 or greater, +as Spacemacs won't work with 24.3. The same may be true for other distributions +as well. + +### macOS + +The recommended way of installing Emacs on macOS is using [homebrew][]: + +```sh +$ brew tap d12frosted/emacs-plus +$ brew install emacs-plus +$ brew linkapps emacs-plus +``` + +*Note:* these homebrew commands will install GNU Emacs, and link it to your +`/Applications` directory. You still need to run the `git clone` mentioned at +the start of this file. That will populate your `~/.emacs.d` directory, which is +what transforms a regular GNU Emacs into Spacemacs. + +*Note:* the proposed `emacs-plus` tap is identical to the `emacs` formulae, it +just builds GNU Emacs with support of several features by default along with +providing Spacemacs icon. +See [emacs-plus](https://github.com/d12frosted/homebrew-emacs-plus) for more +information. + +*Note:* after you have completed the [install process](#install) below, it is +also recommended to add the [osx layer][] to your [dotfile][]. Install +instructions are available in the [osx layer][] documentation. + +*Note:* if the powerline separators on the spaceline are a different (less +saturated) color than the rest of the line, you can add following snippet to +`dotspacemacs/user-config` in your `.spacemacs` file. + +```elisp +(setq ns-use-srgb-colorspace nil) +``` + +Keep in mind that this is not ideal solution as it affects all colours in Emacs. +Another option is to use different powerline separator. For example, `alternate` +and `bar` diminishes the difference. And using `utf-8` separator makes it go +away completely without the need to change colour space. In order to change +powerline separator put following snippet in `dotspacemacs/user-config`. + +```eslip +(setq powerline-default-separator 'utf-8) +``` + +For more information about powerline separators, please refer to appropriate +section in [Documentation][DOCUMENTATION.org]. + +### Windows + +You can download good quality builds from the [emacs-w64 project][emacs-for-windows]. +It is recommended to install the most recent [stable build][emacs-for-windows-stable]. + +Be sure to declare a environment variable named `HOME` pointing to your user +directory `C:\Users\`. Then you can clone Spacemacs in this directory. + +Sometimes you'll get the following error when you first start Emacs: + +``` +The directory ~/.emacs.d/server is unsafe +``` + +To fix it change the owner of the directory `~/.emacs.d/server`: + - from Properties select the Tab “Security”, + - select the button “Advanced”, + - select the Tab “Owner” + - change the owner to your account name + +Source: [Stack Overflow][so-server-unsafe] + +For efficient searches we recommend to install `pt` ([the platinum searcher][]). +`pt` version 1.7.7 or higher is required. + +# Install + +## Default installation + +1. If you have an existing Emacs configuration, back it up first: + + ```sh + cd ~ + mv .emacs.d .emacs.d.bak + mv .emacs .emacs.bak + ``` + + Don't forget to backup and *remove* `~/.emacs` file otherwise Spacemacs + **WILL NOT** load since that file prevents Emacs from loading the proper + initialization file. + +2. Clone the repository: + + ```sh + git clone https://github.com/syl20bnr/spacemacs ~/.emacs.d + ``` + + `master` is the stable branch and it is _immutable_, **DO NOT** make any + modification to it or you will break the update mechanism. If you want to + fork Spacemacs safely use the `develop` branch where you handle the update + manually. + +3. (Optional) Install the [Source Code Pro][] font. + + If you are running in terminal you'll also need to change font settings of + your terminal. + +4. Launch Emacs. Spacemacs will automatically install the packages it requires. + If you get an error regarding package downloads then you may try to disable + the HTTPS protocol by starting Emacs with + + ```sh + emacs --insecure + ``` + + Or you can set the `dotspacemacs-elpa-https` to `nil` in your dotfile to + remove the need to start Emacs with `--insecure` argument. You may wish to + clear out your `.emacs.d/elpa` directory before doing this, so that any + corrupted packages you may have downloaded will be re-installed. + +5. Restart Emacs to complete the installation. + +If the mode-line turns red then be sure to consult the [FAQ][FAQ.org]. + +## Alternate installations + +It may be useful to clone Spacemacs outside Emacs dotdirectory `~/.emacs.d` so +you can try Spacemacs without replacing completely our own configuration. +There is currently two possibilities to support alternative location for +Spacemacs configuration. + +### Modify HOME environment variable + +This solution is ideal to quickly try Spacemacs without compromising your +existing configuration. + +```sh +mkdir ~/spacemacs +git clone https://github.com/syl20bnr/spacemacs.git ~/spacemacs/.emacs.d +HOME=~/spacemacs emacs +``` + +Note: If you're on Fish shell, you will need to modify the last command to: `env +HOME=$HOME/spacemacs emacs` + +### Modify spacemacs-start-directory variable + +This solution is better suited to "embed" Spacemacs into your own configuration. +Say you cloned Spacemacs in `~/.emacs.d/spacemacs/` then drop these lines in +`~/.emacs.d/init.el`: + +```elisp +(setq spacemacs-start-directory "~/.emacs.d/spacemacs/") +(load-file (concat spacemacs-start-directory "init.el")) +``` + +## Spacemacs logo + +For Ubuntu users, follow this guide to +[change the logo in Unity][cpaulik-unity-icon]. + +For Mac users, you need to [download the .icns version of the logo][icon-repository], +then [change the logo on Dock][icon-mac-instructions]. + +# Update + +Spacemacs has a built-in notification of a new version when you are on the +`master` branch. If you are on the `develop` branch then you'll have to +update Spacemacs manually by updating your repository. + +## Automatic update (on master branch) + +When a new version is available a little arrow appears in the mode-line. + +Its color depends on the number of versions available since your last update. +Green means that your current version is recent, orange and red mean that your +current version is older. + +![powerline_update](doc/img/powerline-update.png) + +Click on the arrow to update Spacemacs to the last version. + +## Manual update (on master branch) + +(Remove the angle brackets when typing the lines below into your shell.) + +```sh +git fetch +git reset --hard +``` + +## On develop branch + +1. Update Emacs packages by clicking (press `RET`) on the `[Update Packages]` link of +the starting page. + +2. Close Emacs and update the git repository: + + ```sh + git pull --rebase + ``` + +3. Restart Emacs to complete the upgrade. + +## Revert to a specific version + +To revert to a specific version you just have to checkout the corresponding +branch, for instance to revert to the last `0.103`: + + ```sh + git checkout origin/release-0.103 + ``` + +**After you update, either manually, or automatically, you are advised to update + your packages by clicking the `[Update Packages]` button on the Spacemacs Home + Buffer.** + +# Quotes + +[Quote][quote01] by [ashnur](https://github.com/ashnur): + + «I feel that spacemacs is an aircraft carrier and I am playing table tennis on the deck as a freerider.» + +[Quote][quote02] by [deuill](https://github.com/deuill): + + «I LOVE SPACEMACS AND MAGIT + + That is all» + +# Contributions + +Spacemacs is a community-driven project, it needs _you_ to keep it up to +date and propose great and useful configuration for all the things! + +Before contributing be sure to consult the +[contribution guidelines][CONTRIBUTING.org] and [conventions][CONVENTIONS.org]. + +Here is a throughput graph of the repository for the last few weeks: + +[![Throughput Graph](https://graphs.waffle.io/syl20bnr/spacemacs/throughput.svg)](https://waffle.io/syl20bnr/spacemacs/metrics) + +# Communities + +- [Gitter Chat] +- [Stack Exchange] +- [Reddit] + +# License + +The license is GPLv3 for all parts specific to Spacemacs, this includes: +- the initialization and core files +- all the layer files +- the documentation + +For the packages shipped in this repository you can refer to the files header. + +[Spacemacs logo][] by [Nasser Alshammari][] released under a [Creative Commons Attribution-ShareAlike 4.0 International License.](http://creativecommons.org/licenses/by-sa/4.0/) + +# Supporting Spacemacs + +The best way to support Spacemacs is to contribute to it either by reporting +bugs, helping the community on the [Gitter Chat][] or sending pull requests. + +You can show your love for the project by getting cool Spacemacs t-shirts, mugs +and more in the [Spacemacs Shop][]. + +If you want to show your support financially you can contribute to [Bountysource][] or buy a drink for the +maintainer by clicking on the [Paypal badge](#top). + +If you used spacemacs in a project and you want to show that fact, you can use +the spacemacs badge: [![Built with Spacemacs](https://cdn.rawgit.com/syl20bnr/spacemacs/442d025779da2f62fc86c2082703697714db6514/assets/spacemacs-badge.svg)](http://spacemacs.org) + +- For Markdown: + + ``` + [![Built with Spacemacs](https://cdn.rawgit.com/syl20bnr/spacemacs/442d025779da2f62fc86c2082703697714db6514/assets/spacemacs-badge.svg)](http://spacemacs.org) + ``` + +- For HTML: + + ``` + + ``` + +- For Org-mode: + + ``` + [[http://spacemacs.org][file:https://cdn.rawgit.com/syl20bnr/spacemacs/442d025779da2f62fc86c2082703697714db6514/assets/spacemacs-badge.svg]] + ``` + +Thank you! + +[Twitter]: http://i.imgur.com/tXSoThF.png +[CONTRIBUTING.org]: CONTRIBUTING.org +[CONVENTIONS.org]: http://spacemacs.org/doc/CONVENTIONS +[DOCUMENTATION.org]: http://spacemacs.org/doc/DOCUMENTATION +[QUICK_START.org]: http://spacemacs.org/doc/QUICK_START +[FAQ.org]: http://spacemacs.org/doc/FAQ +[VIMUSERS.org]: http://spacemacs.org/doc/VIMUSERS +[dotfile]: http://spacemacs.org/doc/DOCUMENTATION#orgheadline45 +[osx layer]: http://spacemacs.org/layers/+os/osx/README.html +[Gitter Chat]: https://gitter.im/syl20bnr/spacemacs +[Gitter Chat IRC server]: https://irc.gitter.im/ +[homebrew]: http://brew.sh +[emacs-for-windows]: http://emacsbinw64.sourceforge.net/ +[emacs-for-windows-stable]: https://sourceforge.net/projects/emacsbinw64/files/release/ +[the platinum searcher]: https://github.com/monochromegane/the_platinum_searcher +[so-server-unsafe]: http://stackoverflow.com/questions/885793/emacs-error-when-calling-server-start +[Spacemacs logo]: https://github.com/nashamri/spacemacs-logo +[Nasser Alshammari]: https://github.com/nashamri +[cpaulik-unity-icon]: http://splendidabacus.com/posts/2015/03/spacemacs-unity-icon/ +[icon-mac-instructions]: http://www.idownloadblog.com/2014/07/16/how-to-change-app-icon-mac/ +[icon-repository]: https://github.com/nashamri/spacemacs-logo +[Stack Exchange]: http://emacs.stackexchange.com/questions/tagged/spacemacs +[Reddit]: https://www.reddit.com/r/spacemacs +[quote01]: https://gitter.im/syl20bnr/spacemacs?at=568e627a0cdaaa62045a7df6 +[quote02]: https://gitter.im/syl20bnr/spacemacs?at=5768456c6577f032450cfedb +[build_source]: https://www.gnu.org/software/emacs/manual/html_node/efaq/Installing-Emacs.html +[Bountysource]: https://salt.bountysource.com/teams/spacemacs +[Source Code Pro]: https://github.com/adobe-fonts/source-code-pro +[Spacemacs Shop]: https://shop.spreadshirt.com/spacemacs-shop diff --git a/assets/spacemacs-badge.svg b/assets/spacemacs-badge.svg new file mode 100644 index 0000000..055e527 --- /dev/null +++ b/assets/spacemacs-badge.svg @@ -0,0 +1,166 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + built with + built with + Spacemacs + Spacemacs + + + + + + + + diff --git a/assets/spacemacs.svg b/assets/spacemacs.svg new file mode 100644 index 0000000..fa8a768 --- /dev/null +++ b/assets/spacemacs.svg @@ -0,0 +1,405 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/aprilfool/zemacs.el b/core/aprilfool/zemacs.el new file mode 100644 index 0000000..55bc519 --- /dev/null +++ b/core/aprilfool/zemacs.el @@ -0,0 +1,119 @@ +;;; zemacs.el --- Spacemacs 2016 April Fools File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq spacemacs-buffer-name "*zemacs*") +(setq spacemacs-buffer-logo-title "[Z E M A C S]") +(setq spacemacs-buffer-version-info "af-1.01") + +(define-minor-mode zemacs-buffer-mode + "Zemacs major mode for startup screen." + :lighter "ToTheMAX" + (if zemacs-buffer-mode + (progn + (spacemacs/set-leader-keys-for-major-mode 'spacemacs-buffer-mode + (kbd "aprilfool") 'next-next-NEXT-millennium) + (zemacs//insert-links)) + ;; restore the true one + (ad-disable-advice 'configuration-layer/initialize + 'before 'zemacs/initialize) + (ad-activate 'configuration-layer/initialize) + (ad-disable-advice 'spacemacs-buffer//inject-version + 'around 'zemacs/inject-version) + (ad-activate 'spacemacs-buffer//inject-version) + (ad-disable-advice 'spacemacs-buffer/insert-banner-and-buttons + 'after 'zemacs/insert-banner-and-buttons) + (ad-activate 'spacemacs-buffer/insert-banner-and-buttons) + (load-file (concat spacemacs-start-directory "core/core-spacemacs-buffer.el")) + (setq dotspacemacs-startup-banner 'official) + (kill-buffer) + (insert " +───█──█─█▀▀█─█▀▀█─█▀▀█─█──█─── +───█▀▀█─█▄▄█─█▀▀▀─█▀▀▀─▀▀▀█─── +───█──█─█──█─█────█────█▄▄█─── +────────────────────────────── +───█▀▀█─█▀▀█─█▀▀█─▀▀█▀▀─█───── +───█▄▄█─█▀▀▀─█▀▀▄───█───█───── +───█──█─█────█──█─▄▄█▄▄─█▄▄─── +────────────────────────────── +──█▀▀▀─▄▀▀▀▄─▄▀▀▀▄─█────▄▀▀▀── +──█▀▀▀─█───█─█───█─█────▀▀▀▄── +──█────▀▄▄▄▀─▀▄▄▄▀─█▄▄▄─▄▄▄▀── +────────────────────────────── +──────────▄▄███████▄▄───────── +───────▄███████████████▄────── +────▄██████▀────────▀█████▄─── +──▄█████▀──────────────▀████▄─ +▄████▀────▄██▄────▄██▄───▀████ +██▀───────████────████─────▀██ +██────────████────████──────██ +██────────▀██▀────▀██▀──────██ +██──────────────────────────██ +██──█▄──────────────────▄█──██ +██──█▀██▄──────────────▄██──██ +██──█──▀██▄──────────▄▄█─█──██ +██──█────▀████████████▀──█──██ +██──█─────█────█────█────█──██ +██──█─────█────█────█────█──██ +██──██▄───█────█────█──▄██──██ +██──██████████████████████──██ +██──█─────█────█────█────█──██ +██──█─────█────█────█────█──██ +██──██────█────█────█───█▀──██ +██───▀██████████████████▀───██ +██▄───────────────────────▄███ +█████▄──────────────────▄█████ +─▀███████▄───────────▄██████▀─ +────▀█████████████████████▀─── ") + (spacemacs-buffer/goto-buffer) + (spacemacs-buffer//remove-existing-widget-if-exist))) + +(defun next-next-NEXT-millennium () + "Time to rock on!" + (interactive) + (zemacs-buffer-mode -1)) + +(defvar zemacs--links '(("this one" "http://neovim.io") + ("link" "http://cdn.meme.am/instances/500x/67641307.jpg") + ("Atom" "http://atom.io/") + ("implementation tricks" "http://emacshorrors.com/"))) + +(defun zemacs//insert-links () + "Replace bracketed texts by their link counterparts." + (with-current-buffer spacemacs-buffer-name + (save-excursion + (dolist (l zemacs--links) + (re-search-backward (format "\\(\\[%s\\]\\)" (car l)) nil t) + (make-text-button + (match-beginning 1) + (match-end 1) + 'type 'help-url + 'help-args (cdr l)))))) + +(defadvice configuration-layer/initialize (before zemacs/initialize activate) + (setq dotspacemacs-startup-banner "~/.emacs.d/core/banners/img/zemacs.png")) + +(defadvice spacemacs-buffer//inject-version + (around zemacs/inject-version activate) + (let ((emacs-version "99.9999999") + (dotspacemacs-distribution "zemacs") + (spacemacs-version "af-1.01")) + ad-do-it)) + +(defadvice spacemacs-buffer/insert-banner-and-buttons + (after zemacs/insert-banner-and-buttons activate) + ;; always display the release note + (spacemacs-buffer//insert-release-note-widget + (concat spacemacs-release-notes-directory + spacemacs-buffer-version-info ".txt"))) + +(add-hook 'emacs-startup-hook 'zemacs-buffer-mode t) + +(provide 'zemacs) diff --git a/core/banners/000-banner.txt b/core/banners/000-banner.txt new file mode 100644 index 0000000..ac629f1 --- /dev/null +++ b/core/banners/000-banner.txt @@ -0,0 +1,8 @@ + +Welcome to +███████╗██████╗**█████╗**██████╗███████╗███╗***███╗*█████╗**██████╗███████╗ B +██╔════╝██╔══██╗██╔══██╗██╔════╝██╔════╝████╗*████║██╔══██╗██╔════╝██╔════╝ E +███████╗██████╔╝███████║██║*****█████╗**██╔████╔██║███████║██║*****███████╗ T +╚════██║██╔═══╝*██╔══██║██║*****██╔══╝**██║╚██╔╝██║██╔══██║██║*****╚════██║ A +███████║██║*****██║**██║╚██████╗███████╗██║*╚═╝*██║██║**██║╚██████╗███████║ +╚══════╝╚═╝*****╚═╝**╚═╝*╚═════╝╚══════╝╚═╝*****╚═╝╚═╝**╚═╝*╚═════╝╚══════╝ diff --git a/core/banners/001-banner.txt b/core/banners/001-banner.txt new file mode 100644 index 0000000..4a7db95 --- /dev/null +++ b/core/banners/001-banner.txt @@ -0,0 +1,9 @@ + +┏━━━┓ +┃┏━┓┃ Welcome to +┃┗━━┓╋╋╋╋┏━━┓╋╋╋╋┏━━┓╋╋╋╋┏━━┓╋╋╋╋┏━━┓╋╋╋╋┏┓┏┓╋╋╋╋┏━━┓╋╋╋╋┏━━┓╋╋╋╋┏━━┓ b +┗━━┓┃┏━━┓┃┏┓┃┏━━┓┃┏┓┃┏━━┓┃┏━┛┏━━┓┃┃━┫┏━━┓┃┗┛┃┏━━┓┃┏┓┃┏━━┓┃┏━┛┏━━┓┃━━┫ e +┃┗━┛┃┗━━┛┃┗┛┃┗━━┛┃┏┓┃┗━━┛┃┗━┓┗━━┛┃┃━┫┗━━┛┃┃┃┃┗━━┛┃┏┓┃┗━━┛┃┗━┓┗━━┛┣━━┃ t +┗━━━┛╋╋╋╋┃┏━┛╋╋╋╋┗┛┗┛╋╋╋╋┗━━┛╋╋╋╋┗━━┛╋╋╋╋┗┻┻┛╋╋╋╋┗┛┗┛╋╋╋╋┗━━┛╋╋╋╋┗━━┛ a +╋╋╋╋╋╋╋╋╋┃┃[The best editor is neither Emacs nor Vim, it's Emacs+Vim] +╋╋╋╋╋╋╋╋╋┗┛ diff --git a/core/banners/002-banner.txt b/core/banners/002-banner.txt new file mode 100644 index 0000000..0b79203 --- /dev/null +++ b/core/banners/002-banner.txt @@ -0,0 +1,9 @@ + +╭─┏━━━┓───────────────────────────────────────────────────────────────────╮ +│ ┃┏━┓┃ Welcome to │ +│ ┃┗━━┓ ┏━━┓ ┏━━┓ ┏━━┓ ┏━━┓ ┏┓┏┓ ┏━━┓ ┏━━┓ ┏━━┓ b │ +│ ┗━━┓┃┏━━┓┃┏┓┃┏━━┓┃┏┓┃┏━━┓┃┏━┛┏━━┓┃┃━┫┏━━┓┃┗┛┃┏━━┓┃┏┓┃┏━━┓┃┏━┛┏━━┓┃━━┫ e │ +│ ┃┗━┛┃┗━━┛┃┗┛┃┗━━┛┃┏┓┃┗━━┛┃┗━┓┗━━┛┃┃━┫┗━━┛┃┃┃┃┗━━┛┃┏┓┃┗━━┛┃┗━┓┗━━┛┣━━┃ t │ +│ ┗━━━┛ ┃┏━┛ ┗┛┗┛ ┗━━┛ ┗━━┛ ┗┻┻┛ ┗┛┗┛ ┗━━┛ ┗━━┛ a │ +│ ┃┃[The best editor is neither Emacs nor Vim, it's Emacs+Vim] │ +╰──────────┗┛─────────────────────────────────────────────────────────────╯ diff --git a/core/banners/003-banner.txt b/core/banners/003-banner.txt new file mode 100644 index 0000000..2ed2dfe --- /dev/null +++ b/core/banners/003-banner.txt @@ -0,0 +1,17 @@ + +⠀⠀⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⣠⣾⣿⣿⣿⣷⣶⣤⣀⡤⣤⡒⢖⠖⢖⢒⠢⠤⢄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠠⣿⠛⠉⠁⢉⣹⢿⣿⣿⣿⣷⣼⢸⢸⢨⠢⡡⢑⡠⠀⠑⠢⢄⠀⠀⠀⠀⠀⠀ +⠨⡃⠀⢀⡴⡣⣗⢵⣣⢟⣟⣿⣿⣿⣎⡎⡎⡜⡐⢽⣾⡄⠀⠈⠑⢄⠀⠀⠀⠀ +⠀⢇⣠⢯⡪⣯⣺⢽⢾⣽⡽⣾⣺⣝⢿⣿⣼⢨⠢⡑⢿⣷⠀⠀⠀⠀⠳⡀⠀⠀ +⠀⡸⡪⡪⣿⣾⣺⡽⣿⣳⢯⡿⣵⢷⣝⢼⢻⣯⣎⠢⢹⣿⣇⠀⠀⠀⠀⠱⡀⠀ +⢰⡫⢪⢪⡘⠿⣿⣿⣿⣾⣯⣿⢽⡳⣕⢇⢗⢜⢻⣧⡡⣿⣿⡄⠀⠀⠀⠀⢣⠀ Welcome to +⣞⢨⢊⢎⢆⠀⠀⠉⢿⣿⣿⣿⣿⣿⣷⣯⣮⣮⣦⣽⣿⣿⣿⣇⠀⠀⠀⠀⠈⡆ +⡧⢑⠔⡡⢣⠂⠀⠀⠀⢓⢝⢟⡻⡿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡀⠀⠀⠀⠀⡇ [ S p a c e m a c s ] +⡏⠄⠡⢊⢂⢅⠀⠀⠀⠀⠇⡇⠎⢎⠢⡩⠛⠻⢿⣿⣿⣿⣿⣿⡆⠀⠀⠀⢀⠇ +⢸⡀⡁⢁⠂⡂⠀⠀⠀⠀⠈⠔⡑⠡⢊⠐⡈⠌⢀⠀⠙⠻⢿⣿⣷⠀⠀⠀⡸⠀ +⠀⢣⠀⠀⠠⠈⠀⠀⠀⠀⠀⠀⠂⠌⠐⠠⠀⠀⠀⠀⠀⠀⠀⠈⠙⠀⠀⢠⠃⠀ +⠀⠀⢣⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠃⠀⠀ +⠀⠀⠀⠑⢄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠔⠁⠀⠀⠀ +⠀⠀⠀⠀⠀⠙⠤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡠⠔⠁⠀⠀⠀⠀⠀ + ⠀⠀⠀⠀⠀⠀⠀⠙⠒⠤⠤⣀⣀⣀⣀⣀⡠⠤⠔⠒⠉⠀⠀⠀⠀⠀⠀⠀⠀ diff --git a/core/banners/004-banner.txt b/core/banners/004-banner.txt new file mode 100644 index 0000000..68845e1 --- /dev/null +++ b/core/banners/004-banner.txt @@ -0,0 +1,17 @@ + +⠀⠀⠀⣀⣀⣀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⢀⠎⠁⠀⠀⠈⠉⠒⠦⢀⡀⡄⡤⡤⡤⡤⡤⣄⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⡎⡠⠒⠉⠉⢑⢲⢀⠀⠀⠈⠪⢣⢫⡺⣹⡹⣝⠾⣻⣶⣤⡀⠀⠀⠀⠀⠀⠀ +⠀⢿⡅⠀⠠⡰⡊⡎⡪⢊⠢⡠⢀⠀⠘⠜⣜⢎⡯⣳⠀⠳⣻⣿⣷⡄⠀⠀⠀⠀ +⠀⢹⣇⡠⠫⡪⡊⡢⢊⠨⠨⡂⢕⢐⠄⡀⠈⢺⢸⣝⡆⠀⢻⣷⣿⣿⣦⡀⠀⠀ +⠀⠈⣟⢪⢇⠀⠑⠌⠢⠡⡃⠢⡑⡐⢅⢇⢆⠀⠑⢕⣯⡀⠀⢿⣿⣿⣿⣷⡀⠀ +⠀⣐⢵⢣⢻⣦⣀⠀⠀⠁⠈⠌⠢⡊⡜⡔⡕⡭⢆⠈⠺⡄⠀⠸⣿⣿⣿⣿⣧⠀ Welcome to +⠀⣵⡫⡮⡣⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⠈⠘⠘⠙⠑⠀⠀⠀⠀⢿⣿⣿⣿⣿⡀ +⠀⣗⡯⣞⢵⢽⣿⣿⣿⣟⡕⡕⡤⡠⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⣿⣿⣿⡆ [ S p a c e m a c s ] +⠀⣯⢿⣺⣝⢮⣿⣿⣿⣿⣿⡪⡮⣳⢝⡽⣲⢤⣄⡀⠀⠀⠀⠀⠈⣿⣿⣿⣿⠂ +⠀⢸⣿⡽⣾⣳⣻⣿⣿⣿⣿⣾⡽⣺⢵⡯⣯⣿⣳⡿⣷⣦⣄⠀⠀⢿⣿⣿⡟⠀ +⠀⠀⢺⣿⣯⣿⣽⣿⣿⣿⣿⣿⣿⣽⣯⣟⣿⣾⣿⣿⣿⣿⣿⣿⣶⣼⣿⡿⠁⠀ +⠀⠀⠀⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠁⠀⠀ +⠀⠀⠀⠀⠘⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠋⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠉⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠋⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠛⠻⠻⠿⠿⠿⠛⠛⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀ diff --git a/core/banners/998-banner.txt b/core/banners/998-banner.txt new file mode 100644 index 0000000..82978c4 --- /dev/null +++ b/core/banners/998-banner.txt @@ -0,0 +1,27 @@ + + ▄▄▄▄ ▄ + ▌▄ █▄ ▄▀▄▀▄ + ▌███ ▌ ▄▄▄▄▄▄ ▐ ███ ▌ + ▄▄▀ ░░ ▐░░▐░░░▐ ▀▄ ░░░ ▌▄ + ▄▀ ░░░░ ▐░░ ▌░▌░░ ▐ ░░░░░ ▀▄ + ▐ ░░░░░ ▐░░░▐▌░░░▐ ░░░░░░░░ ▌ + ▐ ░░░ ▄▀▀▄ ░░░░░░░ ▄▀▀▄ ░░░░░░ ▌ + ▐ ░░ ▀▄▄▀ ░░░░░ ▀▄▄▀ ░░░░ ▌ + --▐---------___▄▀▀▄__----------- ▌ + _▐_________--—▀▄▄▀--__________ ▌ + ▀▌ ░░░░░ ▄▄▌▐▄▄ ░░░░░░░░ ▐▀ + ▀▌ ░░ ▐▀▀ ▀▀▌ ░░░░ ▐▀ + ▀▌░ ░▐▀▀ + ▀▀▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ▀▀ + ▐ ▌ + ▄▄▌ ▐▄▄ + ▄▄▀ ░░░ ▀▄▄ + ▄▄▌ ░░░░░░░░ ▐▄▄ + ▌ ░░░░░░░░░░░░░ ▐ + + ▄ ▄ | ███╗ ███╗ ██████╗ ███╗ ███╗ █████╗ ██████╗███████╗ + ▄ ░░▄▄▀▀▄▄░░ ▄ | ████╗ ████║██╔═══██╗████╗ ████║██╔══██╗██╔════╝██╔════╝ + ░░ ▄▀ ░░░░ ▀▄ ░░ | ██╔████╔██║██║ ██║██╔████╔██║███████║██║ ███████╗ + ▐░░░░░░░░░░▌ | ██║╚██╔╝██║██║ ██║██║╚██╔╝██║██╔══██║██║ ╚════██║ + ▀▄▄▄▄▄▄▄▄▀ | ██║ ╚═╝ ██║╚██████╔╝██║ ╚═╝ ██║██║ ██║╚██████╗███████║ + | ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚══════╝ diff --git a/core/banners/999-banner.txt b/core/banners/999-banner.txt new file mode 100644 index 0000000..8568c06 --- /dev/null +++ b/core/banners/999-banner.txt @@ -0,0 +1,26 @@ + + ░░░░░░░░░▄░░░░░░░░░░░░░░▄░░░░ + ░░░░░░░░▌▒█░░░░░░░░░░░▄▀▒▌░░░ + Such powerful ░░░░░░░░▌▒▒█░░░░░░░░▄▀▒▒▒▐░░░ + ░░░░░░░▐▄▀▒▒▀▀▀▀▄▄▄▀▒▒▒▒▒▐░░░ + ░░░░░▄▄▀▒░▒▒▒▒▒▒▒▒▒█▒▒▄█▒▐░░░ Vim and Emacs + ░░░▄▀▒▒▒░░░▒▒▒░░░▒▒▒▀██▀▒▌░░░ So love + ░░▐▒▒▒▄▄▒▒▒▒░░░▒▒▒▒▒▒▒▀▄▒▒▌░░ Much forbidden + ░░▌░░▌█▀▒▒▒▒▒▄▀█▄▒▒▒▒▒▒▒█▒▐░░ +Very modes ░▐░░░▒▒▒▒▒▒▒▒▌██▀▒▒░░░▒▒▒▀▄▌░ + ░▌░▒▄██▄▒▒▒▒▒▒▒▒▒░░░░░░▒▒▒▒▌░ + ▀▒▀▐▄█▄█▌▄░▀▒▒░░░░░░░░░░▒▒▒▐░ + ▐▒▒▐▀▐▀▒░▄▄▒▄▒▒▒▒▒▒░▒░▒░▒▒▒▒▌ + ▐▒▒▒▀▀▄▄▒▒▒▄▒▒▒▒▒▒▒▒░▒░▒░▒▒▐░ + ░▌▒▒▒▒▒▒▀▀▀▒▒▒▒▒▒░▒░▒░▒░▒▒▒▌░ + ░▐▒▒▒▒▒▒▒▒▒▒▒▒▒▒░▒░▒░▒▒▄▒▒▐░░ + ░░▀▄▒▒▒▒▒▒▒▒▒▒▒░▒░▒░▒▄▒▒▒▒▌░░ + ░░░░▀▄▒▒▒▒▒▒▒▒▒▒▄▄▄▀▒▒▒▒▄▀░░░ Wow. + ░░░░░░▀▄▄▄▄▄▄▀▀▀▒▒▒▒▒▄▄▀░░░░░ + ░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▀▀░░░░░░░░ + ██████╗ ██████╗ ██████╗ ███████╗███╗ ███╗ █████╗ ██████╗███████╗ + ██╔══██╗██╔═══██╗██╔════╝ ██╔════╝████╗ ████║██╔══██╗██╔════╝██╔════╝ + ██║ ██║██║ ██║██║ ███╗█████╗ ██╔████╔██║███████║██║ ███████╗ + ██║ ██║██║ ██║██║ ██║██╔══╝ ██║╚██╔╝██║██╔══██║██║ ╚════██║ + ██████╔╝╚██████╔╝╚██████╔╝███████╗██║ ╚═╝ ██║██║ ██║╚██████╗███████║ + ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚══════╝ diff --git a/core/banners/img/heart.png b/core/banners/img/heart.png new file mode 100644 index 0000000..64282f9 Binary files /dev/null and b/core/banners/img/heart.png differ diff --git a/core/banners/img/spacemacs-badge.png b/core/banners/img/spacemacs-badge.png new file mode 100644 index 0000000..4c3cc12 Binary files /dev/null and b/core/banners/img/spacemacs-badge.png differ diff --git a/core/banners/img/spacemacs.png b/core/banners/img/spacemacs.png new file mode 100644 index 0000000..aa8953c Binary files /dev/null and b/core/banners/img/spacemacs.png differ diff --git a/core/banners/img/zemacs.png b/core/banners/img/zemacs.png new file mode 100644 index 0000000..2e261af Binary files /dev/null and b/core/banners/img/zemacs.png differ diff --git a/core/core-auto-completion.el b/core/core-auto-completion.el new file mode 100644 index 0000000..062b253 --- /dev/null +++ b/core/core-auto-completion.el @@ -0,0 +1,83 @@ +;;; core-auto-completion.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Company ------------------------------------------------------------------- + +(defvar spacemacs-default-company-backends + '((company-dabbrev-code company-gtags company-etags company-keywords) + company-files company-dabbrev) + "The list of default company backends used by spacemacs. +This variable is used to configure mode-specific company backends in spacemacs. +Backends in this list will always be active in these modes, as well as any +backends added by individual spacemacs layers.") + +(defmacro spacemacs|defvar-company-backends (mode) + "Define a MODE specific company backend variable with default backends. +The variable name format is company-backends-MODE." + `(defvar ,(intern (format "company-backends-%S" mode)) + ',spacemacs-default-company-backends + ,(format "Company backend list for %S" mode))) + +(defmacro spacemacs|add-company-hook (mode) + "Enable company for the given MODE. +MODE must match the symbol passed in `spacemacs|defvar-company-backends'. +The initialization function is hooked to `MODE-hook'." + (let ((mode-hook (intern (format "%S-hook" mode))) + (func (intern (format "spacemacs//init-company-%S" mode))) + (backend-list (intern (format "company-backends-%S" mode)))) + `(when (configuration-layer/package-usedp 'company) + (defun ,func () + ,(format "Initialize company for %S" mode) + (when auto-completion-enable-snippets-in-popup + (setq ,backend-list (mapcar 'spacemacs//show-snippets-in-company + ,backend-list))) + (set (make-variable-buffer-local 'auto-completion-front-end) + 'company) + (set (make-variable-buffer-local 'company-backends) + ,backend-list)) + (add-hook ',mode-hook ',func t) + (add-hook ',mode-hook 'company-mode t)))) + +(defmacro spacemacs|disable-company (mode) + "Disable company for the given MODE. +MODE parameter must match the parameter used in the call to +`spacemacs|add-company-hook'." + (let ((mode-hook (intern (format "%S-hook" mode))) + (func (intern (format "spacemacs//init-company-%S" mode)))) + `(progn + (remove-hook ',mode-hook ',func) + (remove-hook ',mode-hook 'company-mode)))) + +(defun spacemacs//show-snippets-in-company (backend) + (if (or (not auto-completion-enable-snippets-in-popup) + (and (listp backend) (member 'company-yasnippet backend))) + backend + (append (if (consp backend) backend (list backend)) + '(:with company-yasnippet)))) + +;; Auto-complete ------------------------------------------------------------- + +(defmacro spacemacs|enable-auto-complete (mode) + "Enable auto-complete for the given MODE. +The initialization function is hooked to `MODE-hook'." + (let ((mode-hook (intern (format "%S-hook" mode))) + (func (intern (format "spacemacs//init-auto-complete-%S" mode)))) + `(when (configuration-layer/package-usedp 'auto-complete) + (defun ,func () + ,(format "Initialize auto-complete for %S" mode) + (set (make-variable-buffer-local 'auto-completion-front-end) + 'auto-complete) + (set (make-variable-buffer-local 'company-backends) + ,(intern (format "company-backends-%S" mode)))) + (add-hook ',mode-hook ',func) + (add-hook ',mode-hook 'auto-complete-mode)))) + +(provide 'core-auto-completion) diff --git a/core/core-command-line.el b/core/core-command-line.el new file mode 100644 index 0000000..e6f6a17 --- /dev/null +++ b/core/core-command-line.el @@ -0,0 +1,62 @@ +;;; core-command-line.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar spacemacs-force-resume-layouts nil + "If non-nil force the current emacs instance to resume layouts + at start time despite the value of `dotspacemacs-auto-resume-layouts'.") + +(defvar spacemacs-insecure nil + "If non-nil force Spacemacs to operate without secured protocols.") + +(defun spacemacs//parse-command-line (args) + "Handle Spacemacs specific command line arguments. +The reason why we don't use the Emacs hooks for processing user defined +arguments is that we want to process these arguments as soon as possible." + (let ((i 0) new-args) + (while (< i (length args)) + (let ((arg (nth i args)) + (next-arg-digit + (when (< (1+ i) (length args)) + (string-to-number (nth (1+ i) args))))) + (when (or (null next-arg-digit) (= 0 next-arg-digit)) + (setq next-arg-digit nil)) + (pcase arg + ("--profile" + (setq spacemacs-debug-with-profile t) + (setq spacemacs-debugp t)) + ("--timed-requires" + (setq spacemacs-debug-with-timed-requires t) + (when next-arg-digit + (setq spacemacs-debug-timer-threshold next-arg-digit + i (1+ i))) + (setq spacemacs-debugp t)) + ("--adv-timers" + (setq spacemacs-debug-with-adv-timers t) + (when next-arg-digit + (setq spacemacs-debug-timer-threshold next-arg-digit + i (1+ 1))) + (setq spacemacs-debugp t)) + ("--insecure" + (setq spacemacs-insecure t)) + ("--no-layer" + (setq configuration-layer-exclude-all-layers t)) + ("--distribution" + (setq configuration-layer-force-distribution (intern (nth (1+ i) args)) + i (1+ i))) + ("--resume-layouts" + (setq spacemacs-force-resume-layouts t)) + (_ (push arg new-args)))) + (setq i (1+ i))) + (nreverse new-args))) + +(setq command-line-args (spacemacs//parse-command-line command-line-args)) + +(provide 'core-command-line) diff --git a/core/core-configuration-layer.el b/core/core-configuration-layer.el new file mode 100644 index 0000000..c68d6e7 --- /dev/null +++ b/core/core-configuration-layer.el @@ -0,0 +1,2017 @@ +;;; core-configuration-layer.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(require 'cl-lib) +(require 'eieio) +(require 'subr-x) +(require 'package) +(require 'warnings) +(require 'help-mode) +(require 'ht) +(require 'core-dotspacemacs) +(require 'core-funcs) +(require 'core-spacemacs-buffer) + +(defvar configuration-layer--refresh-package-timeout dotspacemacs-elpa-timeout + "Timeout in seconds to reach a package archive page.") + +(defconst configuration-layer-template-directory + (expand-file-name (concat spacemacs-core-directory "templates/")) + "Configuration layer templates directory.") + +(defconst configuration-layer-directory + (expand-file-name (concat spacemacs-start-directory "layers/")) + "Spacemacs contribution layers base directory.") + +(defconst configuration-layer-private-directory + (expand-file-name (concat spacemacs-start-directory "private/")) + "Spacemacs private layers base directory.") + +(defconst configuration-layer-private-layer-directory + (let ((dotspacemacs-layer-dir + (when dotspacemacs-directory + (expand-file-name + (concat dotspacemacs-directory "layers/"))))) + (if (and dotspacemacs-directory + (file-exists-p dotspacemacs-layer-dir)) + dotspacemacs-layer-dir + configuration-layer-private-directory)) + "Spacemacs default directory for private layers.") + +(defun configuration-layer/elpa-directory (root) + "Evaluate the correct package subdirectory of ROOT. This is +done according to the value of `dotspacemacs-elpa-subdirectory'. +If it is nil, then ROOT is returned. Otherwise a subdirectory of +ROOT is returned." + (if (not dotspacemacs-elpa-subdirectory) + root + (let ((subdir (if (eq 'emacs-version dotspacemacs-elpa-subdirectory) + (format "%d%s%d" + emacs-major-version + version-separator + emacs-minor-version) + (eval dotspacemacs-elpa-subdirectory)))) + (file-name-as-directory (expand-file-name subdir root))))) + +(defvar configuration-layer-rollback-directory + (concat spacemacs-cache-directory ".rollback/") + "Spacemacs rollback directory.") + +(defconst configuration-layer-rollback-info "rollback-info" + "Spacemacs rollback information file.") + +(defclass cfgl-layer () + ((name :initarg :name + :type symbol + :documentation "Name of the layer.") + (dir :initarg :dir + :initform nil + :type (satisfies (lambda (x) (or (null x) (stringp x)))) + :documentation "Absolute path to the layer directory.") + (packages :initarg :packages + :initform nil + :type list + :documentation "List of package symbols declared in this layer.") + (selected-packages :initarg :selected-packages + :initform 'all + :type (satisfies (lambda (x) (or (and (symbolp x) (eq 'all x)) + (listp x)))) + :documentation "List of selected package symbols.") + (variables :initarg :variables + :initform nil + :type list + :documentation "A list of variable-value pairs.") + (lazy-install :initarg :lazy-install + :initform nil + :type boolean + :documentation + "If non-nil then the layer needs to be installed") + (disabled :initarg :disabled-for + :initform nil + :type list + :documentation "A list of layers where this layer is disabled.") + (enabled :initarg :enabled-for + :initform 'unspecified + :type (satisfies (lambda (x) (or (listp x) (eq 'unspecified x)))) + :documentation (concat "A list of layers where this layer is enabled. " + "(Takes precedence over `:disabled-for'.)"))) + "A configuration layer.") + +(defmethod cfgl-layer-owned-packages ((layer cfgl-layer)) + "Return the list of owned packages by LAYER. +LAYER has to be installed for this method to work properly." + (delq nil (mapcar + (lambda (x) + (let ((pkg (configuration-layer/get-package x))) + (when (and pkg (eq (oref layer :name) + (car (oref pkg :owners)))) + pkg))) + (oref layer :packages)))) + +(defmethod cfgl-layer-owned-packages ((layer nil)) + "Accept nil as argument and return nil." + nil) + +(defmethod cfgl-layer-get-packages ((layer cfgl-layer)) + "Return the list of packages for LAYER." + (if (eq 'all (oref layer :selected-packages)) + (oref layer :packages) + (delq nil (mapcar + (lambda (x) + (let ((pkg-name (if (listp x) (car x) x))) + (when (memq pkg-name (oref layer :selected-packages)) x))) + (oref layer :packages))))) + +(defclass cfgl-package () + ((name :initarg :name + :type symbol + :documentation "Name of the package.") + (min-version :initarg :min-version + :initform nil + :type list + :documentation "Minimum version to install as a version list.") + (owners :initarg :owners + :initform nil + :type list + :documentation "The layer defining the init function.") + (pre-layers :initarg :pre-layers + :initform '() + :type list + :documentation "List of layers with a pre-init function.") + (post-layers :initarg :post-layers + :initform '() + :type list + :documentation "List of layers with a post-init function.") + (location :initarg :location + :initform elpa + :type (satisfies (lambda (x) + (or (stringp x) + (memq x '(built-in local site elpa)) + (and (listp x) (eq 'recipe (car x)))))) + :documentation "Location of the package.") + (toggle :initarg :toggle + :initform t + :type (satisfies (lambda (x) (or (symbolp x) (listp x)))) + :documentation + "Package is enabled/installed if toggle evaluates to non-nil.") + (step :initarg :step + :initform nil + :type (satisfies (lambda (x) (member x '(nil bootstrap pre)))) + :documentation "Initialization step.") + (lazy-install :initarg :lazy-install + :initform nil + :type boolean + :documentation + "If non-nil then the package needs to be installed") + (protected :initarg :protected + :initform nil + :type boolean + :documentation + "If non-nil then this package cannot be excluded.") + (excluded :initarg :excluded + :initform nil + :type boolean + :documentation + "If non-nil this package is excluded from all layers."))) + +(defmethod cfgl-package-enabledp ((pkg cfgl-package) &optional inhibit-messages) + "Evaluate the `toggle' slot of passed PKG." + (let ((message-log-max (unless inhibit-messages message-log-max)) + (toggle (oref pkg :toggle))) + (eval toggle))) + +(defmethod cfgl-package-get-safe-owner ((pkg cfgl-package)) + "Safe method to return the name of the layer which owns PKG." + ;; The owner of a package is the first *used* layer in `:owners' slot. + ;; Note: for packages in `configuration-layer--used-packages' the owner is + ;; always the car of the `:owners' slot. + (let ((layers (oref pkg :owners))) + (while (and (consp layers) + (not (configuration-layer/layer-usedp (car layers)))) + (pop layers)) + (when (configuration-layer/layer-usedp (car layers)) + (car layers)))) + +(defmethod cfgl-package-set-property ((pkg cfgl-package) slot value) + "Set SLOT to the given VALUE for the package PKG. +If `configuration-layer--package-properties-read-onlyp' is non-nil then VALUE +is not set for the given SLOT." + (unless configuration-layer--package-properties-read-onlyp + (eval `(oset pkg ,slot value)))) + +(defvar configuration-layer--elpa-archives + '(("melpa" . "melpa.org/packages/") + ("org" . "orgmode.org/elpa/") + ("gnu" . "elpa.gnu.org/packages/")) + "List of ELPA archives required by Spacemacs.") + +(defvar configuration-layer-exclude-all-layers nil + "If non nil then only the distribution layer is loaded.") + +(defvar configuration-layer-force-distribution nil + "If set, bypass the user's choice `dotspacemacs-distribution'.") + +(defvar configuration-layer--package-archives-refreshed nil + "Non nil if package archives have already been refreshed.") + +(defvar configuration-layer--load-packages-files nil + "If non-nil force loading `packages.el' files when creating layer objects.") + +(defvar configuration-layer--used-layers '() + "A non-sorted list of used layer names.") + +(defvar configuration-layer--indexed-layers (make-hash-table :size 1024) + "Hash map to index `cfgl-layer' objects by their names.") + +(defvar configuration-layer--used-packages '() + "An alphabetically sorted list of used package names.") + +(defvar configuration-layer--indexed-packages (make-hash-table :size 2048) + "Hash map to index `cfgl-package' objects by their names.") + +(defvar configuration-layer--used-distant-packages '() + "A list of all distant packages that are effectively used.") + +(defvar configuration-layer--check-new-version-error-packages nil + "A list of all packages that were skipped during last update attempt.") + +(defvar configuration-layer--protected-packages nil + "A list of packages that will be protected from removal as orphans.") + +(defvar configuration-layer--lazy-mode-alist nil + "Association list where the key is a mode and the value a regexp.") + +(defvar configuration-layer--inhibit-warnings nil + "If non-nil then warning message emitted by the layer system are ignored.") + +(defvar configuration-layer--package-properties-read-onlyp nil + "If non-nil then package properties are read only and cannot be overriden by +`configuration-layer/make-package'.") + +(defvar configuration-layer--declared-layers-usedp nil + "If non-nil then declared layers are considered to be used.") + +(defvar configuration-layer-error-count nil + "Non nil indicates the number of errors occurred during the +installation of initialization.") + +(defvar configuration-layer-categories '() + "List of strings corresponding to category names. A category is a +directory with a name starting with `+'.") + +(defvar update-packages-alist '() + "Used to collect information about rollback packages in the +cache folder.") + +(defun configuration-layer/initialize () + "Initialize `package.el'." + (setq configuration-layer--refresh-package-timeout dotspacemacs-elpa-timeout) + (unless package--initialized + (setq configuration-layer-rollback-directory + (configuration-layer/elpa-directory configuration-layer-rollback-directory)) + (setq package-user-dir + (configuration-layer/elpa-directory package-user-dir)) + (setq package-archives (configuration-layer//resolve-package-archives + configuration-layer--elpa-archives)) + ;; optimization, no need to activate all the packages so early + (setq package-enable-at-startup nil) + (package-initialize 'noactivate))) + +(defun configuration-layer//install-quelpa () + "Install `quelpa'." + (setq quelpa-verbose init-file-debug + quelpa-dir (concat spacemacs-cache-directory "quelpa/") + quelpa-build-dir (expand-file-name "build" quelpa-dir) + quelpa-persistent-cache-file (expand-file-name "cache" quelpa-dir) + quelpa-update-melpa-p nil) + (configuration-layer/load-or-install-protected-package 'package-build) + (configuration-layer/load-or-install-protected-package 'quelpa)) + +(defun configuration-layer//resolve-package-archives (archives) + "Resolve HTTP handlers for each archive in ARCHIVES and return a list +of all reachable ones. +If the address of an archive already contains the protocol then this address is +left untouched. +The returned list has a `package-archives' compliant format." + (mapcar + (lambda (x) + (cons (car x) + (if (or (string-match-p "http" (cdr x)) + (string-prefix-p "/" (cdr x))) + (cdr x) + (concat + (if (and dotspacemacs-elpa-https + (not spacemacs-insecure) + ;; for now org ELPA repository does + ;; not support HTTPS + ;; TODO when org ELPA repo support + ;; HTTPS remove the check + ;; `(not (equal "org" (car x)))' + (not (equal "org" (car x)))) + "https://" + "http://") + (cdr x))))) + archives)) + +(defun configuration-layer/retrieve-package-archives (&optional quiet force) + "Retrieve all archives declared in current `package-archives'. + +This function first performs a simple GET request with a timeout in order to +fix very long refresh time when an archive is not reachable. + +Note that this simple GET is a heuristic to determine the availability +likelihood of an archive, so it can gives false positive if the archive +page is served but the archive is not. + +If QUIET is non nil then the function does not print message in the Spacemacs +home buffer. + +If FORCE is non nil then refresh the archives even if they have been already +refreshed during the current session." + (unless (and configuration-layer--package-archives-refreshed + (not force)) + (setq configuration-layer--package-archives-refreshed t) + (let ((count (length package-archives)) + (i 1)) + (dolist (archive package-archives) + (unless quiet + (spacemacs-buffer/replace-last-line + (format "--> refreshing package archive: %s... [%s/%s]" + (car archive) i count) t)) + (spacemacs//redisplay) + (setq i (1+ i)) + (unless (eq 'error + (with-timeout + (dotspacemacs-elpa-timeout + (progn + (display-warning + 'spacemacs + (format + "\nError connection time out for %s repository!" + (car archive)) :warning) + 'error)) + (condition-case err + (url-retrieve-synchronously (cdr archive)) + ('error + (display-warning 'spacemacs + (format + "\nError while contacting %s repository!" + (car archive)) :warning) + 'error)))) + (let ((package-archives (list archive))) + (package-refresh-contents)))) + (package-read-all-archive-contents) + (unless quiet (spacemacs-buffer/append "\n"))))) + +(defun configuration-layer/sync (&optional no-install) + "Synchronize declared layers in dotfile with spacemacs. +If NO-INSTALL is non nil then install steps are skipped." + (dotspacemacs|call-func dotspacemacs/layers "Calling dotfile layers...") + (setq dotspacemacs--configuration-layers-saved + dotspacemacs-configuration-layers) + (when (spacemacs-buffer//choose-banner) + (spacemacs-buffer//inject-version)) + ;; declare used layers then packages as soon as possible to resolve + ;; usage and ownership + (configuration-layer/discover-layers) + (configuration-layer//declare-used-layers dotspacemacs-configuration-layers) + (configuration-layer//declare-used-packages configuration-layer--used-layers) + ;; then load the functions and finally configure the layers + (configuration-layer//load-layers-files configuration-layer--used-layers + '("funcs.el")) + (configuration-layer//configure-layers configuration-layer--used-layers) + ;; pre-filter some packages to save some time later in the loading process + (setq configuration-layer--used-distant-packages + (configuration-layer//get-distant-packages + configuration-layer--used-packages t)) + ;; load layers lazy settings + (configuration-layer/load-auto-layer-file) + ;; install and/or uninstall packages + (unless no-install + (let ((packages + (append + ;; install used packages + (configuration-layer/filter-objects + configuration-layer--used-distant-packages + (lambda (x) + (let ((pkg (configuration-layer/get-package x))) + (not (oref pkg :lazy-install))))) + ;; also install all other packages if requested + (when (eq 'all dotspacemacs-install-packages) + (let (all-other-packages) + (dolist (layer (configuration-layer/get-layers-list)) + (let ((configuration-layer--declared-layers-usedp nil) + (configuration-layer--load-packages-files t)) + (configuration-layer/declare-layer layer) + (let* ((obj (configuration-layer/get-layer layer)) + (pkgs (when obj (oref obj :packages)))) + (configuration-layer/make-packages-from-layers + (list layer)) + (dolist (pkg pkgs) + (let ((pkg-name (if (listp pkg) (car pkg) pkg))) + (add-to-list 'all-other-packages pkg-name)))))) + (configuration-layer//get-distant-packages + all-other-packages nil)))))) + (configuration-layer//install-packages packages) + (when (and (or (eq 'used dotspacemacs-install-packages) + (eq 'used-only dotspacemacs-install-packages)) + (not configuration-layer-force-distribution) + (not configuration-layer-exclude-all-layers)) + (configuration-layer/delete-orphan-packages packages)))) + ;; configure used packages + (configuration-layer//configure-packages configuration-layer--used-packages) + (configuration-layer//load-layers-files configuration-layer--used-layers + '("keybindings.el"))) + +(defun configuration-layer/load-auto-layer-file () + "Load `auto-layer.el' file" + (let ((file (concat configuration-layer-directory "auto-layer.el"))) + (when (file-exists-p file) + (spacemacs-buffer/message "Loading auto-layer file...") + (load-file file)))) + +(defun configuration-layer/create-layer () + "Ask the user for a configuration layer name and the layer +directory to use. Create a layer with this name in the selected +layer directory." + (interactive) + (let* ((current-layer-paths (mapcar (lambda (dir) (expand-file-name dir)) + (cl-pushnew + configuration-layer-private-layer-directory + dotspacemacs-configuration-layer-path))) + (other-choice "Another directory...") + (helm-lp-source + `((name . "Configuration Layer Paths") + (candidates . ,(append current-layer-paths + (list other-choice))) + (action . (lambda (c) c)))) + (layer-path-sel (if (configuration-layer/layer-usedp 'ivy) + (ivy-read "Configuration layer path: " + (append current-layer-paths + (list other-choice))) + (helm :sources helm-lp-source + :prompt "Configuration layer path: "))) + (layer-path (cond + ((string-equal layer-path-sel other-choice) + (read-directory-name (concat "Other configuration " + "layer path: ") "~/" )) + ((member layer-path-sel current-layer-paths) + layer-path-sel) + (t + (error "Please select an option from the list")))) + (name (read-from-minibuffer "Configuration layer name: " )) + (layer-dir (concat layer-path "/" name))) + (cond + ((string-equal "" name) + (message "Cannot create a configuration layer without a name.")) + ((file-exists-p layer-dir) + (message (concat "Cannot create configuration layer \"%s\", " + "this layer already exists.") name)) + (t + (make-directory layer-dir t) + (configuration-layer//copy-template name "packages.el" layer-dir) + (when (y-or-n-p "Create readme?") + (configuration-layer//copy-template name "README.org" layer-dir)) + (message "Configuration layer \"%s\" successfully created." name))))) + +(defun configuration-layer//select-packages (layer-specs packages) + "Return the selected packages of LAYER-SPECS from given PACKAGES list." + (let* ((value (when (listp layer-specs) + (spacemacs/mplist-get layer-specs :packages))) + (selected-packages (if (and (not (null (car value))) + (listp (car value))) + (car value) + value))) + (cond + ;; select packages + ((and selected-packages + (not (memq (car selected-packages) '(all not)))) + selected-packages) + ;; unselect packages + ((and selected-packages + (eq 'not (car selected-packages))) + (delq nil (mapcar (lambda (x) + (let ((pkg-name (if (listp x) (car x) x))) + (unless (memq pkg-name selected-packages) + pkg-name))) + packages))) + ;; no package selections or all package selected + (t 'all)))) + +(defun configuration-layer/make-layer (layer-specs &optional obj usedp dir) + "Return a `cfgl-layer' object based on LAYER-SPECS. +If LOAD-PKGS is non-nil then load the `packages.el' file of the layer. +DIR is the directory where the layer is, if it is nil then search in the +indexed layers for the path." + (let* ((layer-name (if (listp layer-specs) (car layer-specs) layer-specs)) + (obj (if obj obj (cfgl-layer (symbol-name layer-name) + :name layer-name))) + (dir (or dir (oref obj :dir)))) + (if (or (null dir) + (and dir (not (file-exists-p dir)))) + (configuration-layer//warning + "Cannot make layer %S without a valid directory!" + layer-name) + (let* ((dir (file-name-as-directory dir)) + (disabled (when (listp layer-specs) + (spacemacs/mplist-get layer-specs :disabled-for))) + (enabled (if (and (listp layer-specs) + (memq :enabled-for layer-specs)) + (spacemacs/mplist-get layer-specs :enabled-for) + 'unspecified)) + (variables (when (listp layer-specs) + (spacemacs/mplist-get layer-specs :variables))) + (packages-file (concat dir "packages.el")) + (packages + (if (and (or usedp configuration-layer--load-packages-files) + (file-exists-p packages-file)) + (progn + (load packages-file) + (symbol-value (intern (format "%S-packages" layer-name)))) + (oref obj :packages))) + (selected-packages (if packages + (configuration-layer//select-packages + layer-specs packages) + ;; default value + 'all))) + (oset obj :dir dir) + (when usedp + (oset obj :disabled-for disabled) + (oset obj :enabled-for enabled) + (oset obj :variables variables)) + (when packages + (oset obj :packages packages) + (oset obj :selected-packages selected-packages)) + obj)))) + +(defun configuration-layer/make-package (pkg layer-name &optional obj) + "Return a `cfgl-package' object based on PKG. +If OBJ is non nil then copy PKG properties into OBJ, otherwise create +a new object. +Properties that can be copied are `:location', `:step' and `:excluded'. +If TOGGLEP is nil then `:toggle' parameter is ignored." + (let* ((pkg-name (if (listp pkg) (car pkg) pkg)) + (pkg-name-str (symbol-name pkg-name)) + (layer (unless (eq 'dotfile layer-name) + (configuration-layer/get-layer layer-name))) + (min-version (when (listp pkg) (plist-get (cdr pkg) :min-version))) + (step (when (listp pkg) (plist-get (cdr pkg) :step))) + (toggle (when (listp pkg) (plist-get (cdr pkg) :toggle))) + (excluded (when (listp pkg) (plist-get (cdr pkg) :excluded))) + (location (when (listp pkg) (plist-get (cdr pkg) :location))) + (protected (when (listp pkg) (plist-get (cdr pkg) :protected))) + (init-func (intern (format "%S/init-%S" + layer-name pkg-name))) + (pre-init-func (intern (format "%S/pre-init-%S" + layer-name pkg-name))) + (post-init-func (intern (format "%S/post-init-%S" + layer-name pkg-name))) + (copyp (not (null obj))) + (obj (if obj obj (cfgl-package pkg-name-str :name pkg-name))) + (ownerp (or (and (eq 'dotfile layer-name) + (null (oref obj :owners))) + (fboundp init-func)))) + (when min-version + (cfgl-package-set-property obj :min-version (version-to-list min-version))) + (when step (cfgl-package-set-property obj :step step)) + (when toggle (cfgl-package-set-property obj :toggle toggle)) + (cfgl-package-set-property obj :excluded + (and (configuration-layer/layer-usedp layer-name) + (or excluded (oref obj :excluded)))) + (when location + (if (and (listp location) + (eq (car location) 'recipe) + (eq (plist-get (cdr location) :fetcher) 'local)) + (cond + (layer (let ((path (expand-file-name + (format "%s%s/%s.el" + (configuration-layer/get-layer-local-dir + layer-name) + pkg-name-str pkg-name-str)))) + (cfgl-package-set-property + obj :location `(recipe :fetcher file :path ,path)))) + ((eq 'dotfile layer-name) + ;; TODO what is the local path for a packages owned by the dotfile? + nil)) + (cfgl-package-set-property obj :location location))) + ;; cannot override protected packages + (unless copyp + ;; a bootstrap package is protected + (cfgl-package-set-property + obj :protected (or protected (eq 'bootstrap step))) + (when protected + (push pkg-name configuration-layer--protected-packages))) + (when ownerp + ;; warn about mutliple owners + (when (and (oref obj :owners) + (not (memq layer-name (oref obj :owners)))) + (configuration-layer//warning + (format (concat "More than one init function found for " + "package %S. Previous owner was %S, " + "replacing it with layer %S.") + pkg-name (car (oref obj :owners)) layer-name))) + ;; last owner wins over the previous one + (object-add-to-list obj :owners layer-name)) + ;; check consistency betwween package and defined init functions + (unless (or ownerp + (eq 'dotfile layer-name) + (fboundp pre-init-func) + (fboundp post-init-func) + (oref obj :excluded)) + (configuration-layer//warning + (format (concat "package %s not initialized in layer %s, " + "you may consider removing this package from " + "the package list or use the :toggle keyword " + "instead of a `when' form.") + pkg-name layer-name))) + ;; check if toggle can be applied + (when (and (not ownerp) + (and (not (eq 'unspecified toggle)) + toggle)) + (configuration-layer//warning + (format (concat "Ignoring :toggle for package %s because " + "layer %S does not own it.") + pkg-name layer-name))) + (when (fboundp pre-init-func) + (object-add-to-list obj :pre-layers layer-name)) + (when (fboundp post-init-func) + (object-add-to-list obj :post-layers layer-name)) + obj)) + +(define-button-type 'help-dotfile-variable + :supertype 'help-xref + 'help-function + (lambda (variable) + (with-current-buffer (find-file-noselect dotspacemacs-filepath) + (pop-to-buffer (current-buffer)) + (goto-char (point-min)) + ;; try to exclude comments + (if (re-search-forward (format "^[a-z\s\\(\\-]*%s" variable) + nil 'noerror) + (beginning-of-line) + (message "Unable to find location in file")))) + 'help-echo + (purecopy (concat "mouse-2, RET: " + "visit the Spacemacs dotfile where variable is defined."))) + +(defun configuration-layer/describe-package (pkg-symbol + &optional layer-list pkg-list) + "Describe a package in the context of the configuration layer system." + (interactive + (list (intern + (completing-read "Package: " configuration-layer--used-packages)))) + (let* ((pkg (configuration-layer/get-package pkg-symbol)) + (owners (oref pkg :owners)) + (owner (car owners))) + (with-help-window (help-buffer) + ;; declaration location + (princ pkg-symbol) + (princ " is a package declared and configured ") + (cond + ((eq 'dotfile owner) + (princ "by the variable `dotspacemacs-additional-packages' ") + (with-current-buffer standard-output + (save-excursion + (re-search-backward "`\\([^`']+\\)'" nil t) + (help-xref-button 1 'help-variable + 'dotspacemacs-additional-packages + dotspacemacs-filepath))) + (princ "in your `dotfile'.\n") + (with-current-buffer standard-output + (save-excursion + (re-search-backward "`\\([^`']+\\)'" nil t) + (help-xref-button + 1 'help-dotfile-variable 'dotspacemacs-additional-packages)))) + ((not (null owner)) + (let* ((layer (configuration-layer/get-layer owner)) + (path (concat (oref layer dir) "packages.el"))) + (princ "by the layer `") + (princ owner) + (princ "'.\n") + (with-current-buffer standard-output + (save-excursion + (re-search-backward "`\\([^`']+\\)'" nil t) + (help-xref-button + 1 'help-function-def + (intern (format "%S/init-%S" owner pkg-symbol)) path))))) + (t + (princ "in an unknown place in the lisp parenthesis universe.\n"))) + ;; exclusion/protection + (if (oref pkg :protected) + (princ "\nThis package is protected and cannot be excluded.\n") + (when (oref pkg :excluded) + (princ "\nThis package is excluded and cannot be installed.\n"))) + ;; toggle + (unless (or (oref pkg :excluded) (eq t (oref pkg :toggle))) + (princ "\nA toggle is defined for this package, it is currently ") + (princ (if (cfgl-package-enabledp pkg t) "on" "off")) + (princ " because the following expression evaluates to ") + (princ (if (cfgl-package-enabledp pkg t) "t:\n" "nil:\n")) + (princ (oref pkg :toggle)) + (princ "\n")) + (unless (oref pkg :excluded) + ;; usage and installation + (if (not (configuration-layer/package-usedp pkg-symbol)) + (princ "\nYou are not using this package.\n") + (princ "\nYou are using this package") + (if (or (memq (oref pkg :location) '(built-in local site)) + (stringp (oref pkg :location))) + (princ ".\n") + (if (not (package-installed-p pkg-symbol)) + (princ " but it is not yet installed.\n") + (princ ", it is currently installed ") + (if (featurep pkg-symbol) + (princ "and loaded.\n") + (princ "but it has not been loaded yet.\n"))))) + (when (configuration-layer/package-lazy-installp pkg-symbol) + (princ + "\nThis package can be lazily installed using `auto-mode-alist'.\n") + (with-current-buffer standard-output + (save-excursion + (re-search-backward "`\\([^`']+\\)'" nil t) + (help-xref-button 1 'help-variable 'auto-mode-alist))) + (when (assq pkg-symbol configuration-layer--lazy-mode-alist) + (princ (concat "Actually it will be installed when one of the " + "following files is opened: \n")) + (princ (cdr (assq pkg-symbol + configuration-layer--lazy-mode-alist))) + (princ "\n"))) + ;; source location + (let ((location (oref pkg :location))) + (cond + ((eq 'built-in location) + (princ "\nThis is a built-in package distributed with Emacs.\n")) + ((eq 'local location) + (let* ((layer (configuration-layer/get-layer owner)) + (path (format "%slocal/%S" (oref layer dir) pkg-symbol))) + (princ (concat "\nThis is a local package whose source files " + "can be found in layer `")) + (princ owner) + (princ "'.\n") + (with-current-buffer standard-output + (save-excursion + (re-search-backward "`\\([^`']+\\)'" nil t) + (help-xref-button 1 'help-package-def path))))) + ((eq 'site location) + ;; TODO find a way to find the location on disk and detect if it is + ;; really installed + (princ "\nWhen used it must be installed by a third party.\n")) + ((eq 'elpa location) + ;; TODO find a way to find the ELPA repository + (princ "\nWhen used it is downloaded from an ELPA repository.\n")) + ((and (listp location) (eq 'recipe (car location))) + (princ (concat "\nWhen used it is downloaded using `quelpa' " + "with the following recipe:\n")) + (with-current-buffer standard-output + (save-excursion + (re-search-backward "`\\([^`']+\\)'" nil t) + (help-xref-button + 1 'help-url "https://github.com/quelpa/quelpa"))) + (princ location) + (princ "\n")))) + ;; pre/post init functions + (when (or (oref pkg pre-layers) (oref pkg post-layers)) + (princ (concat "\nAdditional configuration for this package " + "can be found in the following ")) + (if (null layer-list) + (princ "used layers:\n") + (princ "layers:\n")) + (when (oref pkg pre-layers) + (princ "(pre-init) ") + (dolist (layer-sym (sort (oref pkg pre-layers) 'string<)) + (let* ((layer (configuration-layer/get-layer layer-sym)) + (path (concat (oref layer dir) "packages.el"))) + (princ (concat "`" (symbol-name layer-sym) "'")) + (with-current-buffer standard-output + (save-excursion + (re-search-backward "`\\([^`']+\\)'" nil t) + (help-xref-button + 1 'help-function-def + (intern (format "%S/pre-init-%S" layer-sym pkg-symbol)) + path)))) + (princ " ")) + (princ "\n")) + (when (oref pkg post-layers) + (princ "(post-init) ") + (dolist (layer-sym (sort (oref pkg post-layers) 'string<)) + (let* ((layer (configuration-layer/get-layer layer-sym)) + (path (concat (oref layer dir) "packages.el"))) + (princ (concat "`" (symbol-name layer-sym) "'")) + (with-current-buffer standard-output + (save-excursion + (re-search-backward "`\\([^`']+\\)'" nil t) + (help-xref-button + 1 'help-function-def + (intern (format "%S/post-init-%S" layer-sym pkg-symbol)) + path)))) + (princ " ")) + (princ "\n")))) + (princ (concat "\nClick [here] to display an Emacs description " + "for this package.\n")) + (with-current-buffer standard-output + (save-excursion + (re-search-backward "\\(\\[.+\\]\\)" nil t) + (help-xref-button 1 'help-package pkg-symbol)))))) + +(defun configuration-layer//warning (msg &rest args) + "Display MSG as a warning message in buffer `*Messages*'. +If `configuration-layer--inhibit-warnings' is non nil then this function is a +no-op." + (unless configuration-layer--inhibit-warnings + (apply 'spacemacs-buffer/warning msg args))) + +(defun configuration-layer//add-layer (layer &optional usedp) + "Add a LAYER object to the system. +USEDP non-nil means that PKG is a used layer." + (let ((layer-name (oref layer :name))) + (puthash layer-name layer configuration-layer--indexed-layers) + (when usedp + (add-to-list 'configuration-layer--used-layers layer-name)))) + +(defun configuration-layer/remove-layers (layer-names) + "Remove layers with LAYER-NAMES from used layers." + (mapc 'configuration-layer/remove-layer layer-names)) + +(defun configuration-layer/remove-layer (layer-name) + "Remove an used layer with name LAYER-NAME." + (setq configuration-layer--used-layers + (delq layer-name configuration-layer--used-layers))) + +(defun configuration-layer/get-layer (layer-name) + "Return a layer object with name LAYER-NAME. +Return nil if layer object is not found." + (when (ht-contains? configuration-layer--indexed-layers layer-name) + (ht-get configuration-layer--indexed-layers layer-name))) + +(defun configuration-layer/get-layers-list () + "Return a list of all discovered layer symbols." + (ht-keys configuration-layer--indexed-layers)) + +(defun configuration-layer/get-layer-local-dir (layer) + "Return the value of SLOT for the given LAYER." + (let ((obj (ht-get configuration-layer--indexed-layers layer))) + (when obj (concat (oref obj :dir) "local/")))) + +(defun configuration-layer/get-layer-path (layer) + "Return the path for LAYER symbol." + (let ((obj (ht-get configuration-layer--indexed-layers layer))) + (when obj (oref obj :dir)))) + +(defun configuration-layer//add-package (pkg &optional usedp) + "Add a PKG object to the system. +USEDP non-nil means that PKG is a used package." + (let ((pkg-name (oref pkg :name))) + (puthash pkg-name pkg configuration-layer--indexed-packages) + (when usedp + (add-to-list 'configuration-layer--used-packages pkg-name)))) + +(defun configuration-layer/get-packages-list () + "Return a list of all package symbols." + (ht-keys configuration-layer--indexed-packages)) + +(defun configuration-layer/get-package (pkg-name) + "Return a package object with name PKG-NAME. +Return nil if package object is not found." + (when (ht-contains? configuration-layer--indexed-packages pkg-name) + (ht-get configuration-layer--indexed-packages pkg-name))) + +(defun configuration-layer//sort-packages (packages) + "Return a sorted list of PACKAGES objects." + (sort packages (lambda (x y) (string< (symbol-name x) (symbol-name y))))) + +(defun configuration-layer/make-all-packages (&optional usedp) + "Create objects for _all_ packages. +USEDP if non-nil indicates that made packages are used packages." + (configuration-layer/make-packages-from-layers + (configuration-layer/get-layers-list) usedp)) + +(defun configuration-layer/make-packages-from-layers + (layer-names &optional usedp) + "Read the package lists of layers with name LAYER-NAMES and create packages. +USEDP if non-nil indicates that made packages are used packages. +DOTFILE if non-nil will process the dotfile `dotspacemacs-additional-packages' +variable as well." + (dolist (layer-name layer-names) + (let ((layer (configuration-layer/get-layer layer-name))) + (dolist (pkg (cfgl-layer-get-packages layer)) + (let* ((pkg-name (if (listp pkg) (car pkg) pkg)) + (obj (configuration-layer/get-package pkg-name))) + (setq obj (configuration-layer/make-package pkg layer-name obj)) + (configuration-layer//add-package + obj (and (cfgl-package-get-safe-owner obj) usedp))))))) + +(defun configuration-layer/make-packages-from-dotfile (&optional usedp) + "Read the additonal packages declared in the dotfile and create packages. +USEDP if non-nil indicates that made packages are used packages." + (dolist (pkg dotspacemacs-additional-packages) + (let* ((pkg-name (if (listp pkg) (car pkg) pkg)) + (obj (configuration-layer/get-package pkg-name))) + (if obj + (setq obj (configuration-layer/make-package pkg 'dotfile obj)) + (setq obj (configuration-layer/make-package pkg 'dotfile))) + (configuration-layer//add-package obj usedp))) + (dolist (xpkg dotspacemacs-excluded-packages) + (let ((obj (configuration-layer/get-package xpkg))) + (unless obj + (setq obj (configuration-layer/make-package xpkg 'dotfile))) + (configuration-layer//add-package obj usedp) + (cfgl-package-set-property obj :excluded t)))) + +(defun configuration-layer/lazy-install (layer-name &rest props) + "Configure auto-installation of layer with name LAYER-NAME." + (declare (indent 1)) + (when (configuration-layer//lazy-install-p layer-name) + (let ((extensions (spacemacs/mplist-get props :extensions))) + (when (configuration-layer/layer-usedp layer-name) + (let* ((layer (configuration-layer/get-layer layer-name)) + (packages (when layer (cfgl-layer-owned-packages layer))) + (package-names (mapcar (lambda (x) (oref x :name)) packages))) + ;; set lazy install flag for a layer if and only if its owned + ;; distant packages are all not already installed + (let ((lazy (cl-reduce + (lambda (x y) (and x y)) + (mapcar + (lambda (p) + (let ((pkg (configuration-layer/get-package p))) + (or (not (eq layer-name (car (oref pkg :owners)))) + (null (package-installed-p + (oref pkg :name)))))) + (configuration-layer//get-distant-packages + package-names t)) + :initial-value t))) + (oset layer :lazy-install lazy) + (dolist (pkg packages) + (cfgl-package-set-property pkg :lazy-install lazy))))) + (dolist (x extensions) + (let ((ext (car x)) + (mode (cadr x))) + (add-to-list 'configuration-layer--lazy-mode-alist (cons mode ext)) + (add-to-list + 'auto-mode-alist + `(,ext . (lambda () + (configuration-layer//auto-mode + ',layer-name ',mode))))))))) + +(defun configuration-layer//auto-mode (layer-name mode) + "Auto mode support of lazily installed layers." + (let ((layer (configuration-layer/get-layer layer-name))) + (when (or (oref layer :lazy-install) + (not (configuration-layer/layer-usedp layer-name))) + (configuration-layer//lazy-install-packages layer-name mode))) + (when (fboundp mode) (funcall mode))) + +(defun configuration-layer/filter-objects (objects ffunc) + "Return a filtered OBJECTS list where each element satisfies FFUNC." + (reverse (cl-reduce (lambda (acc x) (if (funcall ffunc x) (push x acc) acc)) + objects + :initial-value nil))) + +(defun configuration-layer//get-distant-packages (packages usedp) + "Return the distant packages (ie to be intalled). +If USEDP is non nil then returns only the used packages; if it is nil then +return both used and unused packages." + (configuration-layer/filter-objects + packages + (lambda (x) + (let ((pkg (configuration-layer/get-package x))) + (and (not (memq (oref pkg :location) '(built-in site local))) + (not (stringp (oref pkg :location))) + (or (null usedp) + (and (not (null (oref pkg :owners))) + (not (oref pkg :excluded)) + (cfgl-package-enabledp pkg)))))))) + +(defun configuration-layer//get-private-layer-dir (name) + "Return an absolute path to the private configuration layer string NAME." + (file-name-as-directory + (concat configuration-layer-private-layer-directory name))) + +(defun configuration-layer//copy-template (name template &optional layer-dir) + "Copy and replace special values of TEMPLATE to layer string NAME. +If LAYER_DIR is nil, the private directory is used." + (cl-flet ((substitute (old new) (let ((case-fold-search nil)) + (save-excursion + (goto-char (point-min)) + (while (search-forward old nil t) + (replace-match new t)))))) + (let ((src (concat configuration-layer-template-directory + (format "%s.template" template))) + (dest (if layer-dir + (concat layer-dir "/" (format "%s" template)) + (concat (configuration-layer//get-private-layer-dir name) + (format "%s" template))))) + (copy-file src dest) + (find-file dest) + (substitute "%LAYER_NAME%" name) + (cond + (user-full-name + (substitute "%USER_FULL_NAME%" user-full-name) + (substitute "%USER_MAIL_ADDRESS%" user-mail-address)) + (t + (substitute "%USER_FULL_NAME%" "Sylvain Benner & Contributors") + (substitute "%USER_MAIL_ADDRESS%" "sylvain.benner@gmail.com"))) + (save-buffer)))) + +(defun configuration-layer//directory-type (path) + "Return the type of directory pointed by PATH. +Possible return values: + layer - the directory is a layer + category - the directory is a category + nil - the directory is a regular directory." + (when (file-directory-p path) + (if (string-match + "^+" (file-name-nondirectory + (directory-file-name + (concat configuration-layer-directory path)))) + 'category + (let ((files (directory-files path))) + ;; most frequent files encoutered in a layer are tested first + (when (or (member "packages.el" files) + (member "layers.el" files) + (member "config.el" files) + (member "keybindings.el" files) + (member "funcs.el" files)) + 'layer))))) + +(defun configuration-layer//get-category-from-path (dirpath) + "Return a category symbol from the given DIRPATH. +The directory name must start with `+'. +Returns nil if the directory is not a category." + (when (file-directory-p dirpath) + (let ((dirname (file-name-nondirectory + (directory-file-name + (concat configuration-layer-directory + dirpath))))) + (when (string-match "^+" dirname) + (intern (substring dirname 1)))))) + +(defun configuration-layer/discover-layers () + "Initialize `configuration-layer--indexed-layers' with layer directories." + ;; load private layers at the end on purpose we asume that the user layers + ;; must have the final word on configuration choices. Let + ;; `dotspacemacs-directory' override the private directory if it exists. + (setq configuration-layer--indexed-layers (make-hash-table :size 1024)) + (let ((search-paths (append (list configuration-layer-directory) + dotspacemacs-configuration-layer-path + (list configuration-layer-private-layer-directory) + (when dotspacemacs-directory + (list dotspacemacs-directory)))) + (discovered '())) + ;; depth-first search of subdirectories + (while search-paths + (let ((current-path (car search-paths))) + (setq search-paths (cdr search-paths)) + (dolist (sub (directory-files current-path t nil 'nosort)) + ;; ignore ".", ".." and non-directories + (unless (or (string-equal ".." (substring sub -2)) + (string-equal "." (substring sub -1)) + (not (file-directory-p sub))) + (let ((type (configuration-layer//directory-type sub))) + (cond + ((eq 'category type) + (let ((category (configuration-layer//get-category-from-path + sub))) + (spacemacs-buffer/message "-> Discovered category: %S" + category) + (push category configuration-layer-categories) + (setq search-paths (cons sub search-paths)))) + ((eq 'layer type) + (let* ((layer-name-str (file-name-nondirectory sub)) + (layer-name (intern layer-name-str)) + (indexed-layer (configuration-layer/get-layer + layer-name))) + (if indexed-layer + ;; the same layer may have been discovered twice, + ;; in which case we don't need a warning + (unless (string-equal (oref indexed-layer :dir) sub) + (configuration-layer//warning + (concat + "Duplicated layer %s detected in directory \"%s\", " + "replacing old directory \"%s\" with new directory.") + layer-name-str sub (oref indexed-layer :dir)) + (oset indexed-layer :dir sub)) + (spacemacs-buffer/message + "-> Discovered configuration layer: %s" layer-name-str) + (configuration-layer//add-layer + (configuration-layer/make-layer layer-name nil nil sub))))) + (t + ;; layer not found, add it to search path + (setq search-paths (cons sub search-paths))))))))))) + +(defun configuration-layer/declare-layers (layers-specs) + "Declare layers with LAYERS-SPECS." + (mapc 'configuration-layer/declare-layer layers-specs)) + +(defun configuration-layer/declare-layer (layer-specs) + "Declare a single layer with spec LAYER-SPECS. +Set the variable `configuration-layer--declared-layers-usedp' to control +wether the declared layer is an used one or not." + (let* ((layer-name (if (listp layer-specs) (car layer-specs) layer-specs)) + (layer (configuration-layer/get-layer layer-name)) + (usedp configuration-layer--declared-layers-usedp)) + (if layer + (let ((obj (configuration-layer/make-layer + layer-specs + (configuration-layer/get-layer layer-name) + usedp))) + (configuration-layer//add-layer obj usedp) + (configuration-layer//set-layer-variables obj) + (when (or usedp configuration-layer--load-packages-files) + (configuration-layer//load-layer-files layer-name '("layers.el")))) + (configuration-layer//warning "Unknown layer %s declared in dotfile." + layer-name)))) + +(defun configuration-layer//declare-used-layers (layers-specs) + "Declare used layers from LAYERS-SPECS list." + (setq configuration-layer--used-layers nil) + (let ((configuration-layer--declared-layers-usedp t)) + (unless configuration-layer-exclude-all-layers + (dolist (layer-specs layers-specs) + (let* ((layer-name (if (listp layer-specs) + (car layer-specs) + layer-specs)) + (layer (configuration-layer/get-layer layer-name))) + (if layer + (let ((layer-path (oref layer :dir))) + (unless (string-match-p "+distributions" layer-path) + (configuration-layer/declare-layer layer-specs))) + (configuration-layer//warning + "Unknown layer %s declared in dotfile." layer-name)))) + (setq configuration-layer--used-layers + (reverse configuration-layer--used-layers))) + ;; distribution and bootstrap layers are always first + (let ((distribution (if configuration-layer-force-distribution + configuration-layer-force-distribution + dotspacemacs-distribution))) + (unless (eq 'spacemacs-bootstrap distribution) + (configuration-layer/declare-layer distribution))) + (configuration-layer/declare-layer 'spacemacs-bootstrap))) + +(defun configuration-layer//set-layers-variables (layers) + "Set the configuration variables for the passed LAYERS." + (mapc 'configuration-layer//set-layer-variables layers)) + +(defun configuration-layer//set-layer-variables (layer) + "Set the configuration variables for the passed LAYER." + (let ((variables (oref layer :variables))) + (while variables + (let ((var (pop variables))) + (if (consp variables) + (condition-case-unless-debug err + (set-default var (eval (pop variables))) + ('error + (configuration-layer//increment-error-count) + (spacemacs-buffer/append + (format (concat "\nAn error occurred while setting layer " + "variable %s " + "(error: %s). Be sure to quote the value " + "if needed.\n") var err)))) + (configuration-layer//warning "Missing value for variable %s !" + var)))))) + +(defun configuration-layer/layer-usedp (layer-name) + "Return non-nil if LAYER-NAME is the name of a used layer." + (let ((obj (configuration-layer/get-layer layer-name))) + (when obj (memq layer-name configuration-layer--used-layers)))) + +(defun configuration-layer/package-usedp (name) + "Return non-nil if NAME is the name of a used package." + (let ((obj (configuration-layer/get-package name))) + (and obj (cfgl-package-get-safe-owner obj) + (not (oref obj :excluded))))) + +(defun configuration-layer/package-lazy-installp (name) + "Return non-nil if NAME is the name of a package to be lazily installed." + (let ((obj (configuration-layer/get-package name))) + (when obj (oref obj :lazy-install)))) + +(defun configuration-layer//configure-layers (layer-names) + "Configure layers with LAYER-NAMES." + (let ((warning-minimum-level :error)) + (dolist (layer-name layer-names) + (configuration-layer//load-layer-files layer-name '("config.el"))))) + +(defun configuration-layer//declare-used-packages (layers) + "Declare used packages contained in LAYERS." + (setq configuration-layer--used-packages nil) + (let* ((warning-minimum-level :error)) + (configuration-layer/make-packages-from-layers layers t) + (configuration-layer/make-packages-from-dotfile t) + (setq configuration-layer--used-packages + (configuration-layer//sort-packages + configuration-layer--used-packages)))) + +(defun configuration-layer//load-layers-files (layer-names files) + "Load the files of list FILES for all passed LAYER-NAMES." + (dolist (layer-name layer-names) + (configuration-layer//load-layer-files layer-name files))) + +(defun configuration-layer//load-layer-files (layer-name files) + "Load the files of list FILES for the layer with the given LAYER-NAME." + (let ((obj (configuration-layer/get-layer layer-name))) + (when obj + (dolist (file files) + (let ((file (concat (oref obj :dir) file))) + (if (file-exists-p file) (load file))))))) + +(defun configuration-layer/configured-packages-stats (packages) + "Return a statistics alist regarding the number of configured PACKAGES." + `((total ,(length packages)) + (elpa ,(length (configuration-layer/filter-objects + packages + (lambda (x) + (let ((pkg (configuration-layer/get-package x))) + (eq 'elpa (oref pkg :location))))))) + (recipe ,(length (configuration-layer/filter-objects + packages + (lambda (x) + (let* ((pkg (configuration-layer/get-package x)) + (location (oref pkg :location))) + (and (listp location) + (eq 'recipe (car location)))))))) + (local ,(length (configuration-layer/filter-objects + packages + (lambda (x) + (let ((pkg (configuration-layer/get-package x))) + (memq (oref pkg :location) '(local site))))))) + (built-in ,(length (configuration-layer/filter-objects + packages + (lambda (x) + (let ((pkg (configuration-layer/get-package x))) + (eq 'built-in (oref pkg :location))))))))) + +(defun configuration-layer//install-package (pkg) + "Unconditionally install the package PKG." + (let* ((layer (when pkg (car (oref pkg :owners)))) + (location (when pkg (oref pkg :location))) + (min-version (when pkg (oref pkg :min-version)))) + (spacemacs-buffer/replace-last-line + (format "--> installing %s: %s%s... [%s/%s]" + (if layer "package" "dependency") + pkg-name (if layer (format "@%S" layer) "") + installed-count not-inst-count) t) + (spacemacs//redisplay) + (unless (package-installed-p pkg-name min-version) + (condition-case-unless-debug err + (cond + ((or (null pkg) (eq 'elpa location)) + (configuration-layer//install-from-elpa pkg-name) + (when pkg (cfgl-package-set-property pkg :lazy-install nil))) + ((and (listp location) (eq 'recipe (car location))) + (configuration-layer//install-from-recipe pkg) + (cfgl-package-set-property pkg :lazy-install nil)) + (t (configuration-layer//warning "Cannot install package %S." + pkg-name))) + ('error + (configuration-layer//increment-error-count) + (spacemacs-buffer/append + (format (concat "\nAn error occurred while installing %s " + "(error: %s)\n") pkg-name err)) + (spacemacs//redisplay)))))) + +(defun configuration-layer//lazy-install-p (layer-name) + "Return non nil if the layer with LAYER-NAME should be lazy installed." + (or (eq 'all dotspacemacs-enable-lazy-installation) + (and (memq dotspacemacs-enable-lazy-installation '(unused t)) + (not (configuration-layer/layer-usedp layer-name))))) + +(defun configuration-layer//lazy-install-packages (layer-name mode) + "Install layer with LAYER-NAME to support MODE." + (when (or (not dotspacemacs-ask-for-lazy-installation) + (yes-or-no-p (format + (concat "Support for %s requires installation of " + "layer %s, do you want to install it?") + mode layer-name))) + (when (dotspacemacs/add-layer layer-name) + (configuration-layer/sync 'no-install)) + (let* ((layer (configuration-layer/get-layer layer-name)) + (inst-pkgs + (delq nil + (mapcar + (lambda (x) + (let* ((pkg-name (if (listp x) (car x) x)) + (pkg (configuration-layer/get-package pkg-name))) + (cfgl-package-set-property pkg :lazy-install nil) + (when (memq pkg-name + configuration-layer--used-distant-packages) + pkg-name))) + (oref layer :packages))))) + (let ((last-buffer (current-buffer)) + (sorted-pkg (configuration-layer//sort-packages inst-pkgs))) + (spacemacs-buffer/goto-buffer) + (goto-char (point-max)) + (configuration-layer//install-packages sorted-pkg) + (configuration-layer//configure-packages sorted-pkg) + (configuration-layer//load-layer-files layer '("keybindings.el")) + (oset layer :lazy-install nil) + (switch-to-buffer last-buffer))))) + +(defun configuration-layer//install-packages (packages) + "Install PACKAGES which are not lazy installed." + (interactive) + ;; Force the display of warning buffers at the bottom + (let ((display-buffer-alist + '(("\\(\\*Compile-Log\\*\\)\\|\\(\\*Warnings\\*\\)" + (display-buffer-in-side-window) + (inhibit-same-window . t) + (side . bottom) + (window-height . 0.2))))) + ;; ensure we have quelpa available first + (configuration-layer//install-quelpa) + (let* ((upkg-names (configuration-layer//get-uninstalled-packages packages)) + (not-inst-count (length upkg-names)) + installed-count) + ;; installation + (when upkg-names + (spacemacs-buffer/append + (format "Found %s new package(s) to install...\n" + not-inst-count)) + (configuration-layer/retrieve-package-archives) + (setq installed-count 0) + (spacemacs//redisplay) + (dolist (pkg-name upkg-names) + (setq installed-count (1+ installed-count)) + (configuration-layer//install-package + (configuration-layer/get-package pkg-name))) + (spacemacs-buffer/append "\n"))))) + +(defun configuration-layer//install-from-elpa (pkg-name) + "Install PKG from ELPA." + (if (not (assq pkg-name package-archive-contents)) + (spacemacs-buffer/append + (format (concat "\nPackage %s is unavailable. " + "Is the package name misspelled?\n") + pkg-name)) + (let ((pkg-desc (assq pkg-name package-archive-contents))) + (dolist + (dep (configuration-layer//get-package-deps-from-archive + pkg-name)) + (if (package-installed-p (car dep) (cadr dep)) + (configuration-layer//activate-package (car dep)) + (configuration-layer//install-from-elpa (car dep)))) + (if pkg-desc + (package-install (cadr pkg-desc)) + (package-install pkg-name))))) + +(defun configuration-layer//install-from-recipe (pkg) + "Install PKG from a recipe." + (let* ((pkg-name (oref pkg :name)) + (layer (car (oref pkg :owners))) + (recipe (cons pkg-name (cdr (oref pkg :location))))) + (if recipe + (quelpa recipe) + (configuration-layer//warning + (concat "Cannot find any recipe for package %S! Be sure " + "to add a recipe for it in alist %S.") + pkg-name recipes-var)))) + +(defun configuration-layer//filter-packages-with-deps + (pkg-names filter &optional use-archive) + "Return a filtered PKG-NAMES list where each elements satisfies FILTER." + (when pkg-names + (let (result) + (dolist (pkg-name pkg-names) + ;; recursively check dependencies + (let* ((deps + (if use-archive + (configuration-layer//get-package-deps-from-archive + pkg-name) + (configuration-layer//get-package-deps-from-alist pkg-name))) + (install-deps + (when deps (configuration-layer//filter-packages-with-deps + (mapcar 'car deps) filter)))) + (when install-deps + (setq result (append install-deps result)))) + (when (funcall filter pkg-name) + (add-to-list 'result pkg-name t))) + (delete-dups result)))) + +(defun configuration-layer//get-uninstalled-packages (pkg-names) + "Return a filtered list of PKG-NAMES to install." + (configuration-layer//filter-packages-with-deps + pkg-names (lambda (x) + (let* ((pkg (configuration-layer/get-package x)) + (min-version (when pkg (oref pkg :min-version)))) + (not (package-installed-p x min-version)))))) + +(defun configuration-layer//package-has-recipe-p (pkg-name) + "Return non nil if PKG-NAME is the name of a package declared with a recipe." + (when (configuration-layer/get-package pkg-name) + (let* ((pkg (configuration-layer/get-package pkg-name)) + (location (oref pkg :location))) + (and (listp location) (eq 'recipe (car location)))))) + +(defun configuration-layer//get-package-recipe (pkg-name) + "Return the recipe for PGK-NAME if it has one." + (let ((pkg (configuration-layer/get-package pkg-name))) + (when pkg + (let ((location (oref pkg :location))) + (when (and (listp location) (eq 'recipe (car location))) + (cons pkg-name (cdr location))))))) + +(defun configuration-layer//new-version-available-p (pkg-name) + "Return non nil if there is a new version available for PKG-NAME." + (let ((recipe (configuration-layer//get-package-recipe pkg-name)) + (cur-version (configuration-layer//get-package-version-string pkg-name)) + (quelpa-upgrade-p t) + new-version) + (when cur-version + (setq new-version + (if recipe + (or (quelpa-checkout recipe (expand-file-name (symbol-name pkg-name) quelpa-build-dir)) cur-version) + (configuration-layer//get-latest-package-version-string + pkg-name))) + ;; (message "%s: %s > %s ?" pkg-name cur-version new-version) + (if new-version + (version< cur-version new-version) + (cl-pushnew pkg-name + configuration-layer--check-new-version-error-packages + :test #'eq) + nil)))) + +(defun configuration-layer//get-packages-to-update (pkg-names) + "Return a filtered list of PKG-NAMES to update." + (configuration-layer//filter-packages-with-deps + pkg-names 'configuration-layer//new-version-available-p 'use-archive)) + +(defun configuration-layer//configure-packages (packages) + "Configure all passed PACKAGES honoring the steps order." + (setq spacemacs-loading-dots-chunk-threshold + (/ (length configuration-layer--used-packages) + spacemacs-loading-dots-chunk-count)) + (spacemacs-buffer/message "+ Configuring bootstrap packages...") + (configuration-layer//configure-packages-2 + (configuration-layer/filter-objects + packages (lambda (x) + (let ((pkg (configuration-layer/get-package x))) + (eq 'bootstrap (oref pkg :step)))))) + (spacemacs-buffer/message "+ Configuring pre packages...") + (configuration-layer//configure-packages-2 + (configuration-layer/filter-objects + packages (lambda (x) + (let ((pkg (configuration-layer/get-package x))) + (eq 'pre (oref pkg :step)))))) + (spacemacs-buffer/message "+ Configuring packages...") + (configuration-layer//configure-packages-2 + (configuration-layer/filter-objects + packages (lambda (x) + (let ((pkg (configuration-layer/get-package x))) + (null (oref pkg :step))))))) + +(defun configuration-layer//configure-packages-2 (packages) + "Configure all passed PACKAGES." + (dolist (pkg-name packages) + (spacemacs-buffer/loading-animation) + (let ((pkg (configuration-layer/get-package pkg-name))) + (cond + ((oref pkg :lazy-install) + (spacemacs-buffer/message + (format "%S ignored since it can be lazily installed." pkg-name))) + ((and (oref pkg :excluded) + (not (oref pkg :protected))) + (spacemacs-buffer/message + (format "%S ignored since it has been excluded." pkg-name))) + ((null (oref pkg :owners)) + (spacemacs-buffer/message + (format "%S ignored since it has no owner layer." pkg-name))) + ((not (cfgl-package-enabledp pkg t)) + (spacemacs-buffer/message (format "%S is toggled off." pkg-name))) + (t + ;; load-path + (let ((location (oref pkg :location))) + (cond + ((stringp location) + (if (file-directory-p location) + (push (file-name-as-directory location) load-path) + (configuration-layer//warning + "Location path for package %S does not exists (value: %s)." + pkg location))) + ((and (eq 'local location) + (eq 'dotfile (car (oref pkg :owners)))) + (push (file-name-as-directory + (concat configuration-layer-private-directory "local/" + (symbol-name (oref pkg :name)))) + load-path)) + ((eq 'local location) + (let* ((owner (configuration-layer/get-layer + (car (oref pkg :owners)))) + (dir (when owner (oref owner :dir)))) + (push (format "%slocal/%S/" dir pkg-name) load-path))))) + ;; configuration + (unless (memq (oref pkg :location) '(local site built-in)) + (configuration-layer//activate-package pkg-name)) + (cond + ((eq 'dotfile (car (oref pkg :owners))) + (spacemacs-buffer/message + (format "%S is configured in the dotfile." pkg-name))) + (t + (configuration-layer//configure-package pkg)))))))) + +(defun configuration-layer//package-enabled-p (pkg layer) + "Returns true if PKG should be configured for LAYER. +LAYER must not be the owner of PKG." + (let* ((owner (configuration-layer/get-layer (car (oref pkg :owners)))) + (disabled (oref owner :disabled-for)) + (enabled (oref owner :enabled-for))) + (if (not (eq 'unspecified enabled)) + (memq layer enabled) + (not (memq layer disabled))))) + +(defun configuration-layer//configure-package (pkg) + "Configure PKG object." + (let* ((pkg-name (oref pkg :name)) + (owner (car (oref pkg :owners)))) + (spacemacs-buffer/message (format "Configuring %S..." pkg-name)) + ;; pre-init + (mapc + (lambda (layer) + (when (configuration-layer/layer-usedp layer) + (if (not (configuration-layer//package-enabled-p pkg layer)) + (spacemacs-buffer/message + (format " -> ignored pre-init (%S)..." layer)) + (spacemacs-buffer/message + (format " -> pre-init (%S)..." layer)) + (condition-case-unless-debug err + (funcall (intern (format "%S/pre-init-%S" layer pkg-name))) + ('error + (configuration-layer//increment-error-count) + (spacemacs-buffer/append + (format + (concat "\nAn error occurred while pre-configuring %S " + "in layer %S (error: %s)\n") + pkg-name layer err))))))) + (oref pkg :pre-layers)) + ;; init + (spacemacs-buffer/message (format " -> init (%S)..." owner)) + (funcall (intern (format "%S/init-%S" owner pkg-name))) + ;; post-init + (mapc + (lambda (layer) + (when (configuration-layer/layer-usedp layer) + (if (not (configuration-layer//package-enabled-p pkg layer)) + (spacemacs-buffer/message + (format " -> ignored post-init (%S)..." layer)) + (spacemacs-buffer/message + (format " -> post-init (%S)..." layer)) + (condition-case-unless-debug err + (funcall (intern (format "%S/post-init-%S" layer pkg-name))) + ('error + (configuration-layer//increment-error-count) + (spacemacs-buffer/append + (format + (concat "\nAn error occurred while post-configuring %S " + "in layer %S (error: %s)\n") + pkg-name layer err))))))) + (oref pkg :post-layers)))) + +(defun configuration-layer//cleanup-rollback-directory () + "Clean up the rollback directory." + (let* ((dirattrs (delq nil + (mapcar (lambda (d) + (unless (eq t d) d)) + (directory-files-and-attributes + configuration-layer-rollback-directory + nil "\\`\\(\\.\\{0,2\\}[^.\n].*\\)\\'" t)))) + (dirs (sort dirattrs + (lambda (d e) + (time-less-p (nth 6 d) (nth 6 e)))))) + (dotimes (c (- (length dirs) dotspacemacs-max-rollback-slots)) + (delete-directory (concat configuration-layer-rollback-directory + "/" (car (pop dirs))) + t t)))) + +(defun configuration-layer/update-packages (&optional always-update) + "Update packages. + +If called with a prefix argument ALWAYS-UPDATE, assume yes to update." + (interactive "P") + (spacemacs-buffer/insert-page-break) + (spacemacs-buffer/append "\nUpdating package archives, please wait...\n") + (configuration-layer/retrieve-package-archives nil 'force) + (setq configuration-layer--check-new-version-error-packages nil) + (let* ((update-packages + (configuration-layer//get-packages-to-update + configuration-layer--used-distant-packages)) + (skipped-count (length + configuration-layer--check-new-version-error-packages)) + (date (format-time-string "%y-%m-%d_%H.%M.%S")) + (rollback-dir (expand-file-name + (concat configuration-layer-rollback-directory + (file-name-as-directory date)))) + (upgrade-count (length update-packages)) + (upgraded-count 0) + (update-packages-alist)) + (when configuration-layer--check-new-version-error-packages + (spacemacs-buffer/append + (format (concat "--> Warning: cannot update %s package(s), possibly due" + " to a temporary network problem: %s\n") + skipped-count + (mapconcat #'symbol-name + configuration-layer--check-new-version-error-packages + " ")))) + ;; (message "packages to udpate: %s" update-packages) + (when (> upgrade-count 0) + (spacemacs-buffer/append + (format (concat "--> Found %s package(s) to update" + (if (> skipped-count 0) + (format " (skipped %s):\n" skipped-count) + ":\n")) + upgrade-count) t) + (mapc (lambda (x) + (spacemacs-buffer/append + (format (if (memq (intern x) dotspacemacs-frozen-packages) + "%s (won't be updated because package is frozen)\n" + "%s\n") x) t)) + (sort (mapcar 'symbol-name update-packages) 'string<)) + (if (and (not always-update) + (not (yes-or-no-p + (format "Do you want to update %s package(s) ? " + upgrade-count)))) + (spacemacs-buffer/append "Packages update has been cancelled.\n" t) + ;; backup the package directory and construct an alist + ;; variable to be cached for easy update and rollback + (spacemacs-buffer/append + "--> performing backup of package(s) to update...\n" t) + (spacemacs//redisplay) + (dolist (pkg update-packages) + (unless (memq pkg dotspacemacs-frozen-packages) + (let* ((src-dir (configuration-layer//get-package-directory pkg)) + (dest-dir (expand-file-name + (concat rollback-dir + (file-name-as-directory + (file-name-nondirectory src-dir)))))) + (copy-directory src-dir dest-dir 'keeptime 'create 'copy-content) + (push (cons pkg (file-name-nondirectory src-dir)) + update-packages-alist)))) + (spacemacs/dump-vars-to-file + '(update-packages-alist) + (expand-file-name (concat rollback-dir + configuration-layer-rollback-info))) + (dolist (pkg update-packages) + (unless (memq pkg dotspacemacs-frozen-packages) + (setq upgraded-count (1+ upgraded-count)) + (spacemacs-buffer/replace-last-line + (format "--> preparing update of package %s... [%s/%s]" + pkg upgraded-count upgrade-count) t) + (spacemacs//redisplay) + (configuration-layer//package-delete pkg))) + (spacemacs-buffer/append + (format "\n--> %s package(s) to be updated.\n" upgraded-count)) + (spacemacs-buffer/append + (concat "\nEmacs has to be restarted to actually install the " + "new version of the packages (SPC q r).\n")) + (configuration-layer//cleanup-rollback-directory) + (spacemacs//redisplay))) + (when (eq upgrade-count 0) + (spacemacs-buffer/append "--> All packages are up to date.\n") + (spacemacs//redisplay)))) + +(defun configuration-layer//ido-candidate-rollback-slot () + "Return a list of candidates to select a rollback slot." + (let ((rolldir configuration-layer-rollback-directory)) + (when (file-exists-p rolldir) + (reverse + (delq nil (mapcar + (lambda (x) + (when (and (file-directory-p (concat rolldir x)) + (not (or (string= "." x) (string= ".." x)))) + (let ((p (length (directory-files (file-name-as-directory + (concat rolldir x)))))) + ;; -3 for . .. and rollback-info + (format "%s (%s packages)" x (- p 3))))) + (directory-files rolldir))))))) + +(defun configuration-layer/rollback (slot) + "Rollback all the packages in the given SLOT. +If called interactively and SLOT is nil then an ido buffers appears +to select one." + (interactive + (list + (if (boundp 'slot) slot + (let ((candidates (configuration-layer//ido-candidate-rollback-slot))) + (when candidates + (ido-completing-read "Rollback slots (most recent are first): " + candidates)))))) + (spacemacs-buffer/insert-page-break) + (if (not slot) + (message "No rollback slot available.") + (string-match "^\\(.+?\\)\s.*$" slot) + (let* ((slot-dir (match-string 1 slot)) + (rollback-dir (file-name-as-directory + (concat configuration-layer-rollback-directory + (file-name-as-directory slot-dir)))) + (info-file (expand-file-name + (concat rollback-dir + configuration-layer-rollback-info)))) + (spacemacs-buffer/append + (format "\nRollbacking ELPA packages from slot %s...\n" slot-dir)) + (load-file info-file) + (let ((rollback-count (length update-packages-alist)) + (rollbacked-count 0)) + (spacemacs-buffer/append + (format "Found %s package(s) to rollback...\n" rollback-count)) + (spacemacs//redisplay) + (dolist (apkg update-packages-alist) + (let* ((pkg (car apkg)) + (pkg-dir-name (cdr apkg)) + (installed-ver + (configuration-layer//get-package-version-string pkg)) + (elpa-dir (file-name-as-directory package-user-dir)) + (src-dir (expand-file-name + (concat rollback-dir (file-name-as-directory + pkg-dir-name)))) + (dest-dir (expand-file-name + (concat elpa-dir (file-name-as-directory + pkg-dir-name))))) + (unless (memq pkg dotspacemacs-frozen-packages) + (setq rollbacked-count (1+ rollbacked-count)) + (if (string-equal (format "%S-%s" pkg installed-ver) pkg-dir-name) + (spacemacs-buffer/replace-last-line + (format "--> package %s already rolled back! [%s/%s]" + pkg rollbacked-count rollback-count) t) + ;; rollback the package + (spacemacs-buffer/replace-last-line + (format "--> rolling back package %s... [%s/%s]" + pkg rollbacked-count rollback-count) t) + (configuration-layer//package-delete pkg) + (copy-directory src-dir dest-dir + 'keeptime 'create 'copy-content))) + (spacemacs//redisplay))) + (spacemacs-buffer/append + (format "\n--> %s packages rolled back.\n" rollbacked-count)) + (spacemacs-buffer/append + "\nEmacs has to be restarted for the changes to take effect.\n"))))) + +(defun configuration-layer//activate-package (pkg) + "Activate PKG." + (unless (memq pkg package-activated-list) + (package-activate pkg))) + +(defun configuration-layer//get-packages-dependencies () + "Returns dependencies hash map for all packages in `package-alist'." + (let ((result (make-hash-table :size 512))) + (dolist (pkg package-alist) + (let* ((pkg-sym (car pkg)) + (deps (configuration-layer//get-package-deps-from-alist pkg-sym))) + (dolist (dep deps) + (let* ((dep-sym (car dep)) + (value (ht-get result dep-sym))) + (puthash dep-sym + (if value (add-to-list 'value pkg-sym) (list pkg-sym)) + result))))) + result)) + +(defun configuration-layer//get-implicit-packages (packages) + "Returns packages in `packages-alist' which are not found in PACKAGES." + (let (imp-pkgs) + (dolist (pkg package-alist) + (let ((pkg-sym (car pkg))) + (unless (memq pkg-sym packages) + (add-to-list 'imp-pkgs pkg-sym)))) + imp-pkgs)) + +(defun configuration-layer//get-orphan-packages + (dist-pkgs implicit-pkgs dependencies) + "Return orphan packages." + (let (result) + (dolist (imp-pkg implicit-pkgs) + (when (configuration-layer//is-package-orphan + imp-pkg dist-pkgs dependencies) + (add-to-list 'result imp-pkg))) + result)) + +(defun configuration-layer//is-package-orphan (pkg-name dist-pkgs dependencies) + "Returns not nil if PKG-NAME is the name of an orphan package." + (unless (or (memq pkg-name dist-pkgs) + (memq pkg-name configuration-layer--protected-packages)) + (if (ht-contains? dependencies pkg-name) + (let ((parents (ht-get dependencies pkg-name))) + (cl-reduce (lambda (x y) (and x y)) + (mapcar (lambda (p) (configuration-layer//is-package-orphan + p dist-pkgs dependencies)) + parents) + :initial-value t)) + (not (memq pkg-name dist-pkgs))))) + +(defun configuration-layer//get-package-directory (pkg-name) + "Return the directory path for package with name PKG-NAME." + (let ((pkg-desc (assq pkg-name package-alist))) + (package-desc-dir (cadr pkg-desc)))) + +(defun configuration-layer//get-package-deps-from-alist (pkg-name) + "Return the dependencies alist for package with name PKG-NAME." + (let ((pkg-desc (assq pkg-name package-alist))) + (when pkg-desc (package-desc-reqs (cadr pkg-desc))))) + +(defun configuration-layer//get-package-deps-from-archive (pkg-name) + "Return the dependencies alist for a PKG-NAME from the archive data." + (let* ((pkg-arch (assq pkg-name package-archive-contents)) + (reqs (when pkg-arch (package-desc-reqs (cadr pkg-arch))))) + ;; recursively get the requirements of reqs + (dolist (req reqs) + (let* ((pkg-name2 (car req)) + (reqs2 (configuration-layer//get-package-deps-from-archive + pkg-name2))) + (when reqs2 (setq reqs (append reqs2 reqs))))) + reqs)) + +(defun configuration-layer//get-package-version-string (pkg-name) + "Return the version string for package with name PKG-NAME." + (let ((pkg-desc (assq pkg-name package-alist))) + (when pkg-desc + (package-version-join (package-desc-version (cadr pkg-desc)))))) + +(defun configuration-layer//get-package-version (pkg-name) + "Return the version list for package with name PKG-NAME." + (let ((version-string (configuration-layer//get-package-version-string + pkg-name))) + (unless (string-empty-p version-string) + (version-to-list version-string)))) + +(defun configuration-layer//get-latest-package-version-string (pkg-name) + "Return the version string for package with name PKG-NAME." + (let ((pkg-arch (assq pkg-name package-archive-contents))) + (when pkg-arch + (package-version-join (package-desc-version (cadr pkg-arch)))))) + +(defun configuration-layer//get-latest-package-version (pkg-name) + "Return the versio list for package with name PKG-NAME." + (let ((version-string + (configuration-layer//get-latest-package-version-string pkg-name))) + (unless (string-empty-p version-string) + (version-to-list version-string)))) + +(defun configuration-layer//package-delete (pkg-name) + "Delete package with name PKG-NAME." + (cond + ((version<= "25.0.50" emacs-version) + (let ((p (cadr (assq pkg-name package-alist)))) + ;; add force flag to ignore dependency checks in Emacs25 + (when p (package-delete p t t)))) + (t (let ((p (cadr (assq pkg-name package-alist)))) + (when p (package-delete p)))))) + +(defun configuration-layer/delete-orphan-packages (packages) + "Delete PACKAGES if they are orphan." + (interactive) + (let* ((dependencies (configuration-layer//get-packages-dependencies)) + (implicit-packages (configuration-layer//get-implicit-packages + packages)) + (orphans (configuration-layer//get-orphan-packages + packages + implicit-packages + dependencies)) + (orphans-count (length orphans)) + deleted-count) + ;; (message "dependencies: %s" dependencies) + ;; (message "implicit: %s" implicit-packages) + ;; (message "orphans: %s" orphans) + (if orphans + (progn + (spacemacs-buffer/append + (format "Found %s orphan package(s) to delete...\n" + orphans-count)) + (setq deleted-count 0) + (dolist (orphan orphans) + (setq deleted-count (1+ deleted-count)) + (spacemacs-buffer/replace-last-line + (format "--> deleting %s... [%s/%s]" + orphan + deleted-count + orphans-count) t) + (configuration-layer//package-delete orphan) + (spacemacs//redisplay)) + (spacemacs-buffer/append "\n")) + (spacemacs-buffer/message "No orphan package to delete.")))) + +(defun configuration-layer//gather-auto-mode-extensions (mode) + "Return a regular expression matching all the extensions associate to MODE." + (let (gather-extensions) + (dolist (x auto-mode-alist) + (let ((ext (car x)) + (auto-mode (cdr x))) + (when (and (stringp ext) + (symbolp auto-mode) + (eq auto-mode mode)) + (push (car x) gather-extensions)))) + (when gather-extensions + (concat "\\(" + (string-join gather-extensions "\\|") + "\\)")))) + +(defun configuration-layer//lazy-install-extensions-for-layer (layer-name) + "Return an alist of owned modes and extensions for the passed layer." + (let* ((layer (configuration-layer/get-layer layer-name)) + (packages (cfgl-layer-owned-packages layer)) + result) + (dolist (pkg packages) + (let ((pkg-sym (oref pkg :name))) + (dolist (mode (list pkg-sym (intern (format "%S-mode" pkg-sym)))) + (let ((ext (configuration-layer//gather-auto-mode-extensions mode))) + (when ext (push (cons mode ext) result)))))) + result)) + +(defun configuration-layer//insert-lazy-install-form (layer-name mode ext) + "Insert a configuration form for lazy installation of MODE." + (let ((str (concat "(configuration-layer/lazy-install '" + (symbol-name layer-name) + " :extensions '(" + (let ((print-quoted t)) (prin1-to-string ext)) + " " + (symbol-name mode) + "))\n"))) + (insert str))) + +(defun configuration-layer/insert-lazy-install-configuration () + "Prompt for a layer and insert the forms to configure lazy installation." + (interactive) + (let ((layer-name + (intern (completing-read + "Choose a used layer" + (sort configuration-layer--used-layers + (lambda (x y) + (string< (oref (cdr x) :name) + (oref (cdr y) :name)))))))) + (let ((mode-exts (configuration-layer//lazy-install-extensions-for-layer + layer-name))) + (dolist (x mode-exts) + (configuration-layer//insert-lazy-install-form + layer-name (car x) (cdr x)))))) + +(defvar configuration-layer--spacemacs-startup-time nil + "Spacemacs full startup duration.") + +(defun configuration-layer/display-summary (start-time) + "Display a summary of loading time." + (unless configuration-layer--spacemacs-startup-time + (setq configuration-layer--spacemacs-startup-time + (float-time (time-subtract (current-time) emacs-start-time)))) + (let ((stats (configuration-layer/configured-packages-stats + configuration-layer--used-packages))) + (spacemacs-buffer/insert-page-break) + (spacemacs-buffer/append + (format "\n%s packages loaded in %.3fs (e:%s r:%s l:%s b:%s)" + (cadr (assq 'total stats)) + configuration-layer--spacemacs-startup-time + (cadr (assq 'elpa stats)) + (cadr (assq 'recipe stats)) + (cadr (assq 'local stats)) + (cadr (assq 'built-in stats)))) + (with-current-buffer (get-buffer-create spacemacs-buffer-name) + (let ((buffer-read-only nil)) + (spacemacs-buffer//center-line) + (insert "\n"))))) + +(defun configuration-layer/load-or-install-protected-package + (pkg &optional log file-to-load) + "Load PKG package, and protect it against being deleted as an orphan. +See `configuration-layer/load-or-install-package' for more information." + (push pkg configuration-layer--protected-packages) + (configuration-layer/load-or-install-package pkg log file-to-load)) + +(defun configuration-layer/load-or-install-package + (pkg &optional log file-to-load) + "Load PKG package. PKG will be installed if it is not already installed. +Whenever the initial require fails the absolute path to the package +directory is returned. +If LOG is non-nil a message is displayed in spacemacs-buffer-mode buffer. +FILE-TO-LOAD is an explicit file to load after the installation." + (let ((warning-minimum-level :error)) + (unless (require pkg nil 'noerror) + ;; not installed, we try to initialize package.el only if required to + ;; precious seconds during boot time + (require 'cl) + (let ((pkg-elpa-dir (spacemacs//get-package-directory pkg))) + (if pkg-elpa-dir + (add-to-list 'load-path pkg-elpa-dir) + ;; install the package + (when log + (spacemacs-buffer/append + (format "(Bootstrap) Installing %s...\n" pkg)) + (spacemacs//redisplay)) + (configuration-layer/retrieve-package-archives 'quiet) + (package-install pkg) + (setq pkg-elpa-dir (spacemacs//get-package-directory pkg))) + (require pkg nil 'noerror) + (when file-to-load + (load-file (concat pkg-elpa-dir file-to-load))) + pkg-elpa-dir)))) + +(defun configuration-layer//increment-error-count () + "Increment the error counter." + (if configuration-layer-error-count + (setq configuration-layer-error-count + (1+ configuration-layer-error-count)) + (setq configuration-layer-error-count 1))) + +(provide 'core-configuration-layer) + +;;; core-configuration-layer.el ends here diff --git a/core/core-debug.el b/core/core-debug.el new file mode 100644 index 0000000..b2af85c --- /dev/null +++ b/core/core-debug.el @@ -0,0 +1,143 @@ +;;; core-debug.el --- Spacemacs Core File -*- lexical-binding: t; -*- +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(require 'profiler) + +(defvar spacemacs-debug-timer-threshold 0.15 + "Generate message if file takes longer than this number of +seconds to load") + +(defvar spacemacs-debugp nil) +(defvar spacemacs-debug-with-profile nil) +(defvar spacemacs-debug-with-timed-requires nil) +(defvar spacemacs-debug-with-adv-timers nil) + +(defun spacemacs//load-timer (origfunc &rest args) + "Used to time invocation of `require' or `load'." + (let ((start (current-time)) + (required (car args)) + delta) + (prog1 + (apply origfunc args) + (setq delta (float-time (time-since start))) + (when (> delta spacemacs-debug-timer-threshold) + (with-current-buffer "*load-times*" + (goto-char (point-max)) + (insert (format "[%.3f] (%.3f) Load or require\n Feature: %s\n In file: %s\n\n" + (float-time (time-since emacs-start-time)) + delta required load-file-name))))))) + +(defmacro spacemacs||make-function-timer (func) + "Used to time call to FUNC." + `(lambda (origfunc &rest args) + (let ((start (current-time)) + delta) + (prog1 + (apply origfunc args) + (setq delta (float-time (time-since start))) + (when (> delta spacemacs-debug-timer-threshold) + (with-current-buffer "*load-times*" + (goto-char (point-max)) + (insert (format "[%.3f] (%.3f) Function call\n Function: %s\n Args: %s\n\n" + (float-time (time-since emacs-start-time)) + delta ',func args)))))))) + +(defmacro spacemacs||make-function-profiler (func) + `(lambda (origfunc &rest args) + (if (profiler-running-p) + (profiler-report) + (profiler-start 'cpu)) + (prog1 + (apply origfunc args) + (with-current-buffer "*load-times*" + (goto-char (point-max)) + (insert (format "[%.3f] Done profiling function: %s\n\n" + (float-time (time-since emacs-start-time)) ',func))) + (profiler-report)))) + +(defun spacemacs/init-debug () + "Set the debug hooks." + (when spacemacs-debug-with-profile + (profiler-start 'cpu+mem) + (add-hook 'after-init-hook + (lambda () + (run-with-idle-timer 2 nil (lambda () + (profiler-report) + (profiler-stop)))))) + + (when spacemacs-debug-with-timed-requires + (with-current-buffer (get-buffer-create "*load-times*") + (insert (format "Threshold set at %.3f seconds\n\n" + spacemacs-debug-timer-threshold))) + + (defadvice package-initialize (around spacemacs//timed-initialize activate) + (let ((start (current-time)) res delta) + (setq res ad-do-it + delta (float-time (time-since start))) + (when (> delta spacemacs-debug-timer-threshold) + (with-current-buffer "*load-times*" + (goto-char (point-max)) + (insert (format "package-initialize took %.3f sec\n" delta)))) + res)) + + (defadvice require (around spacemacs//timed-require activate) + (let ((start (current-time)) res delta) + (setq res ad-do-it + delta (float-time (time-since start))) + (when (> delta spacemacs-debug-timer-threshold) + (with-current-buffer "*load-times*" + (goto-char (point-max)) + (insert (format "File %s: Required %s: %.3f sec\n" + load-file-name (ad-get-arg 0) delta)))) + res)) + + (defadvice load (around spacemacs//timed-load activate) + (let ((start (current-time)) res delta) + (setq res ad-do-it + delta (float-time (time-since start))) + (when (> delta spacemacs-debug-timer-threshold) + (with-current-buffer "*load-times*" + (goto-char (point-max)) + (insert (format "File %s: Loaded %s: %.3f sec\n" + load-file-name (ad-get-arg 0) delta)))) + res))) + + (when spacemacs-debug-with-adv-timers + (with-current-buffer (get-buffer-create "*load-times*") + (insert (format "Measured times greater than %.3f sec:\n\n" + spacemacs-debug-timer-threshold))) + + (add-hook 'after-init-hook + (lambda () + (with-current-buffer "*load-times*" + (goto-char (point-max)) + (insert (format "[%.3f] Spacemacs finished initializing\n\n" + (float-time (time-since emacs-start-time)) ))))) + + (advice-add 'load :around #'spacemacs//load-timer) + (advice-add 'require :around #'spacemacs//load-timer) + (advice-add 'package-initialize + :around + (spacemacs||make-function-timer package-intialize)) + (advice-add 'configuration-layer/sync + :around + (spacemacs||make-function-timer configuration-layer/sync)) + ;; (advice-add 'configuration-layer/sync + ;; :around + ;; (spacemacs||make-function-profiler configuration-layer/sync)) + (advice-add 'configuration-layer//configure-package + :around + (spacemacs||make-function-timer configuration-layer//configure-package))) + + ;; Keep debug-on-error on for stuff that is lazily loaded + (add-hook 'after-init-hook (lambda () (setq debug-on-error t)))) + +(provide 'core-debug) diff --git a/core/core-display-init.el b/core/core-display-init.el new file mode 100644 index 0000000..8249b0f --- /dev/null +++ b/core/core-display-init.el @@ -0,0 +1,46 @@ +;;; core-display-init.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar spacemacs--after-display-system-init-list '() + "List of functions to be run after the display system is initialized.") + +(defadvice server-create-window-system-frame + (after spacemacs-init-display activate) + "After Emacs server creates a frame, run functions queued in +`SPACEMACS--AFTER-DISPLAY-SYSTEM-INIT-LIST' to do any setup that needs to have +the display system initialized." + (progn + (dolist (fn (reverse spacemacs--after-display-system-init-list)) + (funcall fn)) + (ad-disable-advice 'server-create-window-system-frame + 'after + 'spacemacs-init-display) + (ad-activate 'server-create-window-system-frame))) + +(defmacro spacemacs|do-after-display-system-init (&rest body) + "If the display-system is initialized, run `BODY', otherwise, +add it to a queue of actions to perform after the first graphical frame is +created." + `(let ((init (cond ((boundp 'ns-initialized) ns-initialized) + ;; w32-initialized gets set too early, so + ;; if we're on Windows, check the list of fonts + ;; instead (this is nil until the graphics system + ;; is initialized) + ((boundp 'w32-initialized) (font-family-list)) + ((boundp 'x-initialized) x-initialized) + ;; fallback to normal loading behavior only if in a GUI + (t (display-graphic-p))))) + (if init + (progn + ,@body) + (push (lambda () ,@body) spacemacs--after-display-system-init-list)))) + +(provide 'core-display-init) diff --git a/core/core-documentation.el b/core/core-documentation.el new file mode 100644 index 0000000..35b00e8 --- /dev/null +++ b/core/core-documentation.el @@ -0,0 +1,250 @@ +;;; core-spacemacs.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(require 'org) +(require 'ox-publish) +(require 's) +(require 'dash) +(require 'f) +(require 'toc-org) +(require 'org-id) + +(defvar spacemacs--category-names + '(("config-files" . "Configuration files") + ("email" . "E-mail") + ("intl" . "International support") + ("lang" . "Programming and markup languages") + ("os" . "Operating systems") + ("spacemacs" . "Spacemacs distribution layers")) + "Special names for categories. Used to generate the layers list.") + +(defun spacemacs//generate-layers-from-path (path level) + "Add all layers found in PATH to the current buffer, at org level LEVEL." + (let* ((all-subs (directory-files path t nil nil)) + (layers (-filter (lambda (p) + (eq 'layer (configuration-layer//directory-type p))) + all-subs)) + (categories (-filter (lambda (p) + (eq 'category (configuration-layer//directory-type p))) + all-subs))) + (message "%S" layers) + (dolist (l layers) + (let ((layer-name (file-name-nondirectory l)) + (target-path (concat (file-relative-name + l (concat spacemacs-start-directory "layers")) + "/README.org"))) + (insert (format "- [[file:%s][%s]]\n" target-path layer-name)))) + (dolist (c categories) + (let* ((category-name (substring (file-name-nondirectory c) 1)) + (pretty-name (or (cdr (assoc category-name spacemacs--category-names)) + (s-capitalize (replace-regexp-in-string + "-" " " category-name))))) + (message "%S" category-name) + (unless (string= "distribution" category-name) + (insert (format "\n%s %s\n" level pretty-name)) + (spacemacs//generate-layers-from-path c (concat level "*")) + ))))) + +(defun spacemacs//generate-layers-file () + "Generate the layers list file." + (interactive) + (with-temp-buffer + (org-mode) + (insert "#+TITLE: Configuration layers\n") + (insert "#+HTML_HEAD_EXTRA: \n\n") + (insert "* Table of Contents\n") + (org-set-tags-to '("TOC_4_org" "noexport")) + ;; there is no layer at the root level for now + ;; uncomment this line if any new layer is added at the root level + ;; (insert "* General layers\n") + (spacemacs//generate-layers-from-path configuration-layer-directory "*") + (write-file (concat spacemacs-start-directory "layers/LAYERS.org")))) + +(defun spacemacs//format-toc (&rest r) + (if (not (null (car r))) + (let* ((toc (car r)) + (heading-pos (s-index-of "ContentsClose%s" beginning-of-heading rest-of-toc)) + toc)) + (car r))) + +(defun spacemacs//format-content (&rest r) + (let* ((content (car r)) + (div-string "
") + (toc-string "") + (has-toc (s-index-of "Table of Contents" content)) + (beginning-of-content-div-pos (+ (length div-string) (s-index-of div-string content))) + (beginning-of-content (substring content 0 beginning-of-content-div-pos)) + (rest-of-content (substring content beginning-of-content-div-pos))) + (if (not (null has-toc)) + (format "%s\n%s%s" beginning-of-content toc-string rest-of-content) + content))) + +(defun spacemacs//toc-org-unhrefify-toc () + "Make TOC classical org-mode TOC." + (let ((toc-org-hrefify-default "org")) + (toc-org-insert-toc))) + +(defun spacemacs//org-heading-annotate-custom-id () + "Annotate headings with the indexes that GitHub uses for linking. +`org-html-publish-to-html' will use them instead of the default #orgheadline{N}. +This way the GitHub links and the http://spacemacs.org/ links will be compatible." + (progn (goto-char (point-min)) + (goto-char (point-min)) + (while (re-search-forward "^[\\*]+\s\\(.*\\).*$" nil t) + (let ((heading (match-string 1))) + (progn (move-end-of-line nil) + (open-line 1) + (next-line 1) + (insert (format (concat " :PROPERTIES:\n" + " :CUSTOM_ID: %s\n" + " :END:\n") + (substring (toc-org-hrefify-gh + (replace-regexp-in-string + toc-org-tags-regexp + "" + heading)) + ;; Remove # prefix added by `toc-org-hrefify-gh'. + 1)))))))) + +(defun spacemacs//reroot-links () + "Find the links that start with https://github.com/syl20bnr/spacemacs/blob/ +and end with .org{#an-optional-heading-link} (i.e the links between the local org files). +Change their root to http://spacemacs.org/ so the links will point at files located on the site. +For the file to file links to work properly the exported org files should be processed with +the `spacemacs//org-heading-annotate-custom-id' function." + (let ((git-url-root-regexp + (concat "\\[\\[[\\s]*\\(https\\:\\/\\/github\\.com\\/syl20bnr" + "\\/spacemacs\\/blob\\/[^/]+\\/\\)[^]]+\\(\\.org\\).*$")) + (site-url "http://spacemacs.org/") + (site-doc-postf ".html")) + (progn (goto-char (point-min)) + (while (re-search-forward git-url-root-regexp nil t) + (progn (replace-match site-url nil t nil 1) + (replace-match site-doc-postf nil t nil 2)))))) + +(defun spacemacs//add-org-meta-readtheorg-css (filename) + (let* ((head-css-extra-readtheorg-head (concat + "#+HTML_HEAD_EXTRA:" + "\n")) + (progn (goto-char (point-min)) + (delete-matching-lines "\\+HTML_HEAD_EXTRA\\:.*\\/css\\/readtheorg\\.css") + (goto-char (point-min)) + (if (search-forward "#+TITLE:" nil t nil) + (beginning-of-line 2) + (error (format "Can't find #+TITLE: in %s" + (buffer-file-name)))) + (insert (concat head-css-extra-readtheorg-head + (f-relative spacemacs-start-directory + (file-name-directory filename)) + head-css-extra-readtheorg-tail))))) + +(defun spacemacs//pub-doc-html-advice (origfunc &rest args) + "Wrapper for `org-html-publish-to-html' use it to insert +preprocessors for the exported .org files." + (save-current-buffer + (save-excursion + (let* ((filename (car (nthcdr 1 args))) + (visitingp (find-buffer-visiting filename))) + ;; Temporary "unvisit" the visited org files. + (when visitingp (with-current-buffer visitingp (setq buffer-file-name nil))) + (with-temp-buffer + (save-match-data + (insert-file-contents filename t) + ;; ===========Add preprocessors here=============== + (spacemacs//add-org-meta-readtheorg-css filename) + (spacemacs//toc-org-unhrefify-toc) + (spacemacs//reroot-links) + (spacemacs//org-heading-annotate-custom-id) + (apply origfunc args) + (not-modified))) + ;; Restore `buffer-file-name' for the buffers that previously visited the org files. + (when visitingp (with-current-buffer visitingp (setq buffer-file-name filename))))))) + +(defun spacemacs/publish-doc () + "Publish the documentation to doc/export/." + (interactive) + (advice-add 'org-html-toc :filter-return #'spacemacs//format-toc) + (advice-add 'org-html-template :filter-return #'spacemacs//format-content) + (advice-add 'org-html-publish-to-html :around #'spacemacs//pub-doc-html-advice) + (let* ((header + " + + + + ") + (publish-target (concat spacemacs-start-directory "export/")) + (org-html-htmlize-output-type 'css) + (org-publish-project-alist + `(("spacemacs" + :components ("spacemacs-news" + "spacemacs-doc" + "spacemacs-doc-static" + "layers-doc" + "layers-doc-static")) + ("spacemacs-news" + :base-directory ,spacemacs-news-directory + :base-extension "org" + :publishing-directory ,(concat publish-target "news/") + :publishing-function org-html-publish-to-html + :headline-levels 4 + :html-head ,header) + ("spacemacs-doc" + :base-directory ,spacemacs-docs-directory + :base-extension "org" + :publishing-directory ,(concat publish-target "doc/") + :publishing-function org-html-publish-to-html + :headline-levels 4 + :html-head ,header) + ("layers-doc" + :base-directory ,(concat spacemacs-start-directory "layers/") + :base-extension "org" + :recursive t + :publishing-directory ,(concat publish-target "layers/") + :publishing-function org-html-publish-to-html + :preparation-function spacemacs//generate-layers-file + :exclude "local" + :html-head ,header) + ("spacemacs-doc-static" + :base-directory ,spacemacs-docs-directory + :base-extension "png" + :recursive t + :publishing-directory ,(concat publish-target "doc/") + :publishing-function org-publish-attachment) + ("layers-doc-static" + :base-directory ,(concat spacemacs-start-directory "layers/") + :base-extension "jpg\\|png\\|gif" + :recursive t + :publishing-directory ,(concat publish-target "layers/") + :publishing-function org-publish-attachment)))) + (org-publish-project "spacemacs")) + (advice-remove 'org-html-toc #'spacemacs//format-toc) + (advice-remove 'org-html-template #'spacemacs//format-content) + (advice-remove 'org-html-publish-to-html #'spacemacs//pub-doc-html-advice)) + +(provide 'core-documentation) diff --git a/core/core-dotspacemacs.el b/core/core-dotspacemacs.el new file mode 100644 index 0000000..cf454cb --- /dev/null +++ b/core/core-dotspacemacs.el @@ -0,0 +1,728 @@ +;;; core-dotspacemacs.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(defconst dotspacemacs-template-directory + (expand-file-name (concat spacemacs-core-directory "templates/")) + "Templates directory.") + +(defconst dotspacemacs-test-results-buffer "*dotfile-test-results*" + "Name of the buffer to display dotfile test results.") + +(let* ((env (getenv "SPACEMACSDIR")) + (env-dir (when env (expand-file-name (concat env "/")))) + (env-init (and env-dir (expand-file-name "init.el" env-dir))) + (no-env-dir-default (expand-file-name + (concat user-home-directory + ".spacemacs.d/"))) + (default-init (expand-file-name ".spacemacs" user-home-directory))) + (defconst dotspacemacs-directory + (cond + ((and env (file-exists-p env-dir)) + env-dir) + ((file-exists-p no-env-dir-default) + no-env-dir-default) + (t + nil)) + "Optional spacemacs directory, which defaults to +~/.spacemacs.d. This setting can be overridden using the +SPACEMACSDIR environment variable. If neither of these +directories exist, this variable will be nil.") + + (defvar dotspacemacs-filepath + (let ((spacemacs-dir-init (when dotspacemacs-directory + (concat dotspacemacs-directory + "init.el")))) + (cond + (env-init) + ((file-exists-p default-init) default-init) + ((and dotspacemacs-directory (file-exists-p spacemacs-dir-init)) spacemacs-dir-init) + (t default-init))) + "Filepath to the installed dotfile. If SPACEMACSDIR is given +then SPACEMACSDIR/init.el is used. Otherwise, if ~/.spacemacs +exists, then this is used. If ~/.spacemacs does not exist, then +check for init.el in dotspacemacs-directory and use this if it +exists. Otherwise, fallback to ~/.spacemacs")) + +(defvar dotspacemacs-distribution 'spacemacs + "Base distribution to use. This is a layer contained in the directory +`+distributions'. For now available distributions are `spacemacs-base' +or `spacemacs'.") + +(defvar dotspacemacs-elpa-https t + "If non nil ELPA repositories are contacted via HTTPS whenever it's +possible. Set it to nil if you have no way to use HTTPS in your +environment, otherwise it is strongly recommended to let it set to t.") + +(defvar dotspacemacs-elpa-timeout 5 + "Maximum allowed time in seconds to contact an ELPA repository.") + +(defvar dotspacemacs-elpa-subdirectory nil + "If non-nil, a form that evaluates to a package directory. For +example, to use different package directories for different Emacs +versions, set this to `emacs-version'.") + +(defvar dotspacemacs-configuration-layer-path '() + "List of additional paths where to look for configuration layers. +Paths must have a trailing slash (ie. `~/.mycontribs/')") + +(defvar dotspacemacs-install-packages 'used-only + "Defines the behaviour of Spacemacs when installing packages. +Possible values are `used-only', `used-but-keep-unused' and `all'. `used-only' +installs only explicitly used packages and uninstall any unused packages as well +as their unused dependencies. `used-but-keep-unused' installs only the used +packages but won't uninstall them if they become unused. `all' installs *all* +packages supported by Spacemacs and never uninstall them.") + +(defvar dotspacemacs-enable-lazy-installation 'unused + "Lazy installation of layers (i.e. layers are installed only when a file +with a supported type is opened). Possible values are `all', `unused' and `nil'. +`unused' will lazy install only unused layers (i.e. layers not listed in +variable `dotspacemacs-configuration-layers'), `all' will lazy install any layer +that support lazy installation even the layers listed in +`dotspacemacs-configuration-layers'. `nil' disable the lazy installation feature +and you have to explicitly list a layer in the variable +`dotspacemacs-configuration-layers' to install it.") + +(defvar dotspacemacs-ask-for-lazy-installation t + "If non-nil then Spacemacs will ask for confirmation before installing +a layer lazily.") + +(defvar dotspacemacs-additional-packages '() + "List of additional packages that will be installed wihout being +wrapped in a layer. If you need some configuration for these +packages then consider to create a layer, you can also put the +configuration in `dotspacemacs/user-config'.") + +(defvar dotspacemacs-editing-style 'vim + "One of `vim', `emacs' or `hybrid'. +`hybrid' is like `vim' except that `insert state' is replaced by the +`hybrid state' with `emacs' key bindings. The value can also be a list + with `:variables' keyword (similar to layers). Check the editing styles + section of the documentation for details on available variables.") + +(defvar dotspacemacs-startup-banner 'official + "Specify the startup banner. Default value is `official', it displays +the official spacemacs logo. An integer value is the index of text +banner, `random' chooses a random text banner in `core/banners' +directory. A string value must be a path to a .PNG file. +If the value is nil then no banner is displayed.") + +(defvar dotspacemacs-scratch-mode 'text-mode + "Default major mode of the scratch buffer.") + +(defvar dotspacemacs-check-for-update nil + "If non nil then spacemacs will check for updates at startup +when the current branch is not `develop'. Note that checking for +new versions works via git commands, thus it calls GitHub services +whenever you start Emacs.") + +(defvar dotspacemacs-configuration-layers '(emacs-lisp) + "List of configuration layers to load.") + +(defvar dotspacemacs--configuration-layers-saved nil + "Saved value of `dotspacemacs-configuration-layers' after sync.") + +(defvar dotspacemacs-themes '(spacemacs-dark + spacemacs-light) + "List of themes, the first of the list is loaded when spacemacs starts. +Press `SPC T n' to cycle to the next theme in the list (works great +with 2 themes variants, one dark and one light") + +(defvar dotspacemacs-colorize-cursor-according-to-state t + "If non nil the cursor color matches the state color in GUI Emacs.") + +(defvar dotspacemacs-leader-key "SPC" + "The leader key.") + +(defvar dotspacemacs-emacs-leader-key "M-m" + "The leader key accessible in `emacs state' and `insert state'") + +(defvar dotspacemacs-major-mode-leader-key "," + "Major mode leader key is a shortcut key which is the equivalent of +pressing ` m`. Set it to `nil` to disable it.") + +(defvar dotspacemacs-major-mode-emacs-leader-key "C-M-m" + "Major mode leader key accessible in `emacs state' and `insert state'") + +(defvar dotspacemacs-ex-command-key ":" + "The key used for Vim Ex commands.") + +(defvar dotspacemacs-command-key "SPC" + "The key used for Emacs commands (M-x) (after pressing on the leader key).") +(defvaralias 'dotspacemacs-emacs-command-key 'dotspacemacs-command-key + "New official name for `dotspacemacs-command-key'") + +(defvar dotspacemacs-distinguish-gui-tab nil + "If non nil, distinguish C-i and tab in the GUI version of +emacs.") + +;; (defvar dotspacemacs-distinguish-gui-ret nil +;; "If non nil, distinguish C-m and return in the GUI version of +;; emacs.") + +(defvar dotspacemacs-default-font '("Source Code Pro" + :size 13 + :weight normal + :width normal + :powerline-scale 1.1) + "Default font, or prioritized list of fonts. `powerline-scale' +allows to quickly tweak the mode-line size to make separators +look not too crappy. + +Has no effect when running Emacs in terminal.") + +(defvar dotspacemacs-remap-Y-to-y$ nil + "If non nil `Y' is remapped to `y$' in Evil states.") + +(defvar dotspacemacs-retain-visual-state-on-shift t + "If non-nil, the shift mappings `<' and `>' retain visual state +if used there.") + +(defvar dotspacemacs-visual-line-move-text nil + "If non-nil, J and K move lines up and down when in visual mode.") + +(defvar dotspacemacs-ex-substitute-global nil + "If non nil, inverse the meaning of `g' in `:substitute' Evil ex-command.") + +(defvar dotspacemacs-folding-method 'evil + "Code folding method. Possible values are `evil' and `origami'.") + +(defvar dotspacemacs-default-layout-name "Default" + " Name of the default layout.") + +(defvar dotspacemacs-display-default-layout nil + "If non nil the default layout name is displayed in the mode-line.") + +(defvar dotspacemacs-auto-resume-layouts nil + "If non nil then the last auto saved layouts are resume automatically upon +start.") + +(defvar dotspacemacs-max-rollback-slots 5 + "Maximum number of rollback slots to keep in the cache.") + +(defvar dotspacemacs-helm-resize nil + "If non nil, `helm' will try to minimize the space it uses.") + +(defvar dotspacemacs-helm-no-header nil + "if non nil, the helm header is hidden when there is only one source.") + +(defvar dotspacemacs-helm-position 'bottom + "Position in which to show the `helm' mini-buffer.") + +(defvar dotspacemacs-helm-use-fuzzy 'always + "Controls fuzzy matching in helm. If set to `always', force fuzzy matching + in all non-asynchronous sources. If set to `source', preserve individual + source settings. Else, disable fuzzy matching in all sources.") + +(defvar dotspacemacs-large-file-size 1 + "Size (in MB) above which spacemacs will prompt to open the large file +literally to avoid performance issues. Opening a file literally means that +no major mode or minor modes are active.") + +(defvar dotspacemacs-auto-save-file-location 'cache + "Location where to auto-save files. Possible values are `original' to +auto-save the file in-place, `cache' to auto-save the file to another +file stored in the cache directory and `nil' to disable auto-saving. +Default value is `cache'.") + +(defvar dotspacemacs-enable-paste-transient-state t + "If non nil the paste transient-state is enabled. While enabled pressing `p` +several times cycle between the kill ring content.'") +(defvaralias + 'dotspacemacs-enable-paste-micro-state + 'dotspacemacs-enable-paste-transient-state + "Old name of `dotspacemacs-enable-paste-transient-state'.") + +(defvar dotspacemacs-which-key-delay 0.4 + "Delay in seconds starting from the last keystroke after which +the which-key buffer will be shown if you have not completed a +key sequence. Setting this variable is equivalent to setting +`which-key-idle-delay'.") + +(defvar dotspacemacs-which-key-position 'bottom + "Location of the which-key popup buffer. Possible choices are bottom, +right, and right-then-bottom. The last one will display on the +right if possible and fallback to bottom if not.") + +(defvar dotspacemacs-loading-progress-bar t + "If non nil a progress bar is displayed when spacemacs is loading. This +may increase the boot time on some systems and emacs builds, set it to nil +to boost the loading time.") + +(defvar dotspacemacs-fullscreen-at-startup nil + "If non nil the frame is fullscreen when Emacs starts up (Emacs 24.4+ only).") + +(defvar dotspacemacs-fullscreen-use-non-native nil + "If non nil `spacemacs/toggle-fullscreen' will not use native fullscreen. Use +to disable fullscreen animations in OSX.") + +(defvar dotspacemacs-maximized-at-startup nil + "If non nil the frame is maximized when Emacs starts up (Emacs 24.4+ only). +Takes effect only if `dotspacemacs-fullscreen-at-startup' is nil.") + +(defvar dotspacemacs-active-transparency 90 + "A value from the range (0..100), in increasing opacity, which describes the +transparency level of a frame when it's active or selected. Transparency +can be toggled through `toggle-transparency'.") + +(defvar dotspacemacs-inactive-transparency 90 + "A value from the range (0..100), in increasing opacity, which describes the +transparency level of a frame when it's inactive or deselected. Transparency +can be toggled through `toggle-transparency'.") + +(defvar dotspacemacs-show-transient-state-title t + "If non nil show the titles of transient states.") + +(defvar dotspacemacs-show-transient-state-color-guide t + "If non nil show the color guide hint for transient state keys.") + +(defvar dotspacemacs-mode-line-unicode-symbols t + "If non nil unicode symbols are displayed in the mode-line (eg. for lighters)") + +(defvar dotspacemacs-smooth-scrolling t + "If non nil smooth scrolling (native-scrolling) is enabled. +Smooth scrolling overrides the default behavior of Emacs which +recenters point when it reaches the top or bottom of the +screen.") + +(defvar dotspacemacs-line-numbers nil + "If non nil line numbers are turned on in all `prog-mode' and `text-mode' +derivatives. If set to `relative', also turns on relative line numbers.") + +(defvar dotspacemacs-persistent-server nil + "If non nil advises quit functions to keep server open when quitting.") + +(defvar dotspacemacs-smartparens-strict-mode nil + "If non-nil smartparens-strict-mode will be enabled in programming modes.") + +(defvar dotspacemacs-smart-closing-parenthesis nil + "If non-nil pressing the closing parenthesis `)' key in insert mode passes + over any automatically added closing parenthesis, bracket, quote, etc… + This can be temporary disabled by pressing `C-q' before `)'. (default nil)") + +(defvar dotspacemacs-highlight-delimiters 'all + "Select a scope to highlight delimiters. Possible values are `any', +`current', `all' or `nil'. Default is `all' (highlight any scope and + emphasis the current one.") + +(defvar dotspacemacs-whitespace-cleanup nil + "delete whitespace while saving buffer. possible values are `all' +to aggressively delete empty lines and long sequences of whitespace, `trailing' +to delete only the whitespace at end of lines, `changed' to delete only +whitespace for changed lines or `nil' to disable cleanup.") + +(defvar dotspacemacs-search-tools '("ag" "pt" "ack" "grep") + "List of search tool executable names. Spacemacs uses the first installed +tool of the list. Supported tools are `ag', `pt', `ack' and `grep'.") + +(defvar dotspacemacs-default-package-repository 'melpa-stable + "The default package repository used if no explicit repository has been +specified with an installed package. +NOT USED FOR NOW :-)") + +(defvar dotspacemacs-startup-lists '((recents . 5) + (projects . 7)) + "Association list of items to show in the startup buffer of the form +`(list-type . list-size)`. If nil it is disabled. +Possible values for list-type are: +`recents' `bookmarks' `projects' `agenda' `todos'. +List sizes may be nil, in which case +`spacemacs--buffer-startup-lists-length' takes effect. +") + +(defvar dotspacemacs-startup-buffer-responsive t + "True if the home buffer should respond to resize events.") + +(defvar dotspacemacs-excluded-packages '() + "A list of packages that will not be install and loaded.") + +(defvar dotspacemacs-frozen-packages '() + "A list of packages that cannot be updated.") + +;; only for backward compatibility +(defalias 'dotspacemacs-mode 'emacs-lisp-mode) + +(defmacro dotspacemacs|call-func (func &optional msg) + "Call the function from the dotfile only if it is bound. +If MSG is not nil then display a message in `*Messages'. Errors +are caught and signalled to user in spacemacs buffer." + `(progn + (when ,msg (spacemacs-buffer/message ,msg)) + (when (fboundp ',func) + (condition-case-unless-debug err + (,func) + (error + (configuration-layer//increment-error-count) + (spacemacs-buffer/append (format "Error in %s: %s\n" + ',(symbol-name func) + (error-message-string err)) + t)))))) + +(defun dotspacemacs//check-layers-changed () + "Check if the value of `dotspacemacs-configuration-layers' +changed, and issue a warning if it did." + (unless (eq dotspacemacs-configuration-layers + dotspacemacs--configuration-layers-saved) + (spacemacs-buffer/warning + "`dotspacemacs-configuration-layers' was changed outside of `dotspacemacs/layers'."))) +(add-hook 'spacemacs-post-user-config-hook + 'dotspacemacs//check-layers-changed) + +(defun dotspacemacs//read-editing-style-config (config) + "Read editing style CONFIG: apply variables and return the editing style. +CONFIG can be the symbol of an editing style or a list where the car is +the symbol of an editing style and the cdr is a list of keyword arguments like +`:variables'." + (cond + ((symbolp config) config) + ((listp config) + (let ((variables (spacemacs/mplist-get config :variables))) + (while variables + (let ((var (pop variables))) + (if (consp variables) + (condition-case-unless-debug err + (set-default var (eval (pop variables))) + ('error + (spacemacs-buffer/append + (format (concat "\nAn error occurred while reading the " + "editing style variable %s " + "(error: %s). Be sure to quote the value " + "if needed.\n") var err)))) + (spacemacs-buffer/warning "Missing value for variable %s !" + var))))) + (car config)))) + +(defun dotspacemacs/add-layer (layer-name) + "Add LAYER_NAME to dotfile and reload the it. +Returns non nil if the layer has been effectively inserted." + (unless (configuration-layer/layer-usedp layer-name) + (with-current-buffer (find-file-noselect (dotspacemacs/location)) + (beginning-of-buffer) + (let ((insert-point (re-search-forward + "dotspacemacs-configuration-layers *\n?.*\\((\\)"))) + (insert (format "\n%S" layer-name)) + (indent-region insert-point (+ insert-point + (length (symbol-name layer-name)))) + (save-buffer))) + (load-file (dotspacemacs/location)) + t)) + +(defun dotspacemacs/sync-configuration-layers (&optional arg) + "Synchronize declared layers in dotfile with spacemacs. + +Called with `C-u' skips `dotspacemacs/user-config'. +Called with `C-u C-u' skips `dotspacemacs/user-config' _and_ preleminary tests." + (interactive "P") + (when (file-exists-p dotspacemacs-filepath) + (with-current-buffer (find-file-noselect dotspacemacs-filepath) + (let ((dotspacemacs-loading-progress-bar nil)) + (setq spacemacs-loading-string "") + (save-buffer) + (let ((tests-ok (or (equal arg '(16)) (dotspacemacs/test-dotfile t)))) + (if tests-ok + (progn + (load-file buffer-file-name) + (dotspacemacs|call-func dotspacemacs/init + "Calling dotfile init...") + (dotspacemacs|call-func dotspacemacs/user-init + "Calling dotfile user init...") + (setq dotspacemacs-editing-style + (dotspacemacs//read-editing-style-config + dotspacemacs-editing-style)) + (configuration-layer/sync) + (if (member arg '((4) (16))) + (message (concat "Done (`dotspacemacs/user-config' " + "function has been skipped).")) + (dotspacemacs|call-func dotspacemacs/user-config + "Calling dotfile user config...") + (run-hooks 'spacemacs-post-user-config-hook) + (message "Done."))) + (switch-to-buffer-other-window dotspacemacs-test-results-buffer) + (spacemacs-buffer/warning "Some tests failed, check `%s' buffer" + dotspacemacs-test-results-buffer)))))) + (when (configuration-layer/package-usedp 'spaceline) + (spacemacs//set-powerline-for-startup-buffers))) + +(defun dotspacemacs/get-variable-string-list () + "Return a list of all the dotspacemacs variables as strings." + (all-completions "" obarray + (lambda (x) + (and (boundp x) + (not (keywordp x)) + (string-prefix-p "dotspacemacs" + (symbol-name x)))))) + +(defun dotspacemacs/get-variable-list () + "Return a list of all dotspacemacs variable symbols." + (mapcar 'intern (dotspacemacs/get-variable-string-list))) + +(defmacro dotspacemacs|symbol-value (symbol) + "Return the value of SYMBOL corresponding to a dotspacemacs variable. +If SYMBOL value is `display-graphic-p' then return the result of + `(display-graphic-p)', otherwise return the value of the symbol." + `(if (eq 'display-graphic-p ,symbol) (display-graphic-p) ,symbol)) + +(defun dotspacemacs/location () + "Return the absolute path to the spacemacs dotfile." + dotspacemacs-filepath) + +(defun dotspacemacs/copy-template () + "Copy `.spacemacs.template' in home directory. Ask for confirmation +before copying the file if the destination already exists." + (interactive) + (let* ((copy? (if (file-exists-p dotspacemacs-filepath) + (y-or-n-p + (format "%s already exists. Do you want to overwrite it ? " + dotspacemacs-filepath)) t))) + (when copy? + (copy-file (concat dotspacemacs-template-directory + ".spacemacs.template") dotspacemacs-filepath t) + (message "%s has been installed." dotspacemacs-filepath)))) + +(defun dotspacemacs//ido-completing-read (prompt candidates) + "Call `ido-completing-read' with a CANDIDATES alist where the key is +a display strng and the value is the actual value to return." + (let ((ido-max-window-height (1+ (length candidates)))) + (cadr (assoc (ido-completing-read prompt (mapcar 'car candidates)) + candidates)))) + +(defun dotspacemacs/install (arg) + "Install the dotfile, return non nil if the doftile has been installed. + +If ARG is non nil then Ask questions to the user before installing the dotfile." + (interactive "P") + ;; preferences is an alist where the key is the text to replace by + ;; the value in the dotfile + (let ((preferences + (when arg + ;; editing style + `(("dotspacemacs-editing-style 'vim" + ,(format + "dotspacemacs-editing-style '%S" + (dotspacemacs//ido-completing-read + "What is your preferred editing style? " + '(("Among the stars aboard the Evil flagship (vim)" + vim) + ("On the planet Emacs in the Holy control tower (emacs)" + emacs))))) + ("dotspacemacs-distribution 'spacemacs" + ,(format + "dotspacemacs-distribution '%S" + (dotspacemacs//ido-completing-read + "What distribution of spacemacs would you like to start with? " + `(("The standard distribution, recommended (spacemacs)" + spacemacs) + (,(concat "A minimalist distribution that you can build on " + "(spacemacs-base)") + spacemacs-base))))) + ("helm" + ,(dotspacemacs//ido-completing-read + "What type of completion framework do you want? " + '(("A heavy one but full-featured (helm)" + "helm") + ("A lighter one but still very powerful (ivy)" + "ivy") + ;; For now, None works only if the user selected + ;; the spacemacs-base distribution + ("None (not recommended)" "")))))))) + (with-current-buffer (find-file-noselect + (concat dotspacemacs-template-directory + ".spacemacs.template")) + (dolist (p preferences) + (goto-char (point-min)) + (re-search-forward (car p)) + (replace-match (cadr p))) + (let ((install + (if (file-exists-p dotspacemacs-filepath) + (y-or-n-p + (format "%s already exists. Do you want to overwrite it ? " + dotspacemacs-filepath)) t))) + (when install + (write-file dotspacemacs-filepath) + (message "%s has been installed." dotspacemacs-filepath) + t)))) + (load-file dotspacemacs-filepath)) + +(defun dotspacemacs//install-and-replace (&optional values) + "Install the dotfile and replace its content according to VALUES. + +VALUES is an alist where the key is the text to replace and value is the new +value." + ) + +(defun dotspacemacs/load-file () + "Load ~/.spacemacs if it exists." + (let ((dotspacemacs (dotspacemacs/location))) + (if (file-exists-p dotspacemacs) + (unless (with-demoted-errors "Error loading .spacemacs: %S" (load dotspacemacs)) + (dotspacemacs/safe-load))))) + +(defun dotspacemacs/safe-load () + "Error recovery from malformed .spacemacs. +Loads default .spacemacs template and suspends pruning of orphan packages. +Informs users of error and prompts for default editing style for use during +error recovery." + (load (concat dotspacemacs-template-directory + ".spacemacs.template")) + (defadvice dotspacemacs/layers + (after error-recover-preserve-packages activate) + (progn + (setq-default dotspacemacs-install-packages 'used-but-keep-unused) + (ad-disable-advice 'dotspacemacs/layers 'after + 'error-recover-preserve-packages) + (ad-activate 'dotspacemacs/layers))) + (defadvice dotspacemacs/init + (after error-recover-prompt-for-style activate) + (progn + (setq-default dotspacemacs-editing-style + (intern + (ido-completing-read + (format + (concat + "Spacemacs encountered an error while " + "loading your `%s' file.\n" + "Pick your editing style for recovery " + "(use left and right arrows): ") + dotspacemacs-filepath) + '(("vim" vim) + ("emacs" emacs) + ("hybrid" hybrid)) + nil t nil nil 'vim))) + (ad-disable-advice 'dotspacemacs/init 'after + 'error-recover-prompt-for-style) + (ad-activate 'dotspacemacs/init)))) + +(defun dotspacemacs//test-dotspacemacs/layers () + "Tests for `dotspacemacs/layers'" + (insert + (format (concat "\n* Testing settings in dotspacemacs/layers " + "[[file:%s::dotspacemacs/layers][Show in File]]\n") + dotspacemacs-filepath)) + ;; protect global values of these variables + (let (dotspacemacs-configuration-layer-path dotspacemacs-configuration-layers + dotspacemacs-additional-packages dotspacemacs-excluded-packages + dotspacemacs-install-packages + (passed-tests 0) (total-tests 0)) + (load dotspacemacs-filepath) + (dotspacemacs/layers) + (spacemacs//test-list + 'stringp 'dotspacemacs-configuration-layer-path + "is a string" "path") + (spacemacs//test-list + 'file-directory-p 'dotspacemacs-configuration-layer-path + "exists in filesystem" "path") + (setq dotspacemacs-configuration-layers + (mapcar (lambda (l) (if (listp l) (car l) l)) + dotspacemacs-configuration-layers)) + (spacemacs//test-list + 'configuration-layer/get-layer-path + 'dotspacemacs-configuration-layers "can be found" "layer") + (insert (format + (concat "** RESULTS: " + "[[file:%s::dotspacemacs/layers][dotspacemacs/layers]] " + "passed %s out of %s tests\n") + dotspacemacs-filepath passed-tests total-tests)) + (equal passed-tests total-tests))) + +(defmacro dotspacemacs||let-init-test (&rest body) + "Macro to protect dotspacemacs variables" + `(let ((fpath dotspacemacs-filepath) + ,@(dotspacemacs/get-variable-list) + (passed-tests 0) (total-tests 0)) + (setq dotspacemacs-filepath fpath) + (load dotspacemacs-filepath) + ,@body)) + +(defun dotspacemacs//test-dotspacemacs/init () + "Tests for `dotspacemacs/init'" + (insert + (format (concat "\n* Testing settings in dotspacemacs/init " + "[[file:%s::dotspacemacs/init][Show in File]]\n") + dotspacemacs-filepath)) + (dotspacemacs||let-init-test + (dotspacemacs/init) + (spacemacs//test-var + (lambda (x) (or (member x '(vim emacs hybrid)) + (and (listp x) + (spacemacs/mplist-get x :variables)))) + 'dotspacemacs-editing-style + "is \'vim, \'emacs or \'hybrid or and list with `:variable' keyword") + (spacemacs//test-var + (lambda (x) (member x '(original cache nil))) + 'dotspacemacs-auto-save-file-location (concat "is one of \'original, " + "\'cache or nil")) + (spacemacs//test-var + (lambda (x) (member x '(all any current nil))) + 'dotspacemacs-highlight-delimiters "is one of \'all, \'any, \'current or nil") + (spacemacs//test-list + (lambda (x) + (let ((el (or (car-safe x) x)) + (list-size (cdr-safe x))) + (member el '(recents bookmarks projects todos agenda)))) + 'dotspacemacs-startup-lists (concat "includes \'recents, " + "\'bookmarks, \'todos, " + "\'agenda or \'projects")) + (spacemacs//test-list + (lambda (x) + (let ((el (or (car-safe x) x)) + (list-size (cdr-safe x))) + (or (null list-size)(numberp list-size)))) + 'dotspacemacs-startup-lists (concat "list size is a number")) + (spacemacs//test-var 'stringp 'dotspacemacs-leader-key "is a string") + (spacemacs//test-var 'stringp 'dotspacemacs-emacs-leader-key "is a string") + (spacemacs//test-var + (lambda (x) (or (null x) (stringp x))) + 'dotspacemacs-major-mode-leader-key "is a string or nil") + (spacemacs//test-var + (lambda (x) (or (null x) (stringp x))) + 'dotspacemacs-major-mode-emacs-leader-key "is a string or nil") + (spacemacs//test-var 'stringp 'dotspacemacs-emacs-command-key "is a string") + (insert (format + (concat "** RESULTS: " + "[[file:%s::dotspacemacs/init][dotspacemacs/init]] " + "passed %s out of %s tests\n") + dotspacemacs-filepath passed-tests total-tests)) + (equal passed-tests total-tests))) + +(defun dotspacemacs/test-dotfile (&optional hide-buffer) + "Test settings in dotfile for correctness. + Return non-nil if all the tests passed." + (interactive) + (configuration-layer/discover-layers) + (let ((min-version "0.0")) + ;; dotspacemacs-version not implemented yet + ;; (if (version< dotspacemacs-version min-version) + (if nil + (error (format (concat "error: dotspacemacs/test-dotfile requires " + "dotspacemacs-version %s") min-version)) + (with-current-buffer (get-buffer-create dotspacemacs-test-results-buffer) + (unless hide-buffer + (switch-to-buffer-other-window dotspacemacs-test-results-buffer)) + (org-mode) + (org-indent-mode) + (view-mode) + (when (bound-and-true-p flyspell-mode) + (flyspell-mode -1)) + (let (buffer-read-only) + (erase-buffer) + (insert (format "* Running tests on [[file:%s][%s]] (v%s)\n" + dotspacemacs-filepath dotspacemacs-filepath "0.0")) + ;; dotspacemacs-version not implemented yet + ;; (insert (format "* Running tests on %s (v%s)\n" dotspacemacs-filepath dotspacemacs-version)) + (prog1 + ;; execute all tests no matter what + (cl-reduce (lambda (x y) + (and (funcall y) x)) + '(dotspacemacs//test-dotspacemacs/layers + dotspacemacs//test-dotspacemacs/init) + :initial-value t) + (goto-char (point-min)))))))) + +(provide 'core-dotspacemacs) diff --git a/core/core-emacs-backports.el b/core/core-emacs-backports.el new file mode 100644 index 0000000..5c177ee --- /dev/null +++ b/core/core-emacs-backports.el @@ -0,0 +1,14 @@ +;;; core-emacs-backports.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; nothing for now + +(provide 'core-emacs-backports) diff --git a/core/core-fonts-support.el b/core/core-fonts-support.el new file mode 100644 index 0000000..ffeedb4 --- /dev/null +++ b/core/core-fonts-support.el @@ -0,0 +1,114 @@ +;;; core-fonts-support.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(require 'core-funcs) +(require 'core-spacemacs-buffer) + +(defvar spacemacs--diminished-minor-modes nil + "List of diminished modes to unicode or ascii values.") + +(defun spacemacs/set-default-font (plists) + "Set the font given the passed PLISTS. + +PLISTS has either the form (\"fontname\" :prop1 val1 :prop2 val2 ...) +or is a list of such. The first font that can be found will be used. + +The return value is nil if no font was found, truthy otherwise." + (unless (listp (car plists)) + (setq plists (list plists))) + (catch 'break + (dolist (plist plists) + (when (find-font (font-spec :name (car plist))) + (let* ((font (car plist)) + (props (cdr plist)) + (scale (plist-get props :powerline-scale)) + (font-props (spacemacs/mplist-remove + (spacemacs/mplist-remove props :powerline-scale) + :powerline-offset)) + (fontspec (apply 'font-spec :name font font-props))) + (spacemacs-buffer/message "Setting font \"%s\"..." font) + (set-frame-font fontspec nil t) + (push `(font . ,(frame-parameter nil 'font)) default-frame-alist) + (setq-default powerline-scale scale) + (setq-default powerline-height (spacemacs/compute-powerline-height)) + ;; fallback font for unicode characters used in spacemacs + (pcase system-type + (`gnu/linux + (setq fallback-font-name "NanumGothic") + (setq fallback-font-name2 "NanumGothic")) + (`darwin + (setq fallback-font-name "Arial Unicode MS") + (setq fallback-font-name2 "Arial Unicode MS")) + (`windows-nt + (setq fallback-font-name "MS Gothic") + (setq fallback-font-name2 "Lucida Sans Unicode")) + (`cygwin + (setq fallback-font-name "MS Gothic") + (setq fallback-font-name2 "Lucida Sans Unicode")) + (other + (setq fallback-font-name nil) + (setq fallback-font-name2 nil))) + (when (and fallback-font-name fallback-font-name2) + ;; remove any size or height properties in order to be able to + ;; scale the fallback fonts with the default one (for zoom-in/out + ;; for instance) + (let* ((fallback-props (spacemacs/mplist-remove + (spacemacs/mplist-remove font-props :size) + :height)) + (fallback-spec (apply 'font-spec + :name fallback-font-name + fallback-props)) + (fallback-spec2 (apply 'font-spec + :name fallback-font-name2 + fallback-props))) + ;; window numbers + (set-fontset-font "fontset-default" + '(#x2776 . #x2793) fallback-spec nil 'prepend) + ;; mode-line circled letters + (set-fontset-font "fontset-default" + '(#x24b6 . #x24fe) fallback-spec nil 'prepend) + ;; mode-line additional characters + (set-fontset-font "fontset-default" + '(#x2295 . #x22a1) fallback-spec nil 'prepend) + ;; new version lighter + (set-fontset-font "fontset-default" + '(#x2190 . #x2200) fallback-spec2 nil 'prepend)))) + (throw 'break t))) + nil)) + +(defun spacemacs/compute-powerline-height () + "Return an adjusted powerline height." + (let ((scale (if (and (boundp 'powerline-scale) powerline-scale) + powerline-scale 1))) + (truncate (* scale (frame-char-height))))) + +(defun spacemacs/set-font (&rest args) + "Deprecated function, display a warning message." + (spacemacs-buffer/warning (concat "spacemacs/set-font is deprecated. " + "Use the variable `dotspacemacs-default-font' " + "instead (see Font section in " + "~/.emacs.d/doc/DOCUMENTATION.org for more " + "info)."))) + +(defmacro spacemacs|diminish (mode &optional unicode ascii) + "Diminish MODE name in mode line to UNICODE or ASCII depending on the value +`dotspacemacs-mode-line-unicode-symbols'. +If ASCII is not provided then UNICODE is used instead. If neither are provided, +the mode will not show in the mode line." + `(let ((cell (assq ',mode spacemacs--diminished-minor-modes))) + (if cell + (setcdr cell '(,unicode ,ascii)) + (push '(,mode ,unicode ,ascii) spacemacs--diminished-minor-modes)))) + +(defmacro spacemacs|hide-lighter (mode) + "Diminish MODE name in mode line to LIGHTER." + `(eval-after-load 'diminish '(diminish ',mode))) + +(provide 'core-fonts-support) diff --git a/core/core-funcs.el b/core/core-funcs.el new file mode 100644 index 0000000..9f7334f --- /dev/null +++ b/core/core-funcs.el @@ -0,0 +1,385 @@ +;;; core-funcs.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar configuration-layer--protected-packages) +(defvar dotspacemacs-filepath) +(defvar spacemacs-repl-list '() + "List of all registered REPLs.") + +(defun spacemacs/system-is-mac () + (eq system-type 'darwin)) +(defun spacemacs/system-is-linux () + (eq system-type 'gnu/linux)) +(defun spacemacs/system-is-mswindows () + (eq system-type 'windows-nt)) + +(defun spacemacs/window-system-is-mac () + ;; ns is returned instead of mac on Emacs 25+ + (memq (window-system) '(mac ns))) + +(defun spacemacs/run-prog-mode-hooks () + "Runs `prog-mode-hook'. Useful for modes that don't derive from +`prog-mode' but should." + (run-hooks 'prog-mode-hook)) + +(defun spacemacs/run-text-mode-hooks () + "Runs `text-mode-hook'. Useful for modes that don't derive from +`text-mode' but should." + (run-hooks 'text-mode-hook)) + +(defun spacemacs//get-package-directory (pkg) + "Return the directory of PKG. Return nil if not found." + (let ((elpa-dir (file-name-as-directory package-user-dir))) + (when (file-exists-p elpa-dir) + (let* ((pkg-match (concat "\\`" (symbol-name pkg) "-[0-9]+")) + (dir (car (directory-files elpa-dir 'full pkg-match)))) + (when dir (file-name-as-directory dir)))))) + +(defun spacemacs/mplist-get (plist prop) + "Get the values associated to PROP in PLIST, a modified plist. + +A modified plist is one where keys are keywords and values are +all non-keywords elements that follow it. + +If there are multiple properties with the same keyword, only the first property +and its values is returned. + +Currently this function infloops when the list is circular." + (let ((tail plist) + result) + (while (and (consp tail) (not (eq prop (car tail)))) + (pop tail)) + ;; pop the found keyword + (pop tail) + (while (and (consp tail) (not (keywordp (car tail)))) + (push (pop tail) result)) + (nreverse result))) + +(defun spacemacs/mplist-remove (plist prop) + "Return a copy of a modified PLIST without PROP and its values. + +If there are multiple properties with the same keyword, only the first property +and its values are removed." + (let ((tail plist) + result) + (while (and (consp tail) (not (eq prop (car tail)))) + (push (pop tail) result)) + (when (eq prop (car tail)) + (pop tail) + (while (and (consp tail) (not (keywordp (car tail)))) + (pop tail))) + (while (consp tail) + (push (pop tail) result)) + (nreverse result))) + +;; Originally based on http://stackoverflow.com/questions/2321904/elisp-how-to-save-data-in-a-file +(defun spacemacs/dump-vars-to-file (varlist filename) + "simplistic dumping of variables in VARLIST to a file FILENAME" + (with-temp-file filename + (spacemacs/dump varlist (current-buffer)) + (make-directory (file-name-directory filename) t))) + +;; From http://stackoverflow.com/questions/2321904/elisp-how-to-save-data-in-a-file +(defun spacemacs/dump (varlist buffer) + "insert into buffer the setq statement to recreate the variables in VARLIST" + (cl-loop for var in varlist do + (print (list 'setq var (list 'quote (symbol-value var))) + buffer))) + +(defvar spacemacs--init-redisplay-count 0 + "The number of calls to `redisplay'") +(defun spacemacs//redisplay () + "`redisplay' wrapper." + (setq spacemacs--init-redisplay-count (1+ spacemacs--init-redisplay-count)) + (redisplay)) + +(defun spacemacs//create-key-binding-form (props func) + "Helper which returns a from to bind FUNC to a key according to PROPS. + +Supported properties: + +`:evil-leader STRING' + One or several key sequence strings to be set with `spacemacs/set-leader-keys . + +`:evil-leader-for-mode CONS CELL' + One or several cons cells (MODE . KEY) where MODE is a major-mode symbol + and KEY is a key sequence string to be set with + `spacemacs/set-leader-keys-for-major-mode'. + +`:global-key STRING' + One or several key sequence strings to be set with `global-set-key'. + +`:define-key CONS CELL' + One or several cons cells (MAP . KEY) where MAP is a mode map and KEY is a + key sequence string to be set with `define-key'. " + (let ((evil-leader (spacemacs/mplist-get props :evil-leader)) + (evil-leader-for-mode (spacemacs/mplist-get props :evil-leader-for-mode)) + (global-key (spacemacs/mplist-get props :global-key)) + (def-key (spacemacs/mplist-get props :define-key))) + (append + (when evil-leader + `((dolist (key ',evil-leader) + (spacemacs/set-leader-keys key ',func)))) + (when evil-leader-for-mode + `((dolist (val ',evil-leader-for-mode) + (spacemacs/set-leader-keys-for-major-mode + (car val) (cdr val) ',func)))) + (when global-key + `((dolist (key ',global-key) + (global-set-key (kbd key) ',func)))) + (when def-key + `((dolist (val ',def-key) + (define-key (eval (car val)) (kbd (cdr val)) ',func))))))) + +(defun spacemacs/prettify-org-buffer () + "Apply visual enchantments to the current buffer. +The buffer's major mode should be `org-mode'." + (interactive) + (unless (derived-mode-p 'org-mode) + (user-error "org-mode should be enabled in the current buffer.")) + + ;; Make ~SPC ,~ work, reference: + ;; http://stackoverflow.com/questions/24169333/how-can-i-emphasize-or-verbatim-quote-a-comma-in-org-mode + (setcar (nthcdr 2 org-emphasis-regexp-components) " \t\n") + (org-set-emph-re 'org-emphasis-regexp-components org-emphasis-regexp-components) + (setq-local org-emphasis-alist '(("*" bold) + ("/" italic) + ("_" underline) + ("=" org-verbatim verbatim) + ("~" org-kbd) + ("+" + (:strike-through t)))) + (when (require 'space-doc nil t) + (space-doc-mode))) + +(defun spacemacs/view-org-file (file &optional anchor-text expand-scope) + "Open org file and apply visual enchantments. +FILE is the org file to be opened. +If ANCHOR-TEXT is `nil' then run `re-search-forward' with ^ (beginning-of-line). +If ANCHOR-TEXT is a GitHub style anchor then find a corresponding header. +If ANCHOR-TEXT isn't a GitHub style anchor then run `re-search-forward' with +ANCHOR-TEXT. +If EXPAND-SCOPE is `subtree' then run `outline-show-subtree' at the matched line. +If EXPAND-SCOPE is `all' then run `outline-show-all' at the matched line." + (interactive) + (find-file file) + (spacemacs/prettify-org-buffer) + (goto-char (point-min)) + (when anchor-text + ;; If `anchor-text' is GitHub style link. + (if (string-prefix-p "#" anchor-text) + ;; If the toc-org package is loaded. + (if (configuration-layer/package-usedp 'toc-org) + ;; For each heading. Search the heading that corresponds + ;; to `anchor-text'. + (while (and (re-search-forward "^[\\*]+\s\\(.*\\).*$" nil t) + (not (string= (toc-org-hrefify-gh (match-string 1)) + anchor-text)))) + ;; This is not a problem because without the space-doc package + ;; those links will be opened in the browser. + (message (format (concat "Can't follow the GitHub style anchor: '%s' " + "without the org layer.") anchor-text))) + (re-search-forward anchor-text))) + (beginning-of-line) + (cond + ((eq expand-scope 'subtree) + (outline-show-subtree)) + ((eq expand-scope 'all) + (outline-show-all)) + (t nil))) + +(defun spacemacs//test-var (pred var test-desc) + "Test PRED against VAR and print test result, incrementing +passed-tests and total-tests." + (let ((var-name (symbol-name var)) + (var-val (symbol-value var))) + (when (boundp 'total-tests) (setq total-tests (1+ total-tests))) + (insert (format "** TEST: [[file:%s::%s][%s]] %s\n" + dotspacemacs-filepath var-name var-name test-desc)) + (if (funcall pred var-val) + (progn + (when (boundp 'passed-tests) (setq passed-tests (1+ passed-tests))) + (insert (format "*** PASS: %s\n" var-val))) + (insert (propertize (format "*** FAIL: %s\n" var-val) + 'font-lock-face 'font-lock-warning-face))))) + +(defun spacemacs//test-list (pred varlist test-desc &optional element-desc) + "Test PRED against each element of VARLIST and print test +result, incrementing passed-tests and total-tests." + (let ((varlist-name (symbol-name varlist)) + (varlist-val (symbol-value varlist))) + (if element-desc + (insert (format "** TEST: Each %s in [[file:%s::%s][%s]] %s\n" + element-desc dotspacemacs-filepath varlist-name + varlist-name test-desc)) + (insert (format "** TEST: Each element of [[file:%s::%s][%s]] %s\n" + dotspacemacs-filepath varlist-name varlist-name + test-desc))) + (dolist (var varlist-val) + (when (boundp 'total-tests) (setq total-tests (1+ total-tests))) + (if (funcall pred var) + (progn + (when (boundp 'passed-tests) (setq passed-tests (1+ passed-tests))) + (insert (format "*** PASS: %s\n" var))) + (insert (propertize (format "*** FAIL: %s\n" var) 'font-lock-face 'font-lock-warning-face)))))) + +;; hide mode line +;; from http://bzg.fr/emacs-hide-mode-line.html +(defvar-local hidden-mode-line-mode nil) +(defvar-local hide-mode-line nil) +(define-minor-mode hidden-mode-line-mode + "Minor mode to hide the mode-line in the current buffer." + :init-value nil + :global t + :variable hidden-mode-line-mode + :group 'editing-basics + (if hidden-mode-line-mode + (setq hide-mode-line mode-line-format + mode-line-format nil) + (setq mode-line-format hide-mode-line + hide-mode-line nil)) + (force-mode-line-update) + ;; Apparently force-mode-line-update is not always enough to + ;; redisplay the mode-line + (redraw-display) + (when (and (called-interactively-p 'interactive) + hidden-mode-line-mode) + (run-with-idle-timer + 0 nil 'message + (concat "Hidden Mode Line Mode enabled. " + "Use M-x hidden-mode-line-mode to make the mode-line appear.")))) + +(defun spacemacs/recompile-elpa () + "Recompile packages in elpa directory. Useful if you switch +Emacs versions." + (interactive) + (byte-recompile-directory package-user-dir nil t)) + +(defun spacemacs/register-repl (feature repl-func &optional tag) + "Register REPL-FUNC to the global list of REPLs SPACEMACS-REPL-LIST. +FEATURE will be loaded before running the REPL, in case it is not already +loaded. If TAG is non-nil, it will be used as the string to show in the helm +buffer." + (push `(,(or tag (symbol-name repl-func)) + . (,feature . ,repl-func)) + spacemacs-repl-list)) + +;; http://stackoverflow.com/questions/11847547/emacs-regexp-count-occurrences +(defun spacemacs/how-many-str (regexp str) + (loop with start = 0 + for count from 0 + while (string-match regexp str start) + do (setq start (match-end 0)) + finally return count)) + +;; from https://github.com/cofi/dotfiles/blob/master/emacs.d/config/cofi-util.el#L38 +(defun spacemacs/add-to-hooks (fun hooks) + "Add function to hooks" + (dolist (hook hooks) + (add-hook hook fun))) + +(defun spacemacs/add-all-to-hook (hook &rest funs) + "Add functions to hook." + (spacemacs/add-to-hook hook funs)) + +(defun spacemacs/add-to-hook (hook funs) + "Add list of functions to hook." + (dolist (fun funs) + (add-hook hook fun))) + +(defun spacemacs/echo (msg &rest args) + "Display MSG in echo-area without logging it in *Messages* buffer." + (interactive) + (let ((message-log-max nil)) + (apply 'message msg args))) + +(defun spacemacs/alternate-buffer (&optional window) + "Switch back and forth between current and last buffer in the +current window." + (interactive) + (let ((current-buffer (window-buffer window)) + (buffer-predicate + (frame-parameter (window-frame window) 'buffer-predicate))) + ;; switch to first buffer previously shown in this window that matches + ;; frame-parameter `buffer-predicate' + (switch-to-buffer + (or (cl-find-if (lambda (buffer) + (and (not (eq buffer current-buffer)) + (or (null buffer-predicate) + (funcall buffer-predicate buffer)))) + (mapcar #'car (window-prev-buffers window))) + ;; `other-buffer' honors `buffer-predicate' so no need to filter + (other-buffer current-buffer t))))) + +(defun spacemacs/comint-clear-buffer () + (interactive) + (let ((comint-buffer-maximum-size 0)) + (comint-truncate-buffer))) + + +;; Generalized next-error system ("gne") + +(defun spacemacs/error-delegate () + "Decide which error API to delegate to. + +Delegates to flycheck if it is enabled and the next-error buffer +is not visible. Otherwise delegates to regular Emacs next-error." + (if (and (bound-and-true-p flycheck-mode) + (let ((buf (ignore-errors (next-error-find-buffer)))) + (not (and buf (get-buffer-window buf))))) + 'flycheck + 'emacs)) + +(defun spacemacs/next-error (&optional n reset) + "Dispatch to flycheck or standard emacs error." + (interactive "P") + (let ((sys (spacemacs/error-delegate))) + (cond + ((eq 'flycheck sys) (call-interactively 'flycheck-next-error)) + ((eq 'emacs sys) (call-interactively 'next-error))))) + +(defun spacemacs/previous-error (&optional n reset) + "Dispatch to flycheck or standard emacs error." + (interactive "P") + (let ((sys (spacemacs/error-delegate))) + (cond + ((eq 'flycheck sys) (call-interactively 'flycheck-previous-error)) + ((eq 'emacs sys) (call-interactively 'previous-error))))) + +(defvar-local spacemacs--gne-min-line nil + "The first line in the buffer that is a valid result.") +(defvar-local spacemacs--gne-max-line nil + "The last line in the buffer that is a valid result.") +(defvar-local spacemacs--gne-cur-line 0 + "The current line in the buffer. (It is problematic to use +point for this.)") +(defvar-local spacemacs--gne-line-func nil + "The function to call to visit the result on a line.") + +(defun spacemacs/gne-next (num reset) + "A generalized next-error function. This function can be used +as `next-error-function' in any buffer that conforms to the +Spacemacs generalized next-error API. + +The variables `spacemacs--gne-min-line', +`spacemacs--gne-max-line', and `spacemacs--line-func' must be +set." + (when reset (setq spacemacs--gne-cur-line + spacemacs--gne-min-line)) + (setq spacemacs--gne-cur-line + (min spacemacs--gne-max-line + (max spacemacs--gne-min-line + (+ num spacemacs--gne-cur-line)))) + (goto-line spacemacs--gne-cur-line) + (funcall spacemacs--gne-line-func + (buffer-substring (point-at-bol) (point-at-eol)))) + +(provide 'core-funcs) diff --git a/core/core-jump.el b/core/core-jump.el new file mode 100644 index 0000000..48676d2 --- /dev/null +++ b/core/core-jump.el @@ -0,0 +1,66 @@ +;;; core-jump.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar spacemacs-default-jump-handlers '() + "List of jump handlers available in every mode.") + +(defvar-local spacemacs-jump-handlers '() + "List of jump handlers local to this buffer.") + +(defmacro spacemacs|define-jump-handlers (mode &rest handlers) + "Defines jump handlers for the given MODE. +This defines a variable `spacemacs-jump-handlers-MODE' to which +handlers can be added, and a function added to MODE-hook which +sets `spacemacs-jump-handlers' in buffers of that mode." + (let ((mode-hook (intern (format "%S-hook" mode))) + (func (intern (format "spacemacs//init-jump-handlers-%S" mode))) + (handlers-list (intern (format "spacemacs-jump-handlers-%S" mode)))) + `(progn + (defvar ,handlers-list ',handlers + ,(format (concat "List of mode-specific jump handlers for %S. " + "These take priority over those in " + "`spacemacs-default-jump-handlers'.") + mode)) + (defun ,func () + (setq spacemacs-jump-handlers + (append ,handlers-list + spacemacs-default-jump-handlers))) + (add-hook ',mode-hook ',func) + (with-eval-after-load 'bind-map + (spacemacs/set-leader-keys-for-major-mode ',mode + "gg" 'spacemacs/jump-to-definition))))) + +(defun spacemacs/jump-to-definition () + (interactive) + (catch 'done + (let ((old-buffer (current-buffer)) + (old-point (point))) + (dolist (-handler spacemacs-jump-handlers) + (let ((handler (if (listp -handler) (car -handler) -handler)) + (async (when (listp -handler) + (plist-get (cdr -handler) :async)))) + (ignore-errors + (call-interactively handler)) + (when (or async + (not (eq old-point (point))) + (not (equal old-buffer (current-buffer)))) + (throw 'done t))))) + (message "No jump handler was able to find this symbol."))) + +;; Set the `:jump' property manually instead of just using `evil-define-motion' +;; in an `eval-after-load' macro invocation because doing that prevents +;; `describe-function' from correctly finding the source. +;; +;; See discussion on https://github.com/syl20bnr/spacemacs/pull/6771 +(with-eval-after-load 'evil + (evil-set-command-property 'spacemacs/jump-to-definition :jump t)) + +(provide 'core-jump) diff --git a/core/core-keybindings.el b/core/core-keybindings.el new file mode 100644 index 0000000..fc3cf6d --- /dev/null +++ b/core/core-keybindings.el @@ -0,0 +1,177 @@ +;;; core-keybindings.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(require 'core-funcs) + +(defvar spacemacs/prefix-titles nil + "alist for mapping command prefixes to long names.") + +(defvar spacemacs-default-map (make-sparse-keymap) + "Base keymap for all spacemacs leader key commands.") + +(defun spacemacs/translate-C-i (_) + "If `dotspacemacs-distinguish-gui-tab' is non nil, the raw key +sequence does not include or , and we are in the +gui, translate to [C-i]. Otherwise, [9] (TAB)." + (interactive) + (if (and (not (cl-position 'tab (this-single-command-raw-keys))) + (not (cl-position 'kp-tab (this-single-command-raw-keys))) + dotspacemacs-distinguish-gui-tab + (display-graphic-p)) + [C-i] [?\C-i])) +(define-key key-translation-map [?\C-i] 'spacemacs/translate-C-i) + +;; (defun spacemacs/translate-C-m (_) +;; "If `dotspacemacs-distinguish-gui-ret' is non nil, the raw key +;; sequence does not include , and we are in the gui, translate +;; to [C-m]. Otherwise, [9] (TAB)." +;; (interactive) +;; (if (and +;; (not (cl-position 'return (this-single-command-raw-keys))) +;; (not (cl-position 'kp-enter (this-single-command-raw-keys))) +;; dotspacemacs-distinguish-gui-ret +;; (display-graphic-p)) +;; [C-m] [?\C-m])) +;; (define-key key-translation-map [?\C-m] 'spacemacs/translate-C-m) + +(defun spacemacs/declare-prefix (prefix name &optional long-name) + "Declare a prefix PREFIX. PREFIX is a string describing a key +sequence. NAME is a string used as the prefix command. +LONG-NAME if given is stored in `spacemacs/prefix-titles'." + (let* ((command name) + (full-prefix (concat dotspacemacs-leader-key " " prefix)) + (full-prefix-emacs (concat dotspacemacs-emacs-leader-key " " prefix)) + (full-prefix-lst (listify-key-sequence (kbd full-prefix))) + (full-prefix-emacs-lst (listify-key-sequence + (kbd full-prefix-emacs)))) + ;; define the prefix command only if it does not already exist + (unless long-name (setq long-name name)) + (which-key-declare-prefixes + full-prefix-emacs (cons name long-name) + full-prefix (cons name long-name)))) + +(defun spacemacs/declare-prefix-for-mode (mode prefix name &optional long-name) + "Declare a prefix PREFIX. MODE is the mode in which this prefix command should +be added. PREFIX is a string describing a key sequence. NAME is a symbol name +used as the prefix command." + (let ((command (intern (concat (symbol-name mode) name))) + (full-prefix (concat dotspacemacs-leader-key " " prefix)) + (full-prefix-emacs (concat dotspacemacs-emacs-leader-key " " prefix)) + (is-major-mode-prefix (string-prefix-p "m" prefix)) + (major-mode-prefix (concat dotspacemacs-major-mode-leader-key + " " (substring prefix 1))) + (major-mode-prefix-emacs + (concat dotspacemacs-major-mode-emacs-leader-key + " " (substring prefix 1)))) + (unless long-name (setq long-name name)) + (let ((prefix-name (cons name long-name))) + (which-key-declare-prefixes-for-mode mode + full-prefix-emacs prefix-name + full-prefix prefix-name) + (when (and is-major-mode-prefix dotspacemacs-major-mode-leader-key) + (which-key-declare-prefixes-for-mode mode major-mode-prefix prefix-name)) + (when (and is-major-mode-prefix dotspacemacs-major-mode-emacs-leader-key) + (which-key-declare-prefixes-for-mode + mode major-mode-prefix-emacs prefix-name))))) + +(defun spacemacs/set-leader-keys (key def &rest bindings) + "Add KEY and DEF as key bindings under +`dotspacemacs-leader-key' and `dotspacemacs-emacs-leader-key'. +KEY should be a string suitable for passing to `kbd', and it +should not include the leaders. DEF is most likely a quoted +command. See `define-key' for more information about the possible +choices for DEF. This function simply uses `define-key' to add +the bindings. + +For convenience, this function will accept additional KEY DEF +pairs. For example, + +\(spacemacs/set-leader-keys + \"a\" 'command1 + \"C-c\" 'command2 + \"bb\" 'command3\)" + (while key + (define-key spacemacs-default-map (kbd key) def) + (setq key (pop bindings) def (pop bindings)))) +(put 'spacemacs/set-leader-keys 'lisp-indent-function 'defun) + +(defalias 'evil-leader/set-key 'spacemacs/set-leader-keys) + +(defun spacemacs//acceptable-leader-p (key) + "Return t if key is a string and non-empty." + (and (stringp key) (not (string= key "")))) + +(defun spacemacs//init-leader-mode-map (mode map &optional minor) + "Check for MAP-prefix. If it doesn't exist yet, use `bind-map' +to create it and bind it to `dotspacemacs-major-mode-leader-key' +and `dotspacemacs-major-mode-emacs-leader-key'. If MODE is a +minor-mode, the third argument should be non nil." + (let* ((prefix (intern (format "%s-prefix" map))) + (leader1 (when (spacemacs//acceptable-leader-p + dotspacemacs-major-mode-leader-key) + dotspacemacs-major-mode-leader-key)) + (leader2 (when (spacemacs//acceptable-leader-p + dotspacemacs-leader-key) + (concat dotspacemacs-leader-key + (unless minor " m")))) + (emacs-leader1 (when (spacemacs//acceptable-leader-p + dotspacemacs-major-mode-emacs-leader-key) + dotspacemacs-major-mode-emacs-leader-key)) + (emacs-leader2 (when (spacemacs//acceptable-leader-p + dotspacemacs-emacs-leader-key) + (concat dotspacemacs-emacs-leader-key + (unless minor " m")))) + (leaders (delq nil (list leader1 leader2))) + (emacs-leaders (delq nil (list emacs-leader1 emacs-leader2)))) + (or (boundp prefix) + (progn + (eval + `(bind-map ,map + :prefix-cmd ,prefix + ,(if minor :minor-modes :major-modes) (,mode) + :keys ,emacs-leaders + :evil-keys ,leaders + :evil-states (normal motion visual evilified))) + (boundp prefix))))) + +(defun spacemacs/set-leader-keys-for-major-mode (mode key def &rest bindings) + "Add KEY and DEF as key bindings under +`dotspacemacs-major-mode-leader-key' and +`dotspacemacs-major-mode-emacs-leader-key' for the major-mode +MODE. MODE should be a quoted symbol corresponding to a valid +major mode. The rest of the arguments are treated exactly like +they are in `spacemacs/set-leader-keys'." + (let* ((map (intern (format "spacemacs-%s-map" mode)))) + (when (spacemacs//init-leader-mode-map mode map) + (while key + (define-key (symbol-value map) (kbd key) def) + (setq key (pop bindings) def (pop bindings)))))) +(put 'spacemacs/set-leader-keys-for-major-mode 'lisp-indent-function 'defun) + +(defalias + 'evil-leader/set-key-for-mode + 'spacemacs/set-leader-keys-for-major-mode) + +(defun spacemacs/set-leader-keys-for-minor-mode (mode key def &rest bindings) + "Add KEY and DEF as key bindings under +`dotspacemacs-major-mode-leader-key' and +`dotspacemacs-major-mode-emacs-leader-key' for the minor-mode +MODE. MODE should be a quoted symbol corresponding to a valid +minor mode. The rest of the arguments are treated exactly like +they are in `spacemacs/set-leader-keys'." + (let* ((map (intern (format "spacemacs-%s-map" mode)))) + (when (spacemacs//init-leader-mode-map mode map t) + (while key + (define-key (symbol-value map) (kbd key) def) + (setq key (pop bindings) def (pop bindings)))))) +(put 'spacemacs/set-leader-keys-for-minor-mode 'lisp-indent-function 'defun) + +(provide 'core-keybindings) diff --git a/core/core-load-paths.el b/core/core-load-paths.el new file mode 100644 index 0000000..0c752b3 --- /dev/null +++ b/core/core-load-paths.el @@ -0,0 +1,77 @@ +;;; core-load-paths.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(defun add-to-load-path (dir) (add-to-list 'load-path dir)) + +(defun add-to-load-path-if-exists (dir) + "If DIR exists in the file system, add it to `load-path'." + (when (file-exists-p dir) + (add-to-load-path dir))) + +;; paths +(defvar spacemacs-start-directory + user-emacs-directory + "Spacemacs start directory.") +(defconst spacemacs-core-directory + (expand-file-name (concat spacemacs-start-directory "core/")) + "Spacemacs core directory.") +(defconst spacemacs-info-directory + (expand-file-name (concat spacemacs-core-directory "info/")) + "Spacemacs info files directory") +(defconst spacemacs-release-notes-directory + (expand-file-name (concat spacemacs-info-directory "release-notes/")) + "Spacemacs release notes directory") +(defconst spacemacs-banner-directory + (expand-file-name (concat spacemacs-core-directory "banners/")) + "Spacemacs banners directory.") +(defconst spacemacs-banner-official-png + (expand-file-name (concat spacemacs-banner-directory "img/spacemacs.png")) + "Spacemacs official banner image.") +(defconst spacemacs-badge-official-png + (expand-file-name (concat spacemacs-banner-directory + "img/spacemacs-badge.png")) + "Spacemacs official badge image.") +(defconst spacemacs-purple-heart-png + (expand-file-name (concat spacemacs-banner-directory "img/heart.png")) + "Purple heart emoji.") +(defconst spacemacs-cache-directory + (expand-file-name (concat user-emacs-directory ".cache/")) + "Spacemacs storage area for persistent files") +(defconst spacemacs-auto-save-directory + (expand-file-name (concat spacemacs-cache-directory "auto-save/")) + "Spacemacs auto-save directory") +(defconst spacemacs-docs-directory + (expand-file-name (concat spacemacs-start-directory "doc/")) + "Spacemacs documentation directory.") +(defconst spacemacs-news-directory + (expand-file-name (concat spacemacs-start-directory "news/")) + "Spacemacs News directory.") +(defconst spacemacs-assets-directory + (expand-file-name (concat spacemacs-start-directory "assets/")) + "Spacemacs assets directory.") +(defconst spacemacs-test-directory + (expand-file-name (concat spacemacs-start-directory "tests/")) + "Spacemacs tests directory.") + +(defconst user-home-directory + (expand-file-name "~/") + "User home directory (~/).") +(defconst pcache-directory + (concat spacemacs-cache-directory "pcache/")) +(unless (file-exists-p spacemacs-cache-directory) + (make-directory spacemacs-cache-directory)) + +;; load paths +(mapc 'add-to-load-path + `( + ,spacemacs-core-directory + ,(concat spacemacs-core-directory "libs/") + ,(concat spacemacs-core-directory "aprilfool/") + )) diff --git a/core/core-micro-state.el b/core/core-micro-state.el new file mode 100644 index 0000000..98c34b8 --- /dev/null +++ b/core/core-micro-state.el @@ -0,0 +1,272 @@ +;;; -*- lexical-binding: t -*- +;;; core-micro-state.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spacemacs/defface-micro-state-faces () + "Define faces for micro-states." + (let* ((hname 'spacemacs-micro-state-header-face) + (bname 'spacemacs-micro-state-binding-face) + (box '(:line-width -1 :color (plist-get (face-attribute + 'mode-line :box) :color))) + (err (face-attribute 'error :foreground))) + (eval `(defface ,hname '((t ())) + "Face for micro-state header in echo area. +The header is the name of the micro-state." + :group 'spacemacs)) + (set-face-attribute hname nil + :background "DarkGoldenrod2" + :foreground "black" + :bold t + :box box) + (eval `(defface ,bname '((t ())) + "Face for micro-state key binding in echo area. +Characters enclosed in `[]' will have this face applied to them." + :group 'spacemacs)) + (set-face-attribute bname nil + :foreground err + :bold t))) +(spacemacs/defface-micro-state-faces) +(add-hook 'spacemacs-post-theme-change-hook + 'spacemacs/defface-micro-state-faces) + +(defun spacemacs//micro-state-set-minibuffer-height (str) + "Set the max mini windows size given a string STR." + (let ((line-count (1+ (spacemacs/how-many-str "\n" str)))) + (when (and (> line-count max-mini-window-height) + (> line-count 10)) + (setq max-mini-window-height line-count)))) + +(defmacro spacemacs|define-micro-state (name &rest props) + "Define a micro-state called NAME. + +NAME is a symbol. + +Available PROPS: + +`:on-enter SEXP' + Evaluate SEXP when the micro-state is switched on. + +`:on-exit SEXP' + Evaluate SEXP when leaving the micro-state. + +`:doc STRING or SEXP' + A STRING or a SEXP that evaluates to a string. + +`:use-minibuffer BOOLEAN' + If non nil then the minibuffer is used to display the documenation + strings. Default is nil. + +`:disable-evil-leader BOOLEAN' + If non nil then the evil leader has no effect when the micro state + is active. Default to nil. + +`:persistent BOOLEAN' + If BOOLEAN is non nil then the micro-state never exits. A binding + with an explicitly set `exit t' property is required. Default is nil. + +`:execute-binding-on-enter BOOLEAN' + If BOOLEAN is non nil then execute the micro-state command bound to + to the pressed key that started the micro-state. + +`:bindings EXPRESSIONS' + One or several EXPRESSIONS with the form + (STRING1 SYMBOL1 :doc STRING + :pre SEXP + :post SEXP + :exit SYMBOL) + where: + - STRING1 is a key to be bound to the function or key map SYMBOL1. + - :doc STRING or SEXP is a STRING or an SEXP that evalutes + to a string + - :pre is an SEXP evaluated before the bound action + - :post is an SEXP evaluated after the bound action + - :exit SYMBOL or SEXP, if non nil then pressing this key will + leave the micro-state (default is nil). + Important note: due to inner working of transient-maps in Emacs + the `:exit' keyword is evaluate *before* the actual execution + of the bound command. + +All properties supported by `spacemacs//create-key-binding-form' can be +used." + (declare (indent 1)) + (let* ((func (spacemacs//micro-state-func-name name)) + (doc (spacemacs/mplist-get props :doc)) + (persistent (plist-get props :persistent)) + (disable-leader (plist-get props :disable-evil-leader)) + (msg-func (if (plist-get props :use-minibuffer) + 'message + 'lv-message)) + (exec-binding (plist-get props :execute-binding-on-enter)) + (on-enter (spacemacs/mplist-get props :on-enter)) + (on-exit (spacemacs/mplist-get props :on-exit)) + (bindings (spacemacs/mplist-get props :bindings)) + (wrappers (spacemacs//micro-state-create-wrappers + name doc msg-func disable-leader bindings)) + (keymap-body (spacemacs//micro-state-fill-map-sexps wrappers)) + (bindkeys (spacemacs//create-key-binding-form props func))) + `(progn (defun ,func () + ,(format "%S micro-state." name) + (interactive) + ,@on-enter + ,(when exec-binding + (spacemacs//micro-state-auto-execute bindings)) + (let ((doc ,@doc)) + (when doc + (spacemacs//micro-state-set-minibuffer-height doc) + (apply ',msg-func (list (spacemacs//micro-state-propertize-doc + (format "%S: %s" ',name doc)))))) + (,(if (version< emacs-version "24.4") + 'set-temporary-overlay-map + 'set-transient-map) + (let ((map (make-sparse-keymap))) + ,@keymap-body map) ',(spacemacs//micro-state-create-exit-func + name wrappers persistent on-exit))) + ,@bindkeys))) + +(defun spacemacs//micro-state-func-name (name) + "Return the name of the micro-state function." + (intern (format "spacemacs/%S-micro-state" name))) + +(defun spacemacs//micro-state-auto-execute (bindings) + "Auto execute the binding corresponding to `this-command-keys'." + `(let* ((key (substring (this-command-keys) + (1- (length (this-command-keys))))) + (binding (assoc key ',bindings))) + (when binding + (call-interactively (cadr binding))))) + +(defun spacemacs//micro-state-create-wrappers + (name doc msg-func disable-leader bindings) + "Return an alist (key wrapper) for each binding in BINDINGS." + (mapcar (lambda (x) (spacemacs//micro-state-create-wrapper + name doc msg-func x)) + (append bindings + ;; force SPC to quit the micro-state to avoid a edge case + ;; with evil-leader + (list `(,dotspacemacs-leader-key + ,(unless disable-leader 'spacemacs-default-map) + :exit t))))) + +(defun spacemacs//micro-state-create-wrapper (name default-doc msg-func binding) + "Create a wrapper of FUNC and return a tuple (key wrapper BINDING)." + (let* ((key (car binding)) + (wrapped (cadr binding)) + (binding-doc (spacemacs/mplist-get binding :doc)) + (binding-pre (spacemacs/mplist-get binding :pre)) + (binding-post (spacemacs/mplist-get binding :post)) + (wrapper-name (intern (format "spacemacs//%S-%S-%s" name wrapped key))) + (doc-body + `((let ((bdoc ,@binding-doc) + (defdoc ,@default-doc)) + (cond + (bdoc + (apply ',msg-func + (list (spacemacs//micro-state-propertize-doc + (format "%S: %s" ',name bdoc)))) + bdoc) + ((and defdoc + ',wrapped + (not (plist-get ',binding :exit))) + (spacemacs//micro-state-set-minibuffer-height defdoc) + (apply ',msg-func + (list (spacemacs//micro-state-propertize-doc + (format "%S: %s" ',name defdoc)))) + defdoc))))) + (wrapper-func + (if (and (boundp wrapped) + (eval `(keymapp ,wrapped))) + wrapped + `(defun ,wrapper-name () + "Auto-generated function" + (interactive) + ,@binding-pre + (let ((throwp t)) + (catch 'exit + (when (fboundp ',wrapped) + (setq this-command ',wrapped) + (call-interactively ',wrapped) + (setq last-command ',wrapped)) + (setq throwp nil)) + ,@binding-post + (when throwp (throw 'exit nil))) + (when ,@doc-body + (spacemacs//micro-state-set-minibuffer-height ,@doc-body) + ,@doc-body))))) + (append (list (car binding) (eval wrapper-func)) binding))) + +(defun spacemacs//micro-state-fill-map-sexps (wrappers) + "Return a list of `define-key' sexp to fill the micro-state temporary map." + (mapcar (lambda (x) `(define-key map ,(kbd (car x)) ',(cadr x))) + wrappers)) + +(defun spacemacs//micro-state-create-exit-func + (name wrappers persistent on-exit) + "Return a function to execute when leaving the micro-state. + +The returned function returns nil if the executed command exits the +micro-state." + (let ((func (intern (format "spacemacs//%s-on-exit" name)))) + (eval `(defun ,func () + "Function executed after each micro-state command." + (let* ((cur-wrapper (spacemacs//get-current-wrapper + ',name ',wrappers)) + (exitp (if cur-wrapper (plist-get cur-wrapper :exit) + ,(not persistent)))) + (when (listp exitp) (setq exitp (eval exitp))) + (when exitp ,@on-exit (spacemacs//micro-state-close-window)) + (not exitp)))))) + +(defun spacemacs//get-current-wrapper (name wrappers) + "Return the wrapper being executed. +Return nil if no wrapper is being executed (i.e. an unbound key has been +pressed)." + (let ((micro-state-fun (spacemacs//micro-state-func-name name))) + (catch 'found + (dolist (wrapper wrappers) + (let ((key (car wrapper)) + (func (cadr wrapper))) + (if (and (or (eq this-command micro-state-fun) + (eq this-command func)) + (equal (this-command-keys) (kbd key))) + (throw 'found wrapper)))) + nil))) + +(defun spacemacs//micro-state-propertize-doc (doc) + "Return a propertized doc string from DOC." + (when (string-match "^\\(.+?\\):\\([[:ascii:]]*\\)$" doc) + (let* ((header (match-string 1 doc)) + (pheader (when header + (propertize (concat " " header " ") + 'face 'spacemacs-micro-state-header-face))) + (tail (spacemacs//micro-state-propertize-doc-rec + (match-string 2 doc)))) + (concat pheader tail)))) + +(defun spacemacs//micro-state-propertize-doc-rec (doc) + "Recursively propertize keys" + (if (string-match "^\\([[:ascii:]]*?\\)\\(\\[.+?\\]\\)\\([[:ascii:]]*\\)$" doc) + (let* ((head (match-string 1 doc)) + (key (match-string 2 doc)) + (pkey (when key + (propertize key 'face 'spacemacs-micro-state-binding-face))) + (tail (spacemacs//micro-state-propertize-doc-rec + (match-string 3 doc)))) + (concat head pkey tail)) + doc)) + +(defun spacemacs//micro-state-close-window () + "Close micro-state help window." + (when (window-live-p lv-wnd) + (let ((buf (window-buffer lv-wnd))) + (delete-window lv-wnd) + (kill-buffer buf)))) + +(provide 'core-micro-state) diff --git a/core/core-release-management.el b/core/core-release-management.el new file mode 100644 index 0000000..7967f9f --- /dev/null +++ b/core/core-release-management.el @@ -0,0 +1,343 @@ +;;; core-spacemacs.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(defconst spacemacs-repository "spacemacs" + "Name of the Spacemacs remote repository.") +(defconst spacemacs-repository-owner "syl20bnr" + "Name of the Spacemacs remote repository owner.") +(defconst spacemacs-checkversion-remote "checkversion" + "Name of the remote repository used to check for new version.") +(defconst spacemacs-checkversion-branch "master" + "Name of the branch used to check for new version.") + +(defvar dotspacemacs-check-for-update) +(defvar spacemacs-version) +;; new version variables +(defvar spacemacs-new-version nil + "If non-nil a new Spacemacs version is available.") +;; used to be "6 hours" but we now check for new versions only at startup +(defvar spacemacs-version-check-interval nil + "Time between two version checks.") +(defvar spacemacs-version-check-lighter "[+]" + "Text displayed in the mode-line when a new version is available.") +(defvar spacemacs-version--check-timer nil + "The current timer for new version check.") +(defvar spacemacs-version--last-startup-check-file + (expand-file-name (concat spacemacs-cache-directory "last-version-check")) + "File where the last startup version check time is stored.") +(defvar spacemacs-version--last-startup-check-time nil + "Time of last version check.") +(defvar spacemacs-version--startup-check-interval (* 3600 24) + "Minimum number of seconds between two version checks at startup.") + +(defun spacemacs/switch-to-version (&optional version) + "Switch spacemacs to VERSION. + +VERSION is a string with the format `x.x.x'. +IMPORTANT: The switch is performed by hard resetting the current branch. +If VERSION is nil then a prompt will ask for a version number. +If the current version is not `master' and not `develop' then +a prompt will ask for confirmation before actually switching to the +specified version. +It is not possible to switch version when you are on `develop' branch, +users on `develop' branch must manually pull last commits instead." + (interactive) + (let ((branch (spacemacs//git-get-current-branch)) + (dirty (spacemacs//git-working-directory-dirty))) + (unless version + (message "Getting version information...") + (let ((last-version (spacemacs/get-last-version))) + (setq version (read-string + (format "Version (default %s [latest]): " last-version) + nil nil last-version)))) + (cond ((string-equal "develop" branch) + (message (concat "Cannot switch version because you are on " + "develop.\n" + "You have to manually `pull --rebase' the latest " + "commits."))) + (dirty + (message (concat "Your Emacs directory is not clean.\n" + "git status:\n%s") dirty)) + ((string-equal version spacemacs-version) + (message "You are already on the latest version.")) + ((or (string-equal "master" branch) + (yes-or-no-p + (format (concat "You are not on master. " + "This command will switch branches.\n" + "Are you sure that you want to switch " + "to version %s ? ") + version))) + (let ((tag (concat "v" version))) + (if (spacemacs//git-hard-reset-to-tag tag) + (progn + (setq spacemacs-version version) + (message "Successfully switched to version %s" version)) + (message "An error occurred while switching to version %s" + version)))) + (t (message "Update aborted."))))) + +(defun spacemacs/check-for-new-version (force &optional interval) + "Periodicly check for new for new Spacemacs version. +Update `spacemacs-new-version' variable if any new version has been +found." + (interactive "P") + (cond + ((and (not force) + (not dotspacemacs-check-for-update)) + (message "Skipping check for new version (reason: dotfile)")) + ((and (not force) + (string-equal "develop" (spacemacs//git-get-current-branch))) + (message "Skipping check for new version (reason: develop branch)")) + ((and (not force) + (not (spacemacs//can-check-for-new-version-at-startup))) + (message (concat "Skipping check for new version " + "(reason: last check is too recent)"))) + ((require 'async nil t) + (message "Start checking for new version...") + (async-start + `(lambda () + ,(async-inject-variables "\\`spacemacs-start-directory\\'") + (load-file (concat spacemacs-start-directory + "core/core-load-paths.el")) + (require 'core-spacemacs) + (spacemacs/get-last-version)) + (lambda (result) + (if result + (if (or (version< result spacemacs-version) + (string= result spacemacs-version) + (if spacemacs-new-version + (string= result spacemacs-new-version))) + (message "Spacemacs is up to date.") + (message "New version of Spacemacs available: %s" result) + (setq spacemacs-new-version result)) + (message "Unable to check for new version.")))) + (when interval + (setq spacemacs-version--check-timer + (run-at-time t (timer-duration interval) + 'spacemacs/check-for-new-version)))) + (t (message "Skipping check for new version (reason: async not loaded)")))) + +(defun spacemacs/git-get-current-branch-rev () + "Returns the hash of the head commit on the current branch. +Returns nil if an error occurred." + (let ((proc-buffer "git-get-current-branch-head-hash") + (default-directory (file-truename spacemacs-start-directory))) + (when (eq 0 (process-file "git" nil proc-buffer nil + "rev-parse" "--short" "HEAD")) + (with-current-buffer proc-buffer + (prog1 + (when (buffer-string) + (goto-char (point-min)) + (replace-regexp-in-string + "\n$" "" + (buffer-substring (line-beginning-position) + (line-end-position)))) + (kill-buffer proc-buffer)))))) + +(defun spacemacs/get-new-version-lighter-face (current new) + "Return the new version lighter face given the difference between the CURRENT +version and the NEW version." + (let* ((lcur (version-to-list current)) + (lnew (version-to-list new)) + (scur (spacemacs//compute-version-score lcur)) + (snew (spacemacs//compute-version-score lnew)) + (diff (- snew scur))) + (cond + ((< diff 3000) 'spacemacs-mode-line-new-version-lighter-success-face) + ((< diff 5000) 'spacemacs-mode-line-new-version-lighter-warning-face) + (t 'spacemacs-mode-line-new-version-lighter-error-face)))) + +(defun spacemacs/get-last-version () + "Return the last tagged version." + (interactive) + (spacemacs//get-last-version spacemacs-repository + spacemacs-repository-owner + spacemacs-checkversion-remote + spacemacs-checkversion-branch)) + +(defun spacemacs//can-check-for-new-version-at-startup () + "Return non-nil if the version check at startup can be performed." + (when (file-exists-p spacemacs-version--last-startup-check-file) + (load spacemacs-version--last-startup-check-file)) + (let ((result + (or (null spacemacs-version--last-startup-check-time) + (> (- (float-time) spacemacs-version--last-startup-check-time) + spacemacs-version--startup-check-interval)))) + (when result + (setq spacemacs-version--last-startup-check-time (float-time)) + (spacemacs/dump-vars-to-file '(spacemacs-version--last-startup-check-time) + spacemacs-version--last-startup-check-file)) + result)) + +(defun spacemacs//get-last-version (repo owner remote branch) + "Return the last tagged version of BRANCH on REMOTE repository from +OWNER REPO." + (let ((url (format "https://github.com/%s/%s" owner repo))) + (spacemacs//git-remove-remote remote) + (spacemacs//git-add-remote remote url) + ;; removing this call according to issue #6692 proposal + ;; (spacemacs//git-fetch-remote remote) + (spacemacs//git-fetch-tags remote branch)) + (let ((version (spacemacs//git-latest-tag remote branch))) + (when version + (save-match-data + (string-match "^.*\\([0-9]+\\.[0-9]+\\.[0-9]+\\)$" version) + (match-string 1 version))))) + +(defun spacemacs//git-has-remote (remote) + "Return non nil if REMOTE is declared." + (let ((proc-buffer "git-has-remote") + (default-directory (file-truename spacemacs-start-directory))) + (when (eq 0 (process-file "git" nil proc-buffer nil "remote")) + (with-current-buffer proc-buffer + (prog2 + (goto-char (point-min)) + (re-search-forward (format "^%s$" remote) nil 'noerror) + (kill-buffer proc-buffer)))))) + +(defun spacemacs//git-add-remote (remote url) + "Add a REMOTE with URL, return t if no error." + (let ((proc-buffer "git-add-remote") + (default-directory (file-truename spacemacs-start-directory))) + (prog1 + (eq 0 (process-file "git" nil proc-buffer nil + "remote" "add" remote url)) + (kill-buffer proc-buffer)))) + +(defun spacemacs//git-remove-remote (remote) + "Remove a REMOTE, return t if no error." + (let ((proc-buffer "git-remove-remote") + (default-directory (file-truename spacemacs-start-directory))) + (prog1 + (eq 0 (process-file "git" nil proc-buffer nil + "remote" "remove" remote)) + (kill-buffer proc-buffer)))) + +(defun spacemacs//git-fetch-remote (remote) + "Fetch last commits from REMOTE, return t if no error." + (let ((proc-buffer "git-fetch-remote") + (default-directory (file-truename spacemacs-start-directory))) + (prog1 + (eq 0 (process-file "git" nil proc-buffer nil + "fetch" remote)) + (kill-buffer proc-buffer)))) + +(defun spacemacs//git-fetch-tags (remote branch) + "Fetch the tags for BRANCH in REMOTE repository." + (let ((proc-buffer "git-fetch-tags") + (default-directory (file-truename spacemacs-start-directory))) + (prog1 + ;;;; original comment: seems necessary to fetch first + ;; but we remove this according to issue #6692 proposal + ;; (eq 0 (process-file "git" nil proc-buffer nil + ;; "fetch" remote branch)) + ;; explicitly fetch the new tags + (eq 0 (process-file "git" nil proc-buffer nil + "fetch" "--tags" remote branch)) + (kill-buffer proc-buffer)))) + +(defun spacemacs//git-hard-reset-to-tag (tag) + "Hard reset the current branch to specifed TAG." + (let ((proc-buffer "git-hard-reset") + (default-directory (file-truename spacemacs-start-directory))) + (prog1 + (eq 0 (process-file "git" nil proc-buffer nil + "reset" "--hard" tag)) + (kill-buffer proc-buffer)))) + +(defun spacemacs//git-latest-tag (remote branch) + "Returns the latest tag on REMOTE/BRANCH." + (let ((proc-buffer "git-latest-tag") + (default-directory (file-truename spacemacs-start-directory)) + (where (format "%s/%s" remote branch))) + (when (eq 0 (process-file "git" nil proc-buffer nil + "describe" "--tags" "--abbrev=0" + "--match=v*" where "FETCH_HEAD")) + (with-current-buffer proc-buffer + (prog1 + (when (buffer-string) + (goto-char (point-max)) + (forward-line -1) + (replace-regexp-in-string + "\n$" "" + (buffer-substring (line-beginning-position) + (line-end-position)))) + (kill-buffer proc-buffer)))))) + +(defun spacemacs//git-checkout (branch) + "Checkout the given BRANCH. Return t if there is no error." + (let ((proc-buffer "git-checkout") + (default-directory (file-truename spacemacs-start-directory))) + (prog1 + (eq 0 (process-file "git" nil proc-buffer nil + "checkout" branch)) + (kill-buffer proc-buffer)))) + +(defun spacemacs//git-get-current-branch () + "Return the current branch. Return nil if an error occurred." + (let ((proc-buffer "git-get-current-branch") + (default-directory (file-truename spacemacs-start-directory))) + (when (eq 0 (process-file "git" nil proc-buffer nil + "symbolic-ref" "--short" "-q" "HEAD")) + (with-current-buffer proc-buffer + (prog1 + (when (buffer-string) + (goto-char (point-min)) + (replace-regexp-in-string + "\n$" "" + (buffer-substring (line-beginning-position) + (line-end-position)))) + (kill-buffer proc-buffer)))))) + +(defun spacemacs//git-working-directory-dirty () + "Non-nil if the user's emacs directory is not clean. +Returns the output of git status --porcelain." + (let ((proc-buffer "git-working-directory-dirty") + (default-directory (file-truename spacemacs-start-directory))) + (when (eq 0 (process-file "git" nil proc-buffer nil + "status" "--porcelain")) + (with-current-buffer proc-buffer + (prog1 + (when (and (buffer-string) + ;;simplecheckforanytext + (string-match-p "[^ \t\n]" (buffer-string))) + (replace-regexp-in-string "\n\\'" "" (buffer-string))) + (kill-buffer proc-buffer)))))) + +(defun spacemacs//deffaces-new-version-lighter (state) + "Define a new version lighter face for the given STATE." + (let* ((fname (intern + (format "spacemacs-mode-line-new-version-lighter-%s-face" + (symbol-name state)))) + (foreground (face-foreground state))) + (eval `(defface ,fname '((t ())) + ,(format "Color for new version lighter in mode line (%s)." + (symbol-name state)) + :group 'spacemacs)) + (set-face-attribute fname nil + :foreground foreground + :box (face-attribute 'mode-line :box)))) + +(defun spacemacs//compute-version-score (version) + "Returns an integer from the version list. +Example: (1 42 3) = 1 042 003" + (let ((i -1)) + (cl-reduce '+ (mapcar (lambda (n) (setq i (1+ i)) (* n (expt 10 (* i 3)))) + (reverse version))))) + +(defun spacemacs/set-new-version-lighter-mode-line-faces () + "Define or set the new version lighter mode-line faces." + (mapcar 'spacemacs//deffaces-new-version-lighter + '(error warning success))) +(spacemacs/set-new-version-lighter-mode-line-faces) +(add-hook 'spacemacs-post-theme-change-hook + 'spacemacs/set-new-version-lighter-mode-line-faces) + +(provide 'core-release-management) diff --git a/core/core-spacemacs-buffer.el b/core/core-spacemacs-buffer.el new file mode 100644 index 0000000..5d11296 --- /dev/null +++ b/core/core-spacemacs-buffer.el @@ -0,0 +1,1024 @@ +;;; core-spacemacs-buffer.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(defconst spacemacs-buffer-version-info "0.200" + "Current version used to display addition release information.") + +(defconst spacemacs-buffer-name "*spacemacs*" + "The name of the spacemacs buffer.") + +(defconst spacemacs-buffer-logo-title "[S P A C E M A C S]" + "The title displayed beneath the logo.") + +(defconst spacemacs-buffer-buttons-startup-lists-offset 25 + "Relative position in characters of the home buffer buttons and the home + buffer startup lists.") + +(defconst spacemacs-buffer--banner-length 75 + "Width of a banner.") + +(defconst spacemacs-buffer--cache-file + (expand-file-name (concat spacemacs-cache-directory "spacemacs-buffer.el")) + "Cache file for various persistent data for the spacemacs startup buffer") + +(defvar spacemacs-buffer-startup-lists-length 20 + "Length used for startup lists with otherwise unspecified bounds. +Set to nil for unbounded.") + +(defvar spacemacs-buffer--release-note-version nil + "If nil the release note is displayed. If non nil it contains +a version number, if the version number is lesser than the current +version the release note it displayed") + +(defvar spacemacs-buffer--note-widgets nil + "List of widgets used to display the release note.") + +(defvar spacemacs-buffer--previous-insert-type nil + "Previous type of note inserted.") + +(defvar spacemacs-buffer--fresh-install + (not (file-exists-p dotspacemacs-filepath)) + "Non-nil if this Emacs instance if a fresh install.") + +(defvar spacemacs-buffer--buttons-position nil + "Offset in characters between the edge of the screen and the beginning of the + home buffer buttons. Do not set this variable.") + +(defvar spacemacs-buffer-mode-map + (let ((map (make-sparse-keymap))) + (define-key map [down-mouse-1] 'widget-button-click) + (define-key map (kbd "RET") 'widget-button-press) + + (define-key map [tab] 'widget-forward) + (define-key map (kbd "J") 'widget-forward) + (define-key map (kbd "C-i") 'widget-forward) + + (define-key map [backtab] 'widget-backward) + (define-key map (kbd "K") 'widget-backward) + + (define-key map (kbd "C-r") 'spacemacs-buffer/refresh) + (define-key map "q" 'quit-window) + map) + "Keymap for spacemacs buffer mode.") + +(with-eval-after-load 'evil + (evil-make-overriding-map spacemacs-buffer-mode-map 'motion)) + +(define-derived-mode spacemacs-buffer-mode fundamental-mode "Spacemacs buffer" + "Spacemacs major mode for startup screen. + +\\ +" + :group 'spacemacs + :syntax-table nil + :abbrev-table nil + (page-break-lines-mode) + (setq buffer-read-only t + truncate-lines t) + ;; needed to make tab work correctly in terminal + (evil-define-key 'motion spacemacs-buffer-mode-map + (kbd "C-i") 'widget-forward) + ;; motion state since this is a special mode + (evil-set-initial-state 'spacemacs-buffer-mode 'motion)) + +(defun spacemacs-buffer/insert-ascii-banner-centered (file) + (insert-string + (with-temp-buffer + (insert-file-contents file) + (let ((banner-width 0)) + (while (not (eobp)) + (let ((line-length (- (line-end-position) (line-beginning-position)))) + (if (< banner-width line-length) + (setq banner-width line-length))) + (forward-line 1)) + (goto-char 0) + (let ((margin (max 0 (floor (/ (- spacemacs-buffer--banner-length banner-width) 2))))) + (while (not (eobp)) + (insert (make-string margin ?\ )) + (forward-line 1)))) + (buffer-string)))) + +(defun spacemacs-buffer/insert-banner-and-buttons () + "Choose a banner according to `dotspacemacs-startup-banner'and insert it +in spacemacs buffer along with quick buttons underneath. + +Easter egg: +Doge special text banner can be reachable via `999', `doge' or `random*'. +Cate special text banner can de reachable via `998', `cat' or `random*'. +`random' ignore special banners whereas `random*' does not." + (let ((banner (spacemacs-buffer//choose-banner)) + (buffer-read-only nil)) + (progn + (when banner + (spacemacs-buffer/message (format "Banner: %s" banner)) + (if (image-type-available-p (intern (file-name-extension banner))) + (spacemacs-buffer//insert-image-banner banner) + (spacemacs-buffer/insert-ascii-banner-centered banner)) + (spacemacs-buffer//inject-version)) + (spacemacs-buffer//insert-buttons) + (spacemacs//redisplay)))) + +(defun spacemacs-buffer/display-info-box () + "Display an info box." + (when (file-exists-p spacemacs-buffer--cache-file) + (load spacemacs-buffer--cache-file)) + (cond + (spacemacs-buffer--fresh-install + ;; we assume the user is new to spacemacs and open the quickhelp + (spacemacs-buffer/toggle-note + (concat spacemacs-info-directory "quickhelp.txt") + (spacemacs-buffer//insert-note-p 'quickhelp)) + (setq spacemacs-buffer--release-note-version spacemacs-version) + (spacemacs/dump-vars-to-file '(spacemacs-buffer--release-note-version) + spacemacs-buffer--cache-file)) + ((or (not spacemacs-buffer--release-note-version) + (version< spacemacs-buffer--release-note-version + spacemacs-version)) + ;; check the variable ;; spacemacs-buffer--release-note-version + ;; to decide whether ;; we show the release note + (spacemacs-buffer/toggle-note + (concat spacemacs-release-notes-directory + spacemacs-buffer-version-info ".txt") 'release-note))) + (spacemacs//redisplay)) + +(defun spacemacs-buffer//choose-banner () + "Return the full path of a banner based on the dotfile value." + (when dotspacemacs-startup-banner + (cond ((eq 'official dotspacemacs-startup-banner) + (if (and (display-graphic-p) (image-type-available-p 'png)) + spacemacs-banner-official-png + (spacemacs-buffer//get-banner-path 1))) + ((eq 'random dotspacemacs-startup-banner) + (spacemacs-buffer//choose-random-text-banner)) + ((eq 'random* dotspacemacs-startup-banner) + (spacemacs-buffer//choose-random-text-banner t)) + ((eq 'doge dotspacemacs-startup-banner) + (spacemacs-buffer//get-banner-path 999)) + ((eq 'cat dotspacemacs-startup-banner) + (spacemacs-buffer//get-banner-path 998)) + ((integerp dotspacemacs-startup-banner) + (spacemacs-buffer//get-banner-path dotspacemacs-startup-banner)) + ((and dotspacemacs-startup-banner + (image-type-available-p (intern (file-name-extension + dotspacemacs-startup-banner))) + (display-graphic-p)) + (if (file-exists-p dotspacemacs-startup-banner) + dotspacemacs-startup-banner + (spacemacs-buffer/warning (format "could not find banner %s" + dotspacemacs-startup-banner)) + (spacemacs-buffer//get-banner-path 1))) + (t (spacemacs-buffer//get-banner-path 1))))) + +(defvar spacemacs-buffer--random-banner nil + "The random banner chosen.") + +(defun spacemacs-buffer//choose-random-text-banner (&optional all) + "Return the full path of a banner chosen randomly. + +If ALL is non-nil then truly all banners can be selected." + (setq spacemacs-buffer--random-banner + (or spacemacs-buffer--random-banner + (let* ((files (directory-files spacemacs-banner-directory t ".*\.txt")) + (count (length files)) + ;; -2 to remove the two last ones (easter eggs) + (choice (random (- count (if all 0 2))))) + (nth choice files))))) + +(defun spacemacs-buffer//get-banner-path (index) + "Return the full path to banner with index INDEX." + (concat spacemacs-banner-directory (format "%03d-banner.txt" index))) + +(defun spacemacs-buffer//insert-image-banner (banner) + "Display an image banner." + (when (file-exists-p banner) + (let* ((title spacemacs-buffer-logo-title) + (spec (create-image banner)) + (size (image-size spec)) + (width (car size)) + (left-margin (max 0 (floor (- spacemacs-buffer--banner-length width) 2)))) + (goto-char (point-min)) + (insert "\n") + (insert (make-string left-margin ?\ )) + (insert-image spec) + (insert "\n\n") + (insert (make-string (max 0 (floor (/ (- spacemacs-buffer--banner-length + (+ (length title) 1)) 2))) ?\ )) + (insert (format "%s\n\n" title))))) + +(defun spacemacs-buffer//inject-version () + "Inject the current version of spacemacs in the first line of the +buffer, right justified." + (with-current-buffer (get-buffer-create spacemacs-buffer-name) + (save-excursion + (let ((maxcol spacemacs-buffer--banner-length) + (version (format "%s@%s (%s)" + spacemacs-version + emacs-version + dotspacemacs-distribution)) + (buffer-read-only nil)) + (goto-char (point-min)) + (delete-region (point) (progn (end-of-line) (point))) + (insert (format (format "%%%ds" maxcol) version)))))) + +(defun spacemacs-buffer//insert-footer () + (save-excursion + (let* ((maxcol spacemacs-buffer--banner-length) + (badge-path spacemacs-badge-official-png) + (badge (when (and (display-graphic-p) + (image-type-available-p + (intern (file-name-extension badge-path)))) + (create-image badge-path))) + (badge-size (when badge (car (image-size badge)))) + (heart-path spacemacs-purple-heart-png) + (heart (when (and (display-graphic-p) + (image-type-available-p + (intern (file-name-extension badge-path)))) + (create-image heart-path))) + (heart-size (when heart (car (image-size heart)))) + (build-lhs "Made with ") + (build-rhs " by the community") + (buffer-read-only nil)) + (when (or badge heart) + (goto-char (point-max)) + (spacemacs-buffer/insert-page-break) + (insert "\n") + (when badge + (insert (make-string (floor (/ (- maxcol badge-size) 2)) ?\ )) + (insert-image badge)) + (when heart + (when badge (insert "\n\n")) + (insert (make-string (floor (/ (- maxcol + (length build-lhs) + heart-size + (length build-rhs)) 2)) ?\ )) + (insert build-lhs) + (insert-image heart) + (insert build-rhs) + (insert "\n")))))) + +(defun spacemacs-buffer//insert-note (file caption &optional additional-widgets) + "Insert the release note just under the banner. + +FILE is the file that contains the content to show. +CAPTION is the title of the note. +TAG-STRING is the label of the button for additional action. +HELP-STRING is the help message of the button for additional action." + (save-excursion + (goto-char (point-min)) + (search-forward "Search in Spacemacs\]") + (forward-line) + (let* ((note (concat "\n" (spacemacs//render-framed-text + file spacemacs-buffer--banner-length caption)))) + (add-to-list 'spacemacs-buffer--note-widgets (widget-create 'text note)) + (save-excursion + (while (re-search-backward "\\[\\[\\(.*\\)\\]\\]" nil t) + (let ((buffer-read-only nil)) + (make-text-button + (match-beginning 1) + (match-end 1) + 'type 'help-url + 'help-args (list (match-string 1)))))) + (funcall additional-widgets)))) + +(defun spacemacs-buffer//insert-note-p (type) + "Decicde if whether to insert note widget or not based on current note TYPE. + +If note TYPE is `quickhelp' or `release-note' and is equal to +previous insert type in `spacemacs-buffer--previous-insert-type', +which means previous note widget of the same type already +inserted. In this case, we simply delete the widgets but don't insert. + +Otherwise, delete and allow insert note of TYPE." + (if (not (eq spacemacs-buffer--previous-insert-type type)) + type + (setq spacemacs-buffer--previous-insert-type nil))) + +(defun spacemacs-buffer/toggle-note (file type) + "Toggle the note in FILE for the buffer based on TYPE. + +If TYPE is nil, just remove widgets." + (interactive) + (spacemacs-buffer//remove-existing-widget-if-exist) + (cond + ((eq type 'quickhelp) + (spacemacs-buffer//insert-quickhelp-widget file)) + ((eq type 'release-note) + (spacemacs-buffer//insert-release-note-widget file)) + (t))) + +(defun spacemacs-buffer//remove-existing-widget-if-exist () + "Remove existing note widgets if exists." + (when spacemacs-buffer--note-widgets + (spacemacs-buffer//remove-note-widgets))) + +(defun spacemacs-buffer//insert-quickhelp-widget (file) + "Insert quickhelp with content from FILE." + (spacemacs-buffer//remove-existing-widget-if-exist) + (let ((widget-func + (lambda () + (add-to-list + 'spacemacs-buffer--note-widgets + (widget-create 'push-button + :tag (propertize "Evil Tutorial" + 'face 'font-lock-keyword-face) + :help-echo + "Teach you how to use Vim basics." + :action (lambda (&rest ignore) + (call-interactively #'evil-tutor-start)) + :mouse-face 'highlight + :follow-link "\C-m")) + (widget-insert " ") + (add-to-list + 'spacemacs-buffer--note-widgets + (widget-create 'push-button + :tag (propertize "Emacs Tutorial" + 'face 'font-lock-keyword-face) + :help-echo "Teach you how to use Emacs basics." + :action (lambda (&rest ignore) + (call-interactively #'help-with-tutorial)) + :mouse-face 'highlight + :follow-link "\C-m")) + (widget-insert " ") + (add-to-list + 'spacemacs-buffer--note-widgets + (widget-create 'push-button + :tag (propertize "Vim Migration Guide" + 'face 'font-lock-keyword-face) + :help-echo "Documentation for former vim users." + :action (lambda (&rest ignore) + (spacemacs/view-org-file + (concat spacemacs-docs-directory + "VIMUSERS.org") "^" 'all)) + :mouse-face 'highlight + :follow-link "\C-m"))))) + (spacemacs-buffer//insert-note file "Quick Help" widget-func)) + (setq spacemacs-buffer--previous-insert-type 'quickhelp)) + +(defun spacemacs-buffer//insert-release-note-widget (file) + "Insert release note with content from FILE." + (spacemacs-buffer//remove-existing-widget-if-exist) + (let ((widget-func + (lambda () + (add-to-list + 'spacemacs-buffer--note-widgets + (widget-create 'push-button + :tag (propertize "Click here for full change log" + 'face 'font-lock-warning-face) + :help-echo "Open the full change log." + :action + (lambda (&rest ignore) + (funcall 'spacemacs/view-org-file + (concat spacemacs-start-directory + "CHANGELOG.org") + (format "Release %s.x" + spacemacs-buffer-version-info) + 'subtree)) + :mouse-face 'highlight + :follow-link "\C-m"))))) + (spacemacs-buffer//insert-note file + (format " Important Notes (Release %s.x) " + spacemacs-buffer-version-info) + widget-func)) + + (setq spacemacs-buffer--release-note-version nil) + (spacemacs/dump-vars-to-file + '(spacemacs-buffer--release-note-version) spacemacs-buffer--cache-file) + (setq spacemacs-buffer--previous-insert-type 'release-note)) + +(defun spacemacs-buffer//remove-note-widgets () + (mapc 'widget-delete spacemacs-buffer--note-widgets) + (setq spacemacs-buffer--note-widgets nil) + (setq spacemacs-buffer--release-note-version spacemacs-version) + (spacemacs/dump-vars-to-file + '(spacemacs-buffer--release-note-version) spacemacs-buffer--cache-file)) + +(defun spacemacs-buffer/set-mode-line (format) + "Set mode-line format for spacemacs buffer." + (with-current-buffer (get-buffer-create spacemacs-buffer-name) + (setq mode-line-format format))) + +(defun spacemacs-buffer/message (msg &rest args) + "Display MSG in message prepended with '(Spacemacs)'. +The message is displayed only if `init-file-debug' is non nil." + (when init-file-debug + (message "(Spacemacs) %s" (apply 'format msg args)))) + +(defvar spacemacs-buffer--warnings nil + "List of warnings during startup.") + +(defun spacemacs-buffer/warning (msg &rest args) + "Display MSG as a warning message but in buffer `*Messages*'. +The message is always displayed. " + (let ((msg (apply 'format msg args))) + (message "(Spacemacs) Warning: %s" msg) + (add-to-list 'spacemacs-buffer--warnings msg 'append))) + +(defun spacemacs-buffer/insert-page-break () + "Insert a page break line in spacemacs buffer." + (spacemacs-buffer/append "\n \n")) + +(defun spacemacs-buffer/append (msg &optional messagebuf) + "Append MSG to spacemacs buffer. If MESSAGEBUF is not nil then MSG is + also written in message buffer." + (with-current-buffer (get-buffer-create spacemacs-buffer-name) + (goto-char (point-max)) + (let ((buffer-read-only nil)) + (insert msg) + (if messagebuf (message "(Spacemacs) %s" msg))) + (spacemacs-buffer/set-mode-line ""))) + +(defun spacemacs-buffer/replace-last-line (msg &optional messagebuf) + "Replace the last line of the spacemacs buffer with MSG. If MESSAGEBUF is + not nil then MSG is also written in message buffer." + (with-current-buffer (get-buffer-create spacemacs-buffer-name) + (goto-char (point-max)) + (let ((buffer-read-only nil)) + (delete-region (line-beginning-position) (point-max)) + (insert msg) + (if messagebuf (message "(Spacemacs) %s" msg))) + (spacemacs-buffer/set-mode-line ""))) + +(defun spacemacs-buffer/insert-framed-text + (msg &optional caption hpadding) + "Insert MSG in spacemacs buffer within a frame of width FILL-COLUMN. + +See `spacemacs//render-framed-text' for documentation of the other +parameters." + (with-current-buffer (get-buffer-create spacemacs-buffer-name) + (let ((buffer-read-only nil)) + (insert (spacemacs//render-framed-text msg spacemacs-buffer--banner-length + caption hpadding))))) + +(defun spacemacs-buffer/insert-framed-text-from-file + (filepath &optional caption hpadding) + "Insert at point the content of FILENAME file in spacemacs buffer in a +frame. + +If FILEPATH does not exists the function returns nil. + +See `spacemacs//render-framed-text' for documentation of the other +parameters." + (when (file-exists-p filepath) + (with-current-buffer (get-buffer-create spacemacs-buffer-name) + (let ((buffer-read-only nil)) + (insert (spacemacs//render-framed-text + filepath spacemacs-buffer--banner-length caption hpadding)))))) + +(defun spacemacs//render-framed-text (content &optional width caption hpadding) + "Return a formated string framed with plained lines of width FILL-COLUMN. + +CONTENT can be a text or a filepath. + +WIDTH set the `fill-column' variable. + +If CAPTION is non nil string then it is included in at the top of the frame. +If CAPTION length is greater than FILL-COLUMN minus 5 the function returns +nil. + +HPADDING is the horizontal spacing between the text and the frame. +The vertical spacing is always one line." + (with-temp-buffer + (if (not (file-exists-p content)) + (insert content) + (insert-file-contents content) + ;; remove additional newline at eof + (goto-char (point-max)) + (delete-char -1)) + (let* ((hpadding (or hpadding 1)) + (fill-column (if width + (- width (+ 2 (* 2 hpadding))) + fill-column)) + (sentence-end-double-space nil) + (caption-len (length caption))) + (fill-region (point-min) (point-max) 'justify 'nosqueeze) + (concat + ;; top + "╭─" + (if caption + (concat caption + (make-string (max 0 (+ (- fill-column caption-len 1) + hpadding)) ?─)) + (make-string fill-column ?─)) + (make-string hpadding ?─) "╮\n" + ;; content + (spacemacs//render-framed-line "" hpadding) + (mapconcat (lambda (x) + (spacemacs//render-framed-line x hpadding)) + (split-string (buffer-string) "\n" nil) "") + (spacemacs//render-framed-line "" hpadding) + ;; bottom + "╰" (make-string hpadding ?─) + (make-string fill-column ?─) + (make-string hpadding ?─) "╯")))) + +(defun spacemacs//render-framed-line (line hpadding) + "Return a formated LINE with borders of a frame on each side and +with width FILL-COLUMN. + +If length of LINE is bigger than FILL-COLUMN it returns nil. + +HPADDING is the horizontal spacing betwee the content line and the frame +border." + (let* ((len (length line)) + (fill (- fill-column len))) + (when (>= fill 0) + (concat "│" (make-string hpadding ?\s) + line (make-string fill ?\s) + (make-string hpadding ?\s) "│\n")))) + +(defun spacemacs-buffer/loading-animation () + "Display the progress bar by chunk of size +`spacemacs--loading-dots-chunk-threshold'." + (when (and (not noninteractive) dotspacemacs-loading-progress-bar) + (setq spacemacs-loading-counter (1+ spacemacs-loading-counter)) + (setq spacemacs-loading-value (1+ spacemacs-loading-value)) + (when (>= spacemacs-loading-counter spacemacs-loading-dots-chunk-threshold) + (let ((suffix (format "> %s/%s" spacemacs-loading-value + (length configuration-layer--used-packages)))) + (setq spacemacs-loading-counter 0) + (setq spacemacs-loading-string + (make-string + (max 0 + (- (* spacemacs-loading-dots-chunk-size + (floor (/ spacemacs-loading-value + spacemacs-loading-dots-chunk-threshold))) + (length suffix))) + spacemacs-loading-char)) + (spacemacs-buffer/set-mode-line (concat spacemacs-loading-string + suffix))) + (spacemacs//redisplay)))) + +(defmacro spacemacs//insert--shortcut (shortcut-char search-label + &optional no-next-line) + `(define-key spacemacs-buffer-mode-map + ,shortcut-char (lambda () + (interactive) + (unless (search-forward ,search-label (point-max) t) + (search-backward ,search-label (point-min) t)) + ,@(unless no-next-line + '((forward-line 1))) + (back-to-indentation)))) + +(defun spacemacs-buffer//center-line () + (let* ((width (current-column)) + (margin (max 0 (floor (/ (- spacemacs-buffer--banner-length width) 2))))) + (beginning-of-line) + (insert (make-string margin ?\ )) + (end-of-line))) + +(defun spacemacs-buffer//insert-buttons () + (goto-char (point-max)) + (spacemacs//insert--shortcut "m" "[?]" t) + (widget-create 'url-link + :tag (propertize "?" 'face 'font-lock-doc-face) + :help-echo "Open the quickhelp." + :action (lambda (&rest ignore) + (spacemacs-buffer/toggle-note + (concat spacemacs-info-directory "quickhelp.txt") + ;; if nil is returned, + ;; just delete the current note widgets + (spacemacs-buffer//insert-note-p 'quickhelp))) + :mouse-face 'highlight + :follow-link "\C-m") + (insert " ") + (widget-create 'url-link + :tag (propertize "Homepage" 'face 'font-lock-keyword-face) + :help-echo "Open the Spacemacs Github page in your browser." + :mouse-face 'highlight + :follow-link "\C-m" + "http://spacemacs.org") + (insert " ") + (widget-create 'url-link + :tag (propertize "Documentation" 'face 'font-lock-keyword-face) + :help-echo "Open the Spacemacs documentation in your browser." + :mouse-face 'highlight + :follow-link "\C-m" + "http://spacemacs.org/doc/DOCUMENTATION.html") + (insert " ") + (widget-create 'url-link + :tag (propertize "Gitter Chat" 'face 'font-lock-keyword-face) + :help-echo + "Ask questions and chat with fellow users in our chat room." + :mouse-face 'highlight + :follow-link "\C-m" + "https://gitter.im/syl20bnr/spacemacs") + (insert " ") + (widget-create 'push-button + :help-echo "Update Spacemacs core and layers." + :action (lambda (&rest ignore) (spacemacs/switch-to-version)) + :mouse-face 'highlight + :follow-link "\C-m" + (propertize "Update Spacemacs" 'face 'font-lock-keyword-face)) + (let ((len (- (line-end-position) + (line-beginning-position)))) + (spacemacs-buffer//center-line) + (setq spacemacs-buffer--buttons-position (- (line-end-position) + (line-beginning-position) + len))) + (insert "\n") + (widget-create 'push-button + :help-echo "Update all ELPA packages to the latest versions." + :action (lambda (&rest ignore) + (configuration-layer/update-packages)) + :mouse-face 'highlight + :follow-link "\C-m" + (propertize "Update Packages" 'face 'font-lock-keyword-face)) + (insert " ") + (widget-create 'push-button + :help-echo + "Rollback ELPA package updates if something got borked." + :action (lambda (&rest ignore) + (call-interactively 'configuration-layer/rollback)) + :mouse-face 'highlight + :follow-link "\C-m" + (propertize "Rollback Package Update" + 'face 'font-lock-keyword-face)) + (spacemacs-buffer//center-line) + (insert "\n") + (widget-create 'push-button + :tag (propertize "Release Notes" + 'face 'font-lock-preprocessor-face) + :help-echo "Hide or show the Changelog" + :action (lambda (&rest ignore) + (spacemacs-buffer/toggle-note + (concat spacemacs-release-notes-directory + spacemacs-buffer-version-info + ".txt") + ;; if nil is returned, + ;; just delete the current note widgets + (spacemacs-buffer//insert-note-p 'release-note))) + :mouse-face 'highlight + :follow-link "\C-m") + (insert " ") + (widget-create 'url-link + :tag (propertize "Search in Spacemacs" + 'face 'font-lock-function-name-face) + :help-echo "Search Spacemacs contents." + :action + (lambda (&rest ignore) + (let ((comp-frontend + (cond + ((configuration-layer/layer-usedp 'helm) + 'helm-spacemacs-help) + ((configuration-layer/layer-usedp 'ivy) + 'ivy-spacemacs-help)))) + (call-interactively comp-frontend))) + :mouse-face 'highlight + :follow-link "\C-m") + (spacemacs-buffer//center-line) + (insert "\n\n")) + +(defun spacemacs-buffer//insert-string-list (list-display-name list) + (when (car list) + (insert list-display-name) + (mapc (lambda (el) + (insert + "\n" + (with-temp-buffer + (insert el) + (fill-paragraph) + (goto-char (point-min)) + (insert " - ") + (while (= 0 (forward-line)) + (insert " ")) + (buffer-string)))) + list))) + +(defun spacemacs-buffer//insert-file-list (list-display-name list) + (when (car list) + (insert list-display-name) + (mapc (lambda (el) + (insert "\n ") + (widget-create 'push-button + :action `(lambda (&rest ignore) + (find-file-existing ,el)) + :mouse-face 'highlight + :follow-link "\C-m" + :button-prefix "" + :button-suffix "" + :format "%[%t%]" + (abbreviate-file-name el))) + list))) + +(defun spacemacs-buffer//insert-bookmark-list (list-display-name list) + (when (car list) + (insert list-display-name) + (mapc (lambda (el) + (insert "\n ") + (let ((filename (bookmark-get-filename el))) + (widget-create 'push-button + :action `(lambda (&rest ignore) (bookmark-jump ,el)) + :mouse-face 'highlight + :follow-link "\C-m" + :button-prefix "" + :button-suffix "" + :format "%[%t%]" + (if filename + (format "%s - %s" + el (abbreviate-file-name filename)) + (format "%s" el))))) + list))) + +(defun spacemacs-buffer//get-org-items (types) + "Make a list of agenda file items for today of kind types" + (require 'org-agenda) + (let ((date (calendar-gregorian-from-absolute (org-today)))) + (apply #'append + (loop for file in (org-agenda-files nil 'ifmode) + collect + (spacemacs-buffer//make-org-items + file + (apply 'org-agenda-get-day-entries file date + types)))))) + +(defun spacemacs-buffer//agenda-list () + "Returns today's agenda" + (require 'org-agenda) + (spacemacs-buffer//get-org-items org-agenda-entry-types)) + +(defun spacemacs-buffer//todo-list () + "Returns current todos" + (require 'org-agenda) + (spacemacs-buffer//get-org-items '(:todo))) + +(defun spacemacs-buffer//make-org-items (file items) + "make a spacemacs-buffer org item list" + (loop + for item in items + collect + (spacemacs-buffer//make-org-item file item))) + +(defun spacemacs-buffer//make-org-item (file item) + "make a spacemacs-buffer version of an org item" + (list (cons "text" + (get-text-property 0 'txt item)) + (cons "file" file) + (cons "pos" + (marker-position + (get-text-property 0 'org-marker item))) + (cons "time" + (get-text-property 0 'time item)))) + +(defun spacemacs-buffer//org-jump (el) + (require 'org-agenda) + (find-file-other-window (cdr (assoc "file" el))) + (widen) + (goto-char (cdr (assoc "pos" el))) + (when (derived-mode-p 'org-mode) + (org-show-context 'agenda) + (save-excursion + (and (outline-next-heading) + (org-flag-heading nil))) ; show the next heading + (when (outline-invisible-p) + (outline-show-entry)) ; display invisible text + (recenter (/ (window-height) 2)) + (org-back-to-heading t) + (if (re-search-forward org-complex-heading-regexp nil t) + (goto-char (match-beginning 4)))) + (run-hooks 'org-agenda-after-show-hook)) + +(defun spacemacs-buffer//insert-todo-list (list-display-name list) + (when (car list) + (insert list-display-name) + (setq list (sort list + (lambda (a b) + (cond + ((eq "" (cdr (assoc "time" b))) + t) + ((eq "" (cdr (assoc "time" a))) + nil) + (t + (string< (cdr (assoc "time" a)) + (cdr (assoc "time" b)))))))) + (mapc (lambda (el) + (insert "\n ") + (widget-create 'push-button + :action `(lambda (&rest ignore) + (spacemacs-buffer//org-jump ',el)) + :mouse-face 'highlight + :follow-link "\C-m" + :button-prefix "" + :button-suffix "" + :format "%[%t%]" + (format "%s %s %s" + (abbreviate-file-name + (cdr (assoc "file" el))) + (if (not (eq "" (cdr (assoc "time" el)))) + (format "- %s -" + (cdr (assoc "time" el))) + "-") + (cdr (assoc "text" el))))) + list))) + +(defun spacemacs//subseq (seq start end) + "Use `cl-subseq`, but accounting for end points greater than the size of the +list. Return entire list if `END' is omitted." + (let ((len (length seq))) + (cl-subseq seq start (and (number-or-marker-p end) + (min len end))))) + +(defun spacemacs-buffer//do-insert-startupify-lists () + (let ((list-separator "\n\n")) + (mapc (lambda (els) + (let ((el (or (car-safe els) els)) + (list-size + (or (cdr-safe els) + spacemacs-buffer-startup-lists-length))) + (cond + ((eq el 'warnings) + (when (spacemacs-buffer//insert-string-list + "Warnings:" + spacemacs-buffer--warnings) + (spacemacs//insert--shortcut "w" "Warnings:") + (insert list-separator))) + ((eq el 'recents) + (recentf-mode) + (when (spacemacs-buffer//insert-file-list + "Recent Files:" + (spacemacs//subseq recentf-list 0 list-size)) + (spacemacs//insert--shortcut "r" "Recent Files:") + (insert list-separator))) + ((eq el 'todos) + (when (spacemacs-buffer//insert-todo-list + "ToDo:" + (spacemacs//subseq (spacemacs-buffer//todo-list) + 0 list-size)) + (spacemacs//insert--shortcut "d" "ToDo:") + (insert list-separator))) + ((eq el 'agenda) + (when (spacemacs-buffer//insert-todo-list + "Agenda:" + (spacemacs//subseq (spacemacs-buffer//agenda-list) + 0 list-size)) + (spacemacs//insert--shortcut "c" "Agenda:") + (insert list-separator))) + ((eq el 'bookmarks) + (when (configuration-layer/layer-usedp 'spacemacs-helm) + (helm-mode)) + (require 'bookmark) + (when (spacemacs-buffer//insert-bookmark-list + "Bookmarks:" + (spacemacs//subseq (bookmark-all-names) + 0 list-size)) + (spacemacs//insert--shortcut "b" "Bookmarks:") + (insert list-separator))) + ((and (eq el 'projects) + (fboundp 'projectile-mode)) + (projectile-mode) + (when (spacemacs-buffer//insert-file-list + "Projects:" + (spacemacs//subseq (projectile-relevant-known-projects) + 0 list-size)) + (spacemacs//insert--shortcut "p" "Projects:") + (insert list-separator)))))) + (append + '(warnings) + dotspacemacs-startup-lists)))) + +(defun spacemacs-buffer//get-buffer-width () + (save-excursion + (goto-char 0) + (let ((current-max 0)) + (while (not (eobp)) + (let ((line-length (- (line-end-position) (line-beginning-position)))) + (if (< current-max line-length) + (setq current-max line-length))) + (forward-line 1)) + current-max))) + +(defun spacemacs-buffer//center-startupify-lists () + (let* ((lists-width (spacemacs-buffer//get-buffer-width)) + (margin (max 0 (- spacemacs-buffer--buttons-position + spacemacs-buffer-buttons-startup-lists-offset))) + (final-padding (if (< spacemacs-buffer--banner-length (+ margin lists-width)) + (max 0 (floor (/ (- spacemacs-buffer--banner-length lists-width) 2))) + margin))) + (goto-char 0) + (while (not (eobp)) + (line-beginning-position) + (insert (make-string final-padding ?\ )) + (forward-line)))) + +(defun spacemacs-buffer/insert-startupify-lists () + (interactive) + (with-current-buffer (get-buffer spacemacs-buffer-name) + (let ((buffer-read-only nil)) + (goto-char (point-max)) + (spacemacs-buffer/insert-page-break) + (insert "\n") + (save-restriction + (narrow-to-region (point) (point)) + (spacemacs-buffer//do-insert-startupify-lists) + (spacemacs-buffer//center-startupify-lists))))) + +(defun spacemacs-buffer/goto-link-line () + "Set point to the beginning of the link line." + (interactive) + (with-current-buffer spacemacs-buffer-name + (goto-char (point-min)) + (with-demoted-errors "spacemacs buffer error: %s" + (widget-forward 1)))) + +(defun spacemacs-buffer//startup-hook () + "Code executed when Emacs has finished loading." + (with-current-buffer (get-buffer spacemacs-buffer-name) + (when dotspacemacs-startup-lists + (spacemacs-buffer/insert-startupify-lists)) + (spacemacs-buffer//insert-footer) + (if configuration-layer-error-count + (progn + (spacemacs-buffer-mode) + (spacemacs-buffer/set-mode-line + (format + (concat "%s error(s) at startup! " + "Spacemacs may not be able to operate properly.") + configuration-layer-error-count)) + (face-remap-add-relative 'mode-line + '((:background "red") mode-line))) + (spacemacs-buffer/set-mode-line spacemacs--default-mode-line) + (spacemacs-buffer-mode)) + (force-mode-line-update) + (spacemacs-buffer/goto-link-line))) + +(defvar spacemacs-buffer--last-width nil + "Previous width of spacemacs-buffer") + +(defun spacemacs-buffer/goto-buffer (&optional refresh) + "Create the special buffer for `spacemacs-buffer-mode' if it doesn't +already exist, and switch to it." + (interactive) + (let ((buffer-exists (buffer-live-p (get-buffer spacemacs-buffer-name))) + (save-line nil)) + (when (or (not (eq spacemacs-buffer--last-width (window-width))) + (not buffer-exists) + refresh) + (setq spacemacs-buffer--banner-length (window-width) + spacemacs-buffer--last-width spacemacs-buffer--banner-length) + (with-current-buffer (get-buffer-create spacemacs-buffer-name) + (page-break-lines-mode) + (save-excursion + (when (> (buffer-size) 0) + (set 'save-line (line-number-at-pos)) + (let ((inhibit-read-only t)) + (erase-buffer))) + (spacemacs-buffer/set-mode-line "") + ;; needed in case the buffer was deleted and we are recreating it + (setq spacemacs-buffer--note-widgets nil) + (spacemacs-buffer/insert-banner-and-buttons) + ;; non-nil if emacs-startup-hook was run + (if (bound-and-true-p spacemacs-initialized) + (progn + (configuration-layer/display-summary emacs-start-time) + (when dotspacemacs-startup-lists + (spacemacs-buffer/insert-startupify-lists)) + (spacemacs-buffer//insert-footer) + (spacemacs-buffer/set-mode-line spacemacs--default-mode-line) + (force-mode-line-update) + (spacemacs-buffer-mode)) + (add-hook 'emacs-startup-hook 'spacemacs-buffer//startup-hook t)))) + (if save-line + (progn (goto-char (point-min)) + (forward-line (1- save-line)) + (forward-to-indentation 0)) + (spacemacs-buffer/goto-link-line)) + (switch-to-buffer spacemacs-buffer-name) + (spacemacs//redisplay)))) + +(add-hook 'window-setup-hook + (lambda () + (add-hook 'window-configuration-change-hook 'spacemacs-buffer//resize-on-hook) + (spacemacs-buffer//resize-on-hook))) + +(defun spacemacs-buffer//resize-on-hook () + (let ((space-win (get-buffer-window spacemacs-buffer-name)) + (frame-win (frame-selected-window))) + (when (and dotspacemacs-startup-buffer-responsive + space-win + (not (window-minibuffer-p frame-win))) + (with-selected-window space-win + (spacemacs-buffer/goto-buffer))))) + +(defun spacemacs-buffer/refresh () + "Force recreation of the spacemacs buffer." + (interactive) + (setq spacemacs-buffer--last-width nil) + (spacemacs-buffer/goto-buffer t)) + +(defalias 'spacemacs/home 'spacemacs-buffer/refresh + "Go to home Spacemacs buffer") + +(defun spacemacs/home-delete-other-windows () + "Open home Spacemacs buffer and delete other windows. +Useful for making the home buffer the only visible buffer in the frame." + (interactive) + (spacemacs/home) + (delete-other-windows)) + +(provide 'core-spacemacs-buffer) diff --git a/core/core-spacemacs.el b/core/core-spacemacs.el new file mode 100644 index 0000000..0eaafc8 --- /dev/null +++ b/core/core-spacemacs.el @@ -0,0 +1,341 @@ +;;; core-spacemacs.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(setq message-log-max 16384) +(defconst emacs-start-time (current-time)) + +(require 'subr-x nil 'noerror) +(require 'page-break-lines) +(require 'core-debug) +(require 'core-command-line) +(require 'core-dotspacemacs) +(require 'core-release-management) +(require 'core-auto-completion) +(require 'core-jump) +(require 'core-display-init) +(require 'core-themes-support) +(require 'core-fonts-support) +(require 'core-spacemacs-buffer) +(require 'core-keybindings) +(require 'core-toggle) +(require 'core-funcs) +(require 'core-micro-state) +(require 'core-transient-state) +(require 'core-use-package-ext) + +(defgroup spacemacs nil + "Spacemacs customizations." + :group 'starter-kit + :prefix 'spacemacs-) + +;; loading progress bar variables +(defvar spacemacs-loading-char ?█) +(defvar spacemacs-loading-string "") +(defvar spacemacs-loading-counter 0) +(defvar spacemacs-loading-value 0) +;; (defvar spacemacs-loading-text "Loading") +;; (defvar spacemacs-loading-done-text "Ready!") +(defvar spacemacs-loading-dots-chunk-count 3) +(defvar spacemacs-loading-dots-count (window-total-size nil 'width)) +(defvar spacemacs-loading-dots-chunk-size + (/ spacemacs-loading-dots-count spacemacs-loading-dots-chunk-count)) +(defvar spacemacs-loading-dots-chunk-threshold 0) + +(defvar spacemacs-post-user-config-hook nil + "Hook run after dotspacemacs/user-config") +(defvar spacemacs-post-user-config-hook-run nil + "Whether `spacemacs-post-user-config-hook' has been run") + +(defvar spacemacs--default-mode-line mode-line-format + "Backup of default mode line format.") +(defvar spacemacs-initialized nil + "Whether or not spacemacs has finished initializing by completing +the final step of executing code in `emacs-startup-hook'.") + +(defun spacemacs/init () + "Perform startup initialization." + (when spacemacs-debugp (spacemacs/init-debug)) + ;; silence ad-handle-definition about advised functions getting redefined + (setq ad-redefinition-action 'accept) + ;; this is for a smoother UX at startup (i.e. less graphical glitches) + (hidden-mode-line-mode) + (spacemacs//removes-gui-elements) + ;; explicitly set the prefered coding systems to avoid annoying prompt + ;; from emacs (especially on Microsoft Windows) + (prefer-coding-system 'utf-8) + ;; TODO move these variables when evil is removed from the bootstrapped + ;; packages. + (setq-default evil-want-C-u-scroll t + ;; `evil-want-C-i-jump' is set to nil to avoid `TAB' being + ;; overlapped in terminal mode. The GUI specific `' is used + ;; instead. + evil-want-C-i-jump nil) + (dotspacemacs/load-file) + (require 'core-configuration-layer) + (dotspacemacs|call-func dotspacemacs/init "Calling dotfile init...") + (dotspacemacs|call-func dotspacemacs/user-init "Calling dotfile user init...") + (setq dotspacemacs-editing-style (dotspacemacs//read-editing-style-config + dotspacemacs-editing-style)) + (configuration-layer/initialize) + ;; default theme + (let ((default-theme (car dotspacemacs-themes))) + (spacemacs/load-theme default-theme) + ;; protect used themes from deletion as orphans + (setq configuration-layer--protected-packages + (append + (delq nil (mapcar 'spacemacs//get-theme-package + dotspacemacs-themes)) + configuration-layer--protected-packages)) + (setq-default spacemacs--cur-theme default-theme) + (setq-default spacemacs--cycle-themes (cdr dotspacemacs-themes))) + ;; font + (spacemacs|do-after-display-system-init + ;; If you are thinking to remove this call to `message', think twice. You'll + ;; break the life of several Spacemacser using Emacs in daemon mode. Without + ;; this, their chosen font will not be set on the *first* instance of + ;; emacsclient, at least if different than their system font. You don't + ;; believe me? Go ahead, try it. After you'll have notice that this was true, + ;; increase the counter bellow so next people will give it more confidence. + ;; Counter = 1 + (message "Setting the font...") + (unless (spacemacs/set-default-font dotspacemacs-default-font) + (spacemacs-buffer/warning + "Cannot find any of the specified fonts (%s)! Font settings may not be correct." + (if (listp (car dotspacemacs-default-font)) + (mapconcat 'car dotspacemacs-default-font ", ") + (car dotspacemacs-default-font))))) + ;; spacemacs init + (setq inhibit-startup-screen t) + (spacemacs-buffer/goto-buffer) + (unless (display-graphic-p) + ;; explicitly recreate the home buffer for the first GUI client + ;; in order to correctly display the logo + (spacemacs|do-after-display-system-init + (kill-buffer (get-buffer spacemacs-buffer-name)) + (spacemacs-buffer/goto-buffer))) + ;; This is set to nil during startup to allow Spacemacs to show buffers opened + ;; as command line arguments. + (setq initial-buffer-choice nil) + (setq inhibit-startup-screen t) + (require 'core-keybindings) + ;; for convenience and user support + (unless (fboundp 'tool-bar-mode) + (spacemacs-buffer/message (concat "No graphical support detected, " + "you won't be able to launch a " + "graphical instance of Emacs" + "with this build."))) + ;; check for new version + (if dotspacemacs-mode-line-unicode-symbols + (setq-default spacemacs-version-check-lighter "[⇪]"))) + +(defun spacemacs//removes-gui-elements () + "Remove the menu bar, tool bar and scroll bars." + ;; removes the GUI elements + (unless (spacemacs/window-system-is-mac) + (when (and (fboundp 'menu-bar-mode) (not (eq menu-bar-mode -1))) + (menu-bar-mode -1))) + (when (and (fboundp 'scroll-bar-mode) (not (eq scroll-bar-mode -1))) + (scroll-bar-mode -1)) + (when (and (fboundp 'tool-bar-mode) (not (eq tool-bar-mode -1))) + (tool-bar-mode -1)) + ;; tooltips in echo-aera + (when (and (fboundp 'tooltip-mode) (not (eq tooltip-mode -1))) + (tooltip-mode -1))) + +(defun spacemacs/maybe-install-dotfile () + "Install the dotfile if it does not exist." + (unless (file-exists-p dotspacemacs-filepath) + (spacemacs-buffer/set-mode-line "Dotfile wizard installer") + (spacemacs//redisplay) + (when (dotspacemacs/install 'with-wizard) + (configuration-layer/sync)))) + +(defun spacemacs/display-and-copy-version () + "Echo the current spacemacs version and copy it." + (interactive) + (let ((msg (format "Spacemacs v.%s" spacemacs-version))) + (message msg) (kill-new msg))) + +(defun display-startup-echo-area-message () + "Change the default welcome message of minibuffer to another one." + (message "Spacemacs is ready.")) + +(defun spacemacs/defer-until-after-user-config (func) + "Call FUNC if dotspacemacs/user-config has been called. Otherwise, +defer call using `spacemacs-post-user-config-hook'." + (if spacemacs-post-user-config-hook-run + (funcall func) + (add-hook 'spacemacs-post-user-config-hook func))) + +(defun spacemacs/setup-startup-hook () + "Add post init processing." + (add-hook + 'emacs-startup-hook + (lambda () + ;; This is set here so that emacsclient will show the startup buffer (and + ;; so that it can be changed in user-config if necessary). It was set to + ;; nil earlier in the startup process to properly handle command line + ;; arguments. + (setq initial-buffer-choice (lambda () (get-buffer spacemacs-buffer-name))) + ;; Ultimate configuration decisions are given to the user who can defined + ;; them in his/her ~/.spacemacs file + (dotspacemacs|call-func dotspacemacs/user-config + "Calling dotfile user config...") + (run-hooks 'spacemacs-post-user-config-hook) + (setq spacemacs-post-user-config-hook-run t) + (when (fboundp dotspacemacs-scratch-mode) + (with-current-buffer "*scratch*" + (funcall dotspacemacs-scratch-mode))) + (configuration-layer/display-summary emacs-start-time) + (spacemacs/check-for-new-version nil spacemacs-version-check-interval) + (setq spacemacs-initialized t)))) + +(defun spacemacs//describe-system-info-string () + "Gathers info about your Spacemacs setup and returns it as a string." + (format + (concat "#### System Info :computer:\n" + "- OS: %s\n" + "- Emacs: %s\n" + "- Spacemacs: %s\n" + "- Spacemacs branch: %s (rev. %s)\n" + "- Graphic display: %s\n" + "- Distribution: %s\n" + "- Editing style: %s\n" + "- Completion: %s\n" + "- Layers:\n```elisp\n%s```\n" + (when (version<= "25.1" emacs-version) + "- System configuration features: %s\n")) + system-type + emacs-version + spacemacs-version + (spacemacs//git-get-current-branch) + (spacemacs/git-get-current-branch-rev) + (display-graphic-p) + dotspacemacs-distribution + dotspacemacs-editing-style + (cond ((configuration-layer/layer-usedp 'helm) + 'helm) + ((configuration-layer/layer-usedp 'ivy) + 'ivy) + (t 'helm)) + (pp-to-string dotspacemacs--configuration-layers-saved) + (bound-and-true-p system-configuration-features))) + +(defun spacemacs/describe-system-info () + "Gathers info about your Spacemacs setup and copies to clipboard." + (interactive) + (let ((sysinfo (spacemacs//describe-system-info-string))) + (kill-new sysinfo) + (message sysinfo) + (message (concat "Information has been copied to clipboard.\n" + "You can paste it in the gitter chat.\n" + "Check the *Messages* buffer if you need to review it")))) + +(defun spacemacs//describe-last-keys-string () + "Gathers info about your Emacs last keys and returns it as a string." + (loop + for key + across (recent-keys) + collect (if (or (integerp key) (symbolp key) (listp key)) + (single-key-description key) + (prin1-to-string key)) + into keys + finally (return + (with-temp-buffer + (set-fill-column 60) + (insert (mapconcat 'identity keys " ")) + (fill-region (point-min) (point-max)) + (format "#### Emacs last keys :musical_keyboard: \n```text\n%s\n```\n" (buffer-string)))))) + +(defun spacemacs/describe-last-keys () + "Gathers info about your Emacs last keys and copies to clipboard." + (interactive) + (let ((lossage (spacemacs//describe-last-keys-string))) + (kill-new lossage) + (message lossage) + (message (concat "Information has been copied to clipboard.\n" + (propertize + "PLEASE REVIEW THE DATA BEFORE GOING FURTHER AS IT CAN CONTAIN SENSITIVE DATA (PASSWORD, ...)\n" + 'face 'font-lock-warning-face) + "You can paste it in the gitter chat.\n" + "Check the *Messages* buffer if you need to review it")))) + +(defun spacemacs/report-issue (arg) + "Open a spacemacs/report-issue-mode buffer prepopulated with + issue report template and system information. + + With prefix arg,include the last keys pressed." + (interactive "P") + (let ((buf + (generate-new-buffer "REPORT_SPACEMACS_ISSUE")) + (system-info + (spacemacs//describe-system-info-string)) + (backtrace + (if (get-buffer "*Backtrace*") + (with-current-buffer "*Backtrace*" + (buffer-substring-no-properties + (point-min) + (min (point-max) 1000))) + "<>")) + (last-keys + (if (and arg (y-or-n-p (concat "Do you really want to " + "include your last pressed keys? It " + "may include some sensitive data."))) + (concat (spacemacs//describe-last-keys-string) "\n") + ""))) + (switch-to-buffer buf) + (insert-file-contents-literally + (concat configuration-layer-template-directory "REPORTING.template")) + (loop + for (placeholder replacement) + in '(("%SYSTEM_INFO%" system-info) + ("%BACKTRACE%" backtrace) + ("(%LAST_KEYS%)\n" last-keys)) + do (save-excursion + (goto-char (point-min)) + (search-forward placeholder) + (replace-match (symbol-value replacement) [keep-case] [literal]))) + (spacemacs/report-issue-mode))) + +(define-derived-mode spacemacs/report-issue-mode markdown-mode "Report-Issue" + "Major mode for reporting issues with Spacemacs. + +When done editing, you can type \\[spacemacs//report-issue-done] to create the +issue on Github. You must be logged in already for this to work. After you see +that the issue has been created successfully, you can close this buffer. + +Markdown syntax is supported in this buffer. + +\\{spacemacs/report-issue-mode-map} +" + (font-lock-add-keywords 'spacemacs/report-issue-mode + '(("\\(<<.*?>>\\)" . 'font-lock-comment-face)))) + +(define-key spacemacs/report-issue-mode-map + (kbd "C-c C-c") 'spacemacs//report-issue-done) +(define-key spacemacs/report-issue-mode-map + (kbd "C-c C-k") 'kill-buffer) + +(with-eval-after-load 'bind-map + (spacemacs/set-leader-keys-for-major-mode 'spacemacs/report-issue-mode + "," 'spacemacs//report-issue-done + "c" 'spacemacs//report-issue-done + "a" 'kill-buffer + "k" 'kill-buffer)) + +(defun spacemacs//report-issue-done () + (interactive) + (let ((url "http://github.com/syl20bnr/spacemacs/issues/new?body=")) + (setq url (url-encode-url (concat url (buffer-string)))) + ;; HACK: Needed because the first `#' is not encoded + (setq url (replace-regexp-in-string "#" "%23" url)) + (browse-url url))) + +(provide 'core-spacemacs) diff --git a/core/core-themes-support.el b/core/core-themes-support.el new file mode 100644 index 0000000..8ce8182 --- /dev/null +++ b/core/core-themes-support.el @@ -0,0 +1,230 @@ +;;; core-themes-support.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defconst emacs-built-in-themes (cons 'default (custom-available-themes)) + "List of emacs built-in themes") + +(defface org-kbd + '((t (:background "LemonChiffon1" :foreground "black" :box + (:line-width 2 :color nil :style released-button)))) + "Face for displaying key bindings in Spacemacs documents." + :group 'org-faces) + +(defconst spacemacs-theme-name-to-package + '( + (alect-black-alt . alect-themes) + (alect-black . alect-themes) + (alect-dark-alt . alect-themes) + (alect-dark . alect-themes) + (alect-light-alt . alect-themes) + (alect-light . alect-themes) + (ample-light . ample-theme) + (ample-flat . ample-theme) + (apropospriate-light . apropospriate-theme) + (apropospriate-dark . apropospriate-theme) + (base16-3024 . base16-theme) + (base16-apathy . base16-theme) + (base16-ashes . base16-theme) + (base16-atelier-cave . base16-theme) + (base16-atelier-dune . base16-theme) + (base16-atelier-estuary . base16-theme) + (base16-atelier-forest . base16-theme) + (base16-atelier-heath . base16-theme) + (base16-atelier-lakeside . base16-theme) + (base16-atelier-plateau . base16-theme) + (base16-atelier-savanna . base16-theme) + (base16-atelier-seaside . base16-theme) + (base16-atelier-sulphurpool . base16-theme) + (base16-bespin . base16-theme) + (base16-brewer . base16-theme) + (base16-bright . base16-theme) + (base16-chalk . base16-theme) + (base16-codeschool . base16-theme) + (base16-darktooth . base16-theme) + (base16-default-dark . base16-theme) + (base16-default-light . base16-theme) + (base16-eighties . base16-theme) + (base16-embers . base16-theme) + (base16-flat . base16-theme) + (base16-github . base16-theme) + (base16-google-dark . base16-theme) + (base16-google-light . base16-theme) + (base16-grayscale-dark . base16-theme) + (base16-grayscale-light . base16-theme) + (base16-green-screen . base16-theme) + (base16-harmonic16-dark . base16-theme) + (base16-harmonic16-light . base16-theme) + (base16-hopscotch . base16-theme) + (base16-ir-black . base16-theme) + (base16-isotope . base16-theme) + (base16-london-tube . base16-theme) + (base16-macintosh . base16-theme) + (base16-marrakesh . base16-theme) + (base16-mocha . base16-theme) + (base16-monokai . base16-theme) + (base16-ocean . base16-theme) + (base16-oceanicnext . base16-theme) + (base16-paraiso . base16-theme) + (base16-phd . base16-theme) + (base16-pico . base16-theme) + (base16-pop . base16-theme) + (base16-railscasts . base16-theme) + (base16-seti-ui . base16-theme) + (base16-shapeshifter . base16-theme) + (base16-solar-flare . base16-theme) + (base16-solarized-dark . base16-theme) + (base16-solarized-light . base16-theme) + (base16-summerfruit-dark . base16-theme) + (base16-summerfruit-light . base16-theme) + (base16-tomorrow-night . base16-theme) + (base16-tomorrow . base16-theme) + (base16-twilight . base16-theme) + (base16-unikitty-dark . base16-theme) + (base16-unikitty-light . base16-theme) + (sanityinc-solarized-dark . color-theme-sanityinc-solarized) + (sanityinc-solarized-light . color-theme-sanityinc-solarized) + (sanityinc-tomorrow-blue . color-theme-sanityinc-tomorrow) + (sanityinc-tomorrow-bright . color-theme-sanityinc-tomorrow) + (sanityinc-tomorrow-day . color-theme-sanityinc-tomorrow) + (sanityinc-tomorrow-eighties . color-theme-sanityinc-tomorrow) + (sanityinc-tomorrow-night . color-theme-sanityinc-tomorrow) + (doom-one . doom-themes) + (doom-molokai . doom-themes) + (solarized-light . solarized-theme) + (solarized-dark . solarized-theme) + (spacemacs-light . spacemacs-theme) + (spacemacs-dark . spacemacs-theme) + (colorsarenice-dark . colorsarenice-theme) + (colorsarenice-light . colorsarenice-theme) + (hemisu-dark . hemisu-theme) + (hemisu-light . hemisu-theme) + (majapahit-dark . majapahit-theme) + (majapahit-light . majapahit-theme) + (material-light . material-theme) + (minimal-light . minimal-theme) + (moe-dark . moe-theme) + (moe-light . moe-theme) + (stekene-dark . stekene-theme) + (stekene-light . stekene-theme) + (brin . sublime-themes) + (dorsey . sublime-themes) + (fogus . sublime-themes) + (graham . sublime-themes) + (granger . sublime-themes) + (hickey . sublime-themes) + (junio . sublime-themes) + (mccarthy . sublime-themes) + (odersky . sublime-themes) + (omtose-darker . omtose-phellack-theme) + (omtose-softer . omtose-phellack-theme) + (ritchie . sublime-themes) + (spolsky . sublime-themes) + (wilson . sublime-themes) + (zonokai-blue . zonokai-theme) + (zonokai-red . zonokai-theme) + (tao-yin . tao-theme) + (tao-yang . tao-theme) + (farmhouse-light . farmhouse-theme) + (farmhouse-dark . farmhouse-theme) + ) + "alist matching a theme name with its package name, required when +package name does not match theme name + `-theme' suffix.") + +(defvar spacemacs-post-theme-change-hook nil + "Hook run after theme has changed.") + +(defun spacemacs//get-theme-package (theme) + "Returns the package theme for the given THEME name." + (cond + ;; built-in + ((memq theme emacs-built-in-themes) nil) + ;; from explicit alist + ((assq theme spacemacs-theme-name-to-package) + (cdr (assq theme spacemacs-theme-name-to-package))) + ;; fallback to -theme + (t (intern (format "%S-theme" theme))))) + +(defun spacemacs/load-theme (theme) + "Load THEME." + ;; Required dependencies for some themes + (condition-case-unless-debug err + (progn + (when (or (eq 'zonokai-blue theme) + (eq 'zonokai-red theme) + (eq 'solarized-light theme) + (eq 'solarized-dark theme)) + (configuration-layer/load-or-install-package 'dash)) + ;; Unless Emacs stock themes + (unless (or (memq theme (custom-available-themes)) + (eq 'default theme)) + (cond + ;; themes with explicitly declared package names + ((assq theme spacemacs-theme-name-to-package) + (let* ((pkg (spacemacs//get-theme-package theme)) + (pkg-dir (configuration-layer/load-or-install-package pkg))) + (when (or (eq 'moe-light theme) + (eq 'moe-dark theme)) + (load-file (concat pkg-dir "moe-light-theme.el")) + (load-file (concat pkg-dir "moe-dark-theme.el"))) + (add-to-list 'custom-theme-load-path pkg-dir))) + (t + ;; other themes + ;; we assume that the package name is suffixed with `-theme' + ;; if not we will handle the special themes as we get issues + ;; in the tracker. + (let ((pkg (spacemacs//get-theme-package theme))) + (configuration-layer/load-or-install-package pkg)))))) + ('error + (setq theme 'default) + (display-warning 'spacemacs + (format (concat "An error occurred while retrieving the " + "theme, using default theme. (error: %s)") + err) + :warning))) + (mapc 'disable-theme custom-enabled-themes) + (if (eq 'default theme) + (progn + (setq spacemacs--cur-theme 'default) + (spacemacs/post-theme-init 'default)) + (load-theme theme t) + ;; explicitly reload the theme for the first GUI client + (eval `(spacemacs|do-after-display-system-init + (load-theme ',theme t))))) + +(defun spacemacs/cycle-spacemacs-theme () + "Cycle through themes defined in `dotspacemacs-themes.'" + (interactive) + (when spacemacs--cur-theme + (disable-theme spacemacs--cur-theme) + ;; if current theme isn't in cycleable themes, start over + (setq spacemacs--cycle-themes + (or (cdr (memq spacemacs--cur-theme dotspacemacs-themes)) + dotspacemacs-themes))) + (setq spacemacs--cur-theme (pop spacemacs--cycle-themes)) + (message "Loading theme %s..." spacemacs--cur-theme) + (spacemacs/load-theme spacemacs--cur-theme)) + +(defadvice load-theme (after spacemacs/load-theme-adv activate) + "Perform post load processing." + (let ((theme (ad-get-arg 0))) + ;; Without this a popup is raised every time emacs25 starts up for + ;; assignment to a free variable + (with-no-warnings + (setq spacemacs--cur-theme theme)) + (spacemacs/post-theme-init theme))) + +(defun spacemacs/post-theme-init (theme) + "Some processing that needs to be done when the current theme +has been changed to THEME." + (interactive) + (run-hooks 'spacemacs-post-theme-change-hook)) + +(provide 'core-themes-support) diff --git a/core/core-toggle.el b/core/core-toggle.el new file mode 100644 index 0000000..e3f88dc --- /dev/null +++ b/core/core-toggle.el @@ -0,0 +1,113 @@ +;;; core-toggle.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(require 'core-funcs) + +(defvar spacemacs-toggles '() + "List of all declared toggles. The structure of an element is a +property list (name :func FUNCTION :doc STRING :key STRING).") + +(defmacro spacemacs|add-toggle (name &rest props) + "Add a toggle with NAME symbol. + +This macro creates the following functions: +- spacemacs/toggle-NAME switches on or off depending on the current state +- spacemacs/toggle-NAME-on only switches on if currently disabled +- spacemacs/toggle-NAME-off only switches off if currently enabled + +Avaiblabe PROPS: + +`:status EXPRESSION' + The EXPRESSION to evaluate to get the current status of the toggle. + +`:if EXPRESSION' + If this EXPRESSION evaluate to nil then no attempt to update the toggle + status will be performed. + +`:on BODY' + Evaluate BODY when the toggle is switched on. + +`:off BODY' + Evaluate BODY when the toggle is switched off. + +`:documentation STRING' + STRING describes what the toggle does. + +`:prefix SYMBOL' + SYMBOL is bound to the raw value of prefix-arg (same as calling + (interactive \"P\")) in the wrapper function. + +`:on-message EXPRESSION' + EXPRESSION is evaluated and displayed when the \"on\" toggle is activated. + +`:mode SYMBOL' + If given, must be a minor mode. This overrides `:on', `:off' and `:status'. + +All properties supported by `spacemacs//create-key-binding-form' can be +used." + (declare (indent 1)) + (let* ((wrapper-func (intern (format "spacemacs/toggle-%s" + (symbol-name name)))) + (wrapper-func-status (intern (format "%s-p" wrapper-func))) + (wrapper-func-on (intern (format "%s-on" wrapper-func))) + (wrapper-func-off (intern (format "%s-off" wrapper-func))) + (mode (plist-get props :mode)) + (status (or mode (plist-get props :status))) + (condition (plist-get props :if)) + (doc (plist-get props :documentation)) + (on-body (if mode `((,mode)) (spacemacs/mplist-get props :on))) + (off-body (if mode `((,mode -1)) (spacemacs/mplist-get props :off))) + (prefix-arg-var (plist-get props :prefix)) + (on-message (plist-get props :on-message)) + (bindkeys (spacemacs//create-key-binding-form props wrapper-func)) + ;; we evaluate condition and status only if they are a list or + ;; a bound symbol + (status-eval `(and (or (and (symbolp ',status) (boundp ',status)) + (listp ',status)) + ,status))) + `(progn + (push (append '(,name) '(:function ,wrapper-func + :predicate ,wrapper-func-status) ',props) + spacemacs-toggles) + ;; toggle function + (defun ,wrapper-func ,(if prefix-arg-var (list prefix-arg-var) ()) + ,(format "Toggle %s on and off." (symbol-name name)) + ,(if prefix-arg-var '(interactive "P") '(interactive)) + (if (or (null ',condition) + (and (or (and (symbolp ',condition) (boundp ',condition)) + (listp ',condition)) + ,condition)) + (if (,wrapper-func-status) + (progn ,@off-body + (when (called-interactively-p 'any) + (message ,(format "%s disabled." name)))) + ,@on-body + (when (called-interactively-p 'any) + (message ,(or on-message (format "%s enabled." name))))) + (message "This toggle is not supported."))) + ;; predicate function + (defun ,wrapper-func-status () + ,(format "Check if %s is on." (symbol-name name)) + ,status-eval) + ;; Only define on- or off-functions when status is available + ,@(when status + ;; on-function + `((defun ,wrapper-func-on () + ,(format "Toggle %s on." (symbol-name name)) + (interactive) + (unless (,wrapper-func-status) (,wrapper-func))) + ;; off-function + (defun ,wrapper-func-off () + ,(format "Toggle %s off." (symbol-name name)) + (interactive) + (when (,wrapper-func-status) (,wrapper-func))))) + ,@bindkeys))) + +(provide 'core-toggle) diff --git a/core/core-transient-state.el b/core/core-transient-state.el new file mode 100644 index 0000000..5e572a0 --- /dev/null +++ b/core/core-transient-state.el @@ -0,0 +1,193 @@ +;;; -*- lexical-binding: t -*- +;;; core-transient-state.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Justin Burkett +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spacemacs//transient-state-func-name (name) + "Return the name of the transient state function." + (intern (format "spacemacs/%S-transient-state" name))) + +(defun spacemacs//transient-state-props-var-name (name) + "Return the name of the variable use to store the transient state properties." + (intern (format "spacemacs--%S-transient-state-props" name))) + +(defun spacemacs//transient-state-body-func-name (name) + "Return the name of the transient state function." + (intern (format "spacemacs/%S-transient-state/body" name))) + +(defun spacemacs//transient-state-heads-name (name) + "Return the name of the transient state heads variable which +holds the key bindings." + (intern (format "spacemacs/%S-transient-state/heads" name))) + +(defun spacemacs//transient-state-adjust-bindings (bindings to-remove to-add) + (append + (cl-remove-if + (lambda (bnd) + (and (boundp to-remove) + (listp (symbol-value to-remove)) + (member (car bnd) (symbol-value to-remove)))) + bindings) + (when (and (boundp to-add) + (listp (symbol-value to-add))) + (symbol-value to-add)))) + +(defun spacemacs//transient-state-make-doc + (transient-state docstring &optional body) + "Use `hydra' internal function to format and apply DOCSTRING." + (let ((heads (spacemacs//transient-state-heads-name transient-state))) + (setq body (if body body '(nil nil :hint nil :foreign-keys nil))) + (eval + (hydra--format nil body docstring (symbol-value heads))))) + +(defmacro spacemacs|transient-state-format-hint (name var hint) + "Format HINT and store the result in VAR for transient state NAME." + (declare (indent 1)) + `(add-hook 'spacemacs-post-user-config-hook + (lambda () + (let* ((props-var ,(spacemacs//transient-state-props-var-name + name)) + (prop-hint (cadr (assq 'hint props-var))) + (prop-columns (cadr (assq 'columns props-var))) + (prop-foreign-keys (cadr (assq 'foreign-keys props-var))) + (prop-entry-sexp (cadr (assq 'entry-sexp props-var))) + (prop-exit-sexp (cadr (assq 'exit-sexp props-var)))) + (setq ,var (spacemacs//transient-state-make-doc + ',name + ,hint + `(nil + nil + :hint ,prop-hint + :columns ,prop-columns + :foreign-keys ,prop-foreign-keys + :body-pre ,prop-entry-sexp + :before-exit ,prop-exit-sexp))) + 'append)))) + +(defface spacemacs-transient-state-title-face + `((t :inherit mode-line)) + "Face for title of transient states.") + +(defmacro spacemacs|define-transient-state (name &rest props) + "Define a transient state called NAME. +NAME is a symbol. +Available PROPS: +`:on-enter SEXP' + Evaluate SEXP when the transient state is switched on. +`:on-exit SEXP' + Evaluate SEXP when leaving the transient state. +`:doc STRING or SEXP' + A docstring supported by `defhydra'. +`:additional-docs cons cells (VARIABLE . STRING)' + Additional docstrings to format and store in the corresponding VARIABLE. + This can be used to dynamically change the docstring. +`:title STRING' + Provide a title in the header of the transient state +`:columns INTEGER' + Automatically generate :doc with this many number of columns. +`:hint BOOLEAN' + Whether to display hints. Default is nil. +`:hint-is-doc BOOLEAN' + Whether the hints act as a documentation, the only effect of this value is + to change where the hints are displayed. If non-nil the hints are displayed + on the same line as the `:title', otherwise they are displayed below it. + Default is nil. +`:dynamic-hint SEXP' + An sexp evaluating to a string for dynamic hinting. + When provided `:hint' has no effect. Default is nil. +`:foreign-keys SYMBOL' + What to do when keys not bound in the transient state are entered. This + can be nil (default), which means to exit the transient state, warn, + which means to not exit but warn the user that the key is not part + of the transient state, or run, which means to try to run the key binding + without exiting. +`:bindings EXPRESSIONS' + One or several EXPRESSIONS with the form + (STRING1 SYMBOL1 DOCSTRING + :exit SYMBOL) + where: + - STRING1 is a key to be bound to the function or key map SYMBOL1. + - DOCSTRING is a STRING or an SEXP that evaluates to a string + - :exit SYMBOL or SEXP, if non nil then pressing this key will + leave the transient state (default is nil). + Important note: due to inner working of transient-maps in Emacs + the `:exit' keyword is evaluate *before* the actual execution + of the bound command. +All properties supported by `spacemacs//create-key-binding-form' can be +used." + (declare (indent 1)) + (let* ((func (spacemacs//transient-state-func-name name)) + (props-var (spacemacs//transient-state-props-var-name name)) + (body-func (spacemacs//transient-state-body-func-name name)) + (add-bindings + (intern (format "spacemacs-%s-transient-state-add-bindings" name))) + (remove-bindings + (intern (format "spacemacs-%s-transient-state-remove-bindings" name))) + (bindings (spacemacs/mplist-get props :bindings)) + (doc (or (plist-get props :doc) "\n")) + (title (plist-get props :title)) + (hint-var (intern (format "%s/hint" func))) + (columns (plist-get props :columns)) + (entry-sexp (plist-get props :on-enter)) + (exit-sexp (plist-get props :on-exit)) + (hint (plist-get props :hint)) + (hint-doc-p (plist-get props :hint-is-doc)) + (dyn-hint (plist-get props :dynamic-hint)) + (additional-docs (spacemacs/mplist-get props :additional-docs)) + (foreign-keys (plist-get props :foreign-keys)) + (bindkeys (spacemacs//create-key-binding-form props body-func))) + `(progn + (defvar ,props-var nil + ,(format (concat "Association list containing a copy of some " + "properties of the transient state %S. Those " + "properties are used in macro " + "`spacemacs|transient-state-format-hint'.") name)) + (add-to-list ',props-var '(hint ,hint)) + (add-to-list ',props-var '(columns ,columns)) + (add-to-list ',props-var '(foreign-keys ,foreign-keys)) + (add-to-list ',props-var '(entry-sexp ,entry-sexp)) + (add-to-list ',props-var '(exit-sexp ,exit-sexp)) + (spacemacs/defer-until-after-user-config + '(lambda () + (eval + (append + '(defhydra ,func + (nil nil + :hint ,hint + :columns ,columns + :foreign-keys ,foreign-keys + :body-pre ,entry-sexp + :before-exit ,exit-sexp) + ,doc) + (spacemacs//transient-state-adjust-bindings + ',bindings ',remove-bindings ',add-bindings))) + (when ,title + (let ((guide (concat "[" (propertize "KEY" 'face 'hydra-face-blue) + "] exits state [" + (if ',foreign-keys + (propertize "KEY" 'face 'hydra-face-pink) + (propertize "KEY" 'face 'hydra-face-red)) + "] will not exit"))) + ;; (add-face-text-property 0 (length guide) '(:height 0.9) t guide) + (add-face-text-property 0 (length guide) 'italic t guide) + (setq ,hint-var + (list 'concat + (when dotspacemacs-show-transient-state-title + (concat + (propertize + ,title + 'face 'spacemacs-transient-state-title-face) + (if ,hint-doc-p " " "\n"))) ,hint-var + ',dyn-hint + (when dotspacemacs-show-transient-state-color-guide + (concat "\n" guide)))))) + ,@bindkeys))))) + +(provide 'core-transient-state) diff --git a/core/core-use-package-ext.el b/core/core-use-package-ext.el new file mode 100644 index 0000000..f9c7040 --- /dev/null +++ b/core/core-use-package-ext.el @@ -0,0 +1,50 @@ +;;; core-use-package-ext.el --- Spacemacs Core File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(defconst spacemacs--use-package-add-hook-keywords '(:pre-init + :post-init + :pre-config + :post-config)) + +(defmacro spacemacs|use-package-add-hook (name &rest plist) + "Add post hooks to `:init' or `:config' arguments of an existing +configuration. + +In order to use this macro the variable `use-package-inject-hooks' +must be non-nil. + +This is useful in the dotfile to override the default configuration +of a package. + +Usage: + + (spacemacs|use-package-add-hook package-name + [:keyword [option]]...) + +:pre-init Code to run before the default `:init' configuration. +:post-init Code to run after the default `:init' configuration. +:pre-config Code to run before the default `:config' configuration. +:post-config Code to run after the default `:config' configuration. + +In practice the most useful hook is the `:post-config' where you can +override lazy-loaded settings." + (declare (indent 1)) + (let ((name-symbol (if (stringp name) (intern name) name)) + (expanded-forms '())) + (dolist (keyword spacemacs--use-package-add-hook-keywords) + (let ((body (spacemacs/mplist-get plist keyword))) + (when body + (let ((hook (intern (format "use-package--%S--%s-hook" + name-symbol + (substring (format "%s" keyword) 1))))) + (push `(add-hook ',hook (lambda nil ,@body)) expanded-forms))))) + `(progn ,@expanded-forms))) + +(provide 'core-use-package-ext) diff --git a/core/info/quickhelp.txt b/core/info/quickhelp.txt new file mode 100644 index 0000000..0591722 --- /dev/null +++ b/core/info/quickhelp.txt @@ -0,0 +1,28 @@ +Press [TAB] or [J] to move to next button. + +Press [Shift-TAB] or [K] to move to previous button. + +Press [r] to jump to recent file list if it is enabled. + +Press [p] to jump to project list if it is enabled. + +Press [b] to jump to bookmark list if it is enabled. + +Press [o] to jump to any link or button. + +Press [m] to jump to the top menu. + +Press [SPC] (in Vim editing style) or [Alt-m] (in Emacs editing style) to access +Spacemacs commands (will list only the Vim style ones for the rest of this +help). + +Press [SPC f e d] (or [Alt-m f e d] in Emacs style) to access .spacemacs file. + +Press [SPC h SPC] to access a list of documentation and supported layers. You +can type anything to narrow to a specific feature i.e. "python" for Python +layer. There are multiple lists and you can press [Ctrl-o] to switch between +them. + +When reading a document, you can use [SPC s j] to jump to a heading. + +Please consult Spacemacs documentation from [SPC h SPC] for more details. diff --git a/core/info/release-notes/0.101.txt b/core/info/release-notes/0.101.txt new file mode 100644 index 0000000..be5f02a --- /dev/null +++ b/core/info/release-notes/0.101.txt @@ -0,0 +1,10 @@ +New layers: +company-mode layer has been replaced by the new layer auto-completion. +Org packages have been moved to the new layer org. +Flycheck has been moved to the new layer syntax-checking. +Be sure to update your dotfile to add these layers. + +Init functions: +The init function /init- is now mandatory. Any package +without an explicit init function will be ignored and uninstalled by +Spacemacs. diff --git a/core/info/release-notes/0.102.txt b/core/info/release-notes/0.102.txt new file mode 100644 index 0000000..1305f63 --- /dev/null +++ b/core/info/release-notes/0.102.txt @@ -0,0 +1,34 @@ +1. Dotfile + +It is now possible to reload the dotfile and layers anywhere with `SPC f e +R`. This key binding *replaces* the old `C-c C-c` and `SPC m c c` only +available in the dotfile. + +*Important* You should replace your `(defvar -packages ...)`, +`(defvar -pre-extensions ...)`, `(defvar -post-extensions ...)` +and `(defvar -excluded-packages ...)` by `(setq ...)`. This will +allow to install newly added packages to a layer without restarting spacemacs +by pressing `SPC f e R`. Be sure to remove the docstring when replacing the +`defvar` since `setq` does not take a third argument. + +`:variables` keyword now behaves like a regular `setq` so you'll have to +quote any value appropriately. + +2. Emacs lisp and Shell config are now in their own layers + +Be sure to add the new layers `emacs-lisp` and `shell` to your dotfile to +continue to enjoy the emacs-lisp and shell configurations of Spacemacs. + +Also be sure to check the key binding `SPC '` to open a shell buffer. + +3. Key bindings + +`SPC b s` to switch buffer is now on `SPC b b`. +`SPC f f` uses helm instead of ido, set the new variable. +`dotspacemacs-use-ido` to t to get back the old ido behavior. +`TAB` and `C-z` in helm buffers have been *swapped*. + +4. Sentence delimiter + +Sentence delimiter is now a *single space* as opposed to Emacs default +which is double spaces. diff --git a/core/info/release-notes/0.103.txt b/core/info/release-notes/0.103.txt new file mode 100644 index 0000000..bc67213 --- /dev/null +++ b/core/info/release-notes/0.103.txt @@ -0,0 +1,36 @@ +1. Magit 2.1 + +Spacemacs is now compatible only with Magit 2.1 and later, be +sure to *update your packages* (at least Magit). + +2. Helm + +Helm input pattern is now displayed in its header instead of the +minibuffer. + +3. Git layer + +The `git` layer has been split into two layers: `git` and `github` so +the layer variable `git-enabled-github-support` is deprecated, you +have to *add the layer `github` in your dotfile*. + +The `git-gutter` has been replaced by `diff-hl`. This package is in +the new layer `version-control`, be sure to *add this new layer to +your dotfile*. + +4. Auctex layer + +The `auctex` layer has been renamed `latex`, be sure to *update your +dotfile* if you use this layer. + +5. Erlang/Elixir layer + +The erlang/elixir layer has been split into two layers `erlang` and +`elixir`, be sure to *update your dotfile* if you use these layers. + +6. Key bindings changes + +Projectile key bindings changes: +~SPC p e~ is now ~SPC p r~ (recent files), +~SPC p R~ is now ~SPC p G~ (regenerate tags), +~SPC p r~ is now ~SPC p R~ (replace). diff --git a/core/info/release-notes/0.104.txt b/core/info/release-notes/0.104.txt new file mode 100644 index 0000000..fa6ac4d --- /dev/null +++ b/core/info/release-notes/0.104.txt @@ -0,0 +1,44 @@ +1. Org + +`org-plus-contrib` is now installed from org ELPA repository, you may +encounter strange behaviours from Org. In this case delete the `org` +directory in the `elpa` directory and restart Emacs. + +2. Helm + +`Helm` key bindings have been slightly adjusted: + +- in `helm-find-files` (`SPC f f`): now `C-h` move up a directory + and `C-l` enter the selected directory. `describe-key` command is + available on `C-S-h` + +- in other `helm` buffers ~C-h~ is used to go to the next source + and `C-l` is the same as `RET`. `describe-key` command is also + available on `C-S-h`. + +3. Vim keys + +`Y` has been remapped to `y$`, if you don't like this behavior you can +set the variable `dotspacemacs-remap-Y-to-y$` to nil in your dotfile. + +4. Guide-key + +`guide-key` has been replaced by `which-key`, you may encounter issues +if you have some `guide-key` custom configuration, remove any `guide-key` +configuration and check the options offered by `which-key`. + +5. Bookmarks + +The `bookmark` save file has been moved to the `.cache` directory, if +you have a bookmark file `~/.emacs.d/bookmarks` then you'll have to move +it to file `~/.emacs.d/.cache/bookmarks` + +6. Ruby on Rails + +Ruby on Rails framework has now its own layer called `ruby-on-rails`, +be sure to add this layer to your dotfile if you use it. + +7. Django + +Django framework has now its own layer called `django`, +be sure to add this layer to your dotfile if you use it. diff --git a/core/info/release-notes/0.105.txt b/core/info/release-notes/0.105.txt new file mode 100644 index 0000000..e114293 --- /dev/null +++ b/core/info/release-notes/0.105.txt @@ -0,0 +1,32 @@ +1. Key binding changes + +- `SPC l` for `avy-goto-line` is now under `SPC y`. `SPC l` is now for + spacemacs layouts. + +- `SPC a p` is now for `list-processes` and `SPC a P` for `proced`, + `paradox` to list ELPA packages is now on `SPC a k`. + +- `SPC s l` is now used to bring back last search buffer and `SPC s j` + is for jumping into a file using `imenu` (was `SPC s l`). + +- In home buffer, jumping to bookmark list is now on ~b~. + +2. Magit + +Magit key bindings have been revamped thanks to the official `evil-magit` +package. `evil-magit` provides a faithful port of Magit UX using Vim key +bindings. If you want to continue to use the old evilified bindings add +`evil-magit` package to the `dotspacemacs-excluded-packages` variable +of your dotfile. + +3. Projectile + +Caching is now disabled by default, while it should not break anything, +if you have some functions relying on caching being enabled be sure to +activate it explicitly with `(setq projectile-enable-caching t)`. + +4. Ruby + +The default major mode is now the Emacs built-in `ruby-mode`. If you want +to continue to use `enh-ruby-mode` set the layer variable +`ruby-enable-enh-ruby-mode` to `t`. diff --git a/core/info/release-notes/0.200.txt b/core/info/release-notes/0.200.txt new file mode 100644 index 0000000..30a241f --- /dev/null +++ b/core/info/release-notes/0.200.txt @@ -0,0 +1,16 @@ +The Autumnal Cleanup 2016 is complete! Thank you to everyone +who helped keep the issue tracker clean. In particular + +1. gilbertw1 (230 issues, 27.09%) +2. NJBS (98 issues, 11.54%) +3. mahinshaw (90 issues, 10.60%) +4. smile13241324 (75 issues, 8.83%) +5. deb0ch (66 issues, 7.77%) + +as well as bleggett, jredville, lazywithclass, rgrinberg, +kdelwat, cmr, bmag, ksjogo, ekmecic, cro, inirudebwoy, +mwillsey, robbyoconnor and alimoeeny. And of course, last but +not least, the hard working organizer d12frosted! + +For more info on release 0.200.x see the newsletter #01 at +[[http://spacemacs.org/news/news01.html]] diff --git a/core/info/release-notes/af-1.01.txt b/core/info/release-notes/af-1.01.txt new file mode 100644 index 0000000..70c43e1 --- /dev/null +++ b/core/info/release-notes/af-1.01.txt @@ -0,0 +1,38 @@ + The new version of Spacemacs has arrived! + +This version brings Emacs to a whole new level by embedding Zerovim technologies +through a state of the art message passing interface, this is Emacs for the next +next NEXT century. + +This is so powerful that we decided to rename Spacemacs! + + Zemacs: Emacs to THE MAX! + +- Zerovim ambitious refactor of the (-1)Vim code base directly improves the code +quality of Emacs while still retaining its important [implementation tricks]. + +- Elisp can now be transpiled to Vimscript which can be transpiled to Lua which +can be used to code plugins for Zerovim, so now Emacs can have true native Vim +plugins in Lua code coded in Elisp. +Note: For performance reasons native plugins are transpiled to Elisp before +being executed. + +- You can now type in [Atom] in Emacs by sharing a Zerovim session. Zemacs is +shipped with a groundbreaking new UI using the new VR headsets capabilities: +by projecting the Atom web-based interface on the left eye and the Emacs +text-based interface on the right eye (also available the `swap-the-eyes' major +mode tailored for colour-blind people) we can create the perfect blend of Emacs +and Atom, instantaneous context switching with the blink of an eye. Welcome +to the definitive GUI: + + Zemacstom, the editor for the next next NEXT millennium. + + ------------------------------------------- + +This text is a parody of Neovim whose only purpose is to be funny (the text, not +Neovim!). Neovim is a popular fork of Vim, you can try it and contribute to it +by visiting this [link] or maybe [this one]. + +This prank will self-destruct the 2nd April 2016. + +Type ~SPC m aprilfool~ to start working :-) diff --git a/core/libs/ht.el b/core/libs/ht.el new file mode 100644 index 0000000..0d5d8b0 --- /dev/null +++ b/core/libs/ht.el @@ -0,0 +1,280 @@ +;;; ht.el --- The missing hash table library for Emacs + +;; Copyright (C) 2013 Wilfred Hughes + +;; Author: Wilfred Hughes +;; Version: 2.0 +;; Keywords: hash table, hash map, hash + +;; 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 this program. If not, see . + +;;; Commentary: + +;; The missing hash table utility library for Emacs. +;; +;; See documentation on https://github.com/Wilfred/ht.el + +;;; Code: + +(eval-when-compile (require 'cl)) ;; dolist + +(defmacro ht (&rest pairs) + "Create a hash table with the key-value pairs given. +Keys are compared with `equal'. + +\(fn (KEY-1 VALUE-1) (KEY-2 VALUE-2) ...)" + (let* ((table-symbol (make-symbol "ht-temp")) + (assignments + (mapcar + (lambda (pair) `(ht-set! ,table-symbol ,@pair)) + pairs))) + `(let ((,table-symbol (ht-create))) + ,@assignments + ,table-symbol))) + +(defun ht-create (&optional test) + "Create an empty hash table. + +TEST indicates the function used to compare the hash +keys. Default is `equal'. It can be `eq', `eql', `equal' or a +user-supplied test created via `define-hash-table-test'." + (make-hash-table :test (or test 'equal))) + +(defun ht<-alist (alist) + "Create a hash table with initial values according to ALIST." + (let ((h (ht-create))) + ;; the first key-value pair in an alist gets precedence, so we + ;; start from the end of the list: + (dolist (pair (reverse alist) h) + (let ((key (car pair)) + (value (cdr pair))) + (ht-set! h key value))))) + +(defalias 'ht-from-alist 'ht<-alist) + +;; based on the excellent -partition from dash.el, but we aim to be self-contained +(defun ht/group-pairs (list) + "Return a new list with the items in LIST grouped into pairs. +Errors if LIST doesn't contain an even number of elements." + (let ((result) + (sublist) + (len 0)) + + (while list + ;; take the head of LIST and push onto SUBLIST + (setq sublist (cons (car list) sublist)) + (setq list (cdr list)) + + (setq len (1+ len)) + + (when (= len 2) + ;; push this two-item list onto RESULT + (setq result (cons (nreverse sublist) result)) + (setq sublist nil) + (setq len 0))) + + (when sublist (error "Expected an even number of elements")) + (nreverse result))) + +(defun ht<-plist (plist) + "Create a hash table with initial values according to PLIST." + (let ((h (ht-create))) + (dolist (pair (ht/group-pairs plist) h) + (let ((key (car pair)) + (value (cadr pair))) + (ht-set! h key value))))) + +(defalias 'ht-from-plist 'ht<-plist) + +(defun ht-get (table key &optional default) + "Look up KEY in TABLE, and return the matching value. +If KEY isn't present, return DEFAULT (nil if not specified)." + (gethash key table default)) + +(defun ht-set! (table key value) + "Associate KEY in TABLE with VALUE." + (puthash key value table) + nil) + +(defalias 'ht-set 'ht-set!) + +(defun ht-update! (table from-table) + "Update TABLE according to every key-value pair in FROM-TABLE." + (maphash + (lambda (key value) (puthash key value table)) + from-table) + nil) + +(defalias 'ht-update 'ht-update!) + +(defun ht-merge (&rest tables) + "Crete a new tables that includes all the key-value pairs from TABLES. +If multiple have tables have the same key, the value in the last +table is used." + (let ((merged (ht-create))) + (mapc (lambda (table) (ht-update! merged table)) tables) + merged)) + +(defun ht-remove! (table key) + "Remove KEY from TABLE." + (remhash key table)) + +(defalias 'ht-remove 'ht-remove!) + +(defun ht-clear! (table) + "Remove all keys from TABLE." + (clrhash table) + nil) + +(defalias 'ht-clear 'ht-clear!) + +(defun ht-map (function table) + "Apply FUNCTION to each key-value pair of TABLE, and make a list of the results. +FUNCTION is called with two arguments, KEY and VALUE." + (let (results) + (maphash + (lambda (key value) + (push (funcall function key value) results)) + table) + results)) + +(defmacro ht-amap (form table) + "Anaphoric version of `ht-map'. +For every key-value pair in TABLE, evaluate FORM with the +variables KEY and VALUE bound." + `(ht-map (lambda (key value) ,form) ,table)) + +(defun ht-keys (table) + "Return a list of all the keys in TABLE." + (ht-amap key table)) + +(defun ht-values (table) + "Return a list of all the values in TABLE." + (ht-amap value table)) + +(defun ht-items (table) + "Return a list of two-element lists '(key value) from TABLE." + (ht-amap (list key value) table)) + +(defalias 'ht-each 'maphash + "Apply FUNCTION to each key-value pair of TABLE. +Returns nil, used for side-effects only.") + +(defmacro ht-aeach (form table) + "Anaphoric version of `ht-each'. +For every key-value pair in TABLE, evaluate FORM with the +variables key and value bound." + `(ht-each (lambda (key value) ,form) ,table)) + +(defun ht->plist (table) + "Return a flat list '(key1 value1 key2 value2...) from TABLE. + +Note that hash tables are unordered, so this cannot be an exact +inverse of `ht<-plist'. The following is not guaranteed: + +\(let ((data '(a b c d))) + (equalp data + (ht->plist (ht<-plist data))))" + (apply 'append (ht-items table))) + +(defalias 'ht-to-plist 'ht->plist) + +(defun ht-copy (table) + "Return a shallow copy of TABLE (keys and values are shared)." + (copy-hash-table table)) + +(defun ht->alist (table) + "Return a list of two-element lists '(key . value) from TABLE. + +Note that hash tables are unordered, so this cannot be an exact +inverse of `ht<-alist'. The following is not guaranteed: + +\(let ((data '((a . b) (c . d)))) + (equalp data + (ht->alist (ht<-alist data))))" + (ht-amap (cons key value) table)) + +(defalias 'ht-to-alist 'ht->alist) + +(defalias 'ht? 'hash-table-p) + +(defalias 'ht-p 'hash-table-p) + +(defun ht-contains? (table key) + "Return 't if TABLE contains KEY." + (not (eq (ht-get table key 'ht--not-found) 'ht--not-found))) + +(defalias 'ht-contains-p 'ht-contains?) + +(defun ht-size (table) + "Return the actual number of entries in TABLE." + (hash-table-count table)) + +(defun ht-empty? (table) + "Return true if the actual number of entries in TABLE is zero." + (zerop (ht-size table))) + +(defun ht-select (function table) + "Return a hash table containing all entries in TABLE for which +FUNCTION returns a truthy value. + +FUNCTION is called with two arguments, KEY and VALUE." + (let ((results (ht-create))) + (ht-each + (lambda (key value) + (when (funcall function key value) + (ht-set! results key value))) + table) + results)) + +(defun ht-reject (function table) + "Return a hash table containing all entries in TABLE for which +FUNCTION returns a falsy value. + +FUNCTION is called with two arguments, KEY and VALUE." + (let ((results (ht-create))) + (ht-each + (lambda (key value) + (unless (funcall function key value) + (ht-set! results key value))) + table) + results)) + +(defun ht-reject! (function table) + "Delete entries from TABLE for which FUNCTION returns a falsy value. + +FUNCTION is called with two arguments, KEY and VALUE." + (ht-each + (lambda (key value) + (when (funcall function key value) + (remhash key table))) + table) + nil) + +(defalias 'ht-delete-if 'ht-reject!) + +(defun ht-find (function table) + "Return (key, value) from TABLE for which FUNCTION returns a truthy value. +Return nil otherwise. + +FUNCTION is called with two arguments, KEY and VALUE." + (catch 'break + (ht-each + (lambda (key value) + (when (funcall function key value) + (throw 'break (list key value)))) + table))) + +(provide 'ht) +;;; ht.el ends here diff --git a/core/libs/mocker.el b/core/libs/mocker.el new file mode 100644 index 0000000..c06080e --- /dev/null +++ b/core/libs/mocker.el @@ -0,0 +1,368 @@ +;;; mocker.el --- mocking framework for emacs + +;; Copyright (C) 2011 Yann Hodique. + +;; Author: Yann Hodique +;; Keywords: lisp, testing +;; Version: 0.3.0 +;; Package-Requires: ((eieio "1.3") (el-x "0.2.4")) + +;; This file 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 file 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: + +;; + +;;; Code: + +(eval-when-compile + (require 'cl)) + +(require 'eieio) + +(eval-and-compile + ;; use dflet from el-x if available + (if (require 'dflet nil t) + (defalias 'mocker-flet 'dflet) + ;; fallback to regular flet, hoping it's still there + (defalias 'mocker-flet 'flet))) + +(defvar mocker-mock-default-record-cls 'mocker-record) + +(put 'mocker-mock-error 'error-conditions '(mocker-mock-error error)) +(put 'mocker-mock-error 'error-message "Mocker mock error") + +(put 'mocker-record-error 'error-conditions '(mocker-record-error error)) +(put 'mocker-record-error 'error-message "Mocker record error") + +(defun mocker--plist-remove (plist key) + ;; courtesy of pjb + (if (eq (car plist) key) (cdr (cdr plist)) + (cons (car plist) + (cons (cadr plist) + (mocker--plist-remove (cddr plist) key))))) + +;;; Mock object +(defclass mocker-mock () + ((function :initarg :function :type symbol) + (orig-def :initarg :orig-def :initform nil) + (argspec :initarg :argspec :initform nil :type list) + (ordered :initarg :ordered :initform t) + (records :initarg :records :initform nil :type list))) + +(defmethod constructor :static ((mock mocker-mock) newname &rest args) + (let* ((obj (call-next-method)) + (recs (oref obj :records)) + (func (oref obj :function))) + (oset obj :orig-def (when (fboundp func) (symbol-function func))) + (oset obj :records nil) + (mapc #'(lambda (r) + (apply 'mocker-add-record obj r)) + recs) + obj)) + +(defmethod mocker-add-record ((mock mocker-mock) &rest args) + (object-add-to-list mock :records + (let ((cls mocker-mock-default-record-cls) + (tmp (plist-get args :record-cls))) + (when tmp + (setq cls tmp + args (mocker-read-record cls + (mocker--plist-remove + args :record-cls)))) + (apply 'make-instance cls :-mock mock + :-sym (make-symbol "unique") args)) + t)) + +(defmethod mocker-fail-mock ((mock mocker-mock) args) + (signal 'mocker-mock-error + (list (format (concat "Unexpected call to mock `%s'" + " with input `%s'") + (oref mock :function) args)))) + +(defvar mocker-inhibit nil) + +(defmethod mocker-run ((mock mocker-mock) &rest args) + (if (not mocker-inhibit) + (let* ((mocker-inhibit t) + (rec (mocker-find-active-record mock args)) + (ordered (oref mock :ordered))) + (cond ((null rec) + (mocker-fail-mock mock args)) + ((or (not ordered) (mocker-test-record rec args)) + (mocker-run-record rec args)) + (t + (mocker-fail-record rec args)))) + (apply (oref mock :orig-def) args))) + +(defmethod mocker-find-active-record ((mock mocker-mock) args) + (let ((first-match (lambda (pred seq) + (let ((x nil)) + (while (and seq + (not (setq x (funcall pred (pop seq)))))) + x)))) + (let* ((ordered (oref mock :ordered)) + rec) + (if ordered + (setq rec (funcall + first-match + #'(lambda (r) + (when (oref r :-active) + (if (mocker-test-record r args) + (progn + (mocker-use-record r) + r) + (mocker-skip-record r args)))) + (oref mock :records))) + (setq rec (funcall + first-match + #'(lambda (r) + (and + (oref r :-active) + (mocker-test-record r args) + (progn + (mocker-use-record r) + r))) + (oref mock :records)))) + rec))) + +(defmethod mocker-verify ((mock mocker-mock)) + (mapc #'(lambda (r) (when (and (oref r :-active) + (< (oref r :-occurrences) + (oref r :min-occur))) + (signal 'mocker-record-error + (list (format + (concat "Expected call to mock `%s'," + " with input like %s," + " was not run.") + (oref mock :function) + (mocker-get-record-expectations r)))))) + (oref mock :records))) + +;;; Mock record base object +(defclass mocker-record-base () + ((min-occur :initarg :min-occur :initform 1 :type number) + (max-occur :initarg :max-occur :initform nil :type (or null number)) + (-occur :initarg :occur :initform nil :type (or null number)) + (-occurrences :initarg :-occurrences :initform 0 :type number + :protection :protected) + (-mock :initarg :-mock) + (-active :initarg :-active :initform t :protection :protected) + (-sym :initarg :-sym))) + +(defmethod constructor :static ((rec mocker-record-base) newname &rest args) + (let* ((obj (call-next-method)) + (occur (oref obj :occur))) + (when occur + (oset obj :min-occur (max (oref obj :min-occur) + occur)) + (oset obj :max-occur (if (oref obj :max-occur) + (min (oref obj :max-occur) occur) + occur))) + obj)) + +(defmethod mocker-read-record :static ((rec mocker-record-base) spec) + spec) + +(defmethod mocker-use-record ((rec mocker-record-base)) + (let ((max (oref rec :max-occur)) + (n (1+ (oref rec :-occurrences)))) + (oset rec :-occurrences n) + (when (and (not (null max)) + (= n max)) + (oset rec :-active nil)))) + +(defmethod mocker-skip-record ((rec mocker-record-base) args) + (if (>= (oref rec :-occurrences) + (oref rec :min-occur)) + (oset rec :-active nil) + (mocker-fail-record rec args))) + +(defmethod mocker-test-record ((rec mocker-record-base) args) + (error "not implemented in base class")) + +(defmethod mocker-run-record ((rec mocker-record-base) args) + (error "not implemented in base class")) + +(defmethod mocker-get-record-expectations ((rec mocker-record-base))) + +(defmethod mocker-fail-record ((rec mocker-record-base) args) + (signal 'mocker-record-error + (list (format (concat "Violated record while mocking `%s'." + " Expected input like: %s, got: `%s' instead") + (oref (oref rec :-mock) :function) + (mocker-get-record-expectations rec) + args)))) + +;;; Mock input recognizer +(defclass mocker-input-record (mocker-record-base) + ((input :initarg :input :initform nil :type list) + (input-matcher :initarg :input-matcher :initform nil))) + +(defmethod constructor :static ((rec mocker-input-record) newname &rest args) + (let* ((obj (call-next-method))) + (when (or (not (slot-boundp obj :max-occur)) + (and (oref obj :max-occur) + (< (oref obj :max-occur) + (oref obj :min-occur)))) + (oset obj :max-occur (oref obj :min-occur))) + obj)) + +(defmethod mocker-test-record ((rec mocker-input-record) args) + (let ((matcher (oref rec :input-matcher)) + (input (oref rec :input))) + (cond (matcher + (apply matcher args)) + (t + (equal input args))))) + +(defmethod mocker-get-record-expectations ((rec mocker-input-record)) + (format "`%s'" (or (oref rec :input-matcher) (oref rec :input)))) + +;;; Mock record default object +(defclass mocker-record (mocker-input-record) + ((output :initarg :output :initform nil) + (output-generator :initarg :output-generator :initform nil))) + +(defmethod mocker-run-record ((rec mocker-record) args) + (let ((generator (oref rec :output-generator)) + (output (oref rec :output))) + (cond (generator + (apply generator args)) + (t + output)))) + +;;; Mock simple stub object +(defclass mocker-stub-record (mocker-record-base) + ((output :initarg :output :initform nil))) + +(defmethod constructor :static ((rec mocker-stub-record) newname &rest args) + (let* ((obj (call-next-method))) + (unless (slot-boundp obj :min-occur) + (oset obj :min-occur 0)) + (unless (slot-boundp obj :max-occur) + (oset obj :max-occur nil)) + obj)) + +(defmethod mocker-test-record ((rec mocker-stub-record) args) + t) + +(defmethod mocker-run-record ((rec mocker-stub-record) args) + (oref rec :output)) + +(defmethod mocker-get-record-expectations ((rec mocker-stub-record)) + "anything") + +;;; Mock passthrough record +(defclass mocker-passthrough-record (mocker-input-record) + ()) + +(defmethod mocker-run-record ((rec mocker-passthrough-record) args) + (let* ((mock (oref rec :-mock)) + (def (oref mock :orig-def))) + (when def + (apply def args)))) + +;;; Helpers +(defun mocker-gen-mocks (mockspecs) + "helper to generate mocks from the input of `mocker-let'" + (mapcar #'(lambda (m) + (let* ((func (car m)) + (argspec (cadr m)) + (rest (cddr m)) + (sym (make-symbol (concat (symbol-name func) "--mock")))) + (list sym + (apply 'make-instance 'mocker-mock + :function func + :argspec argspec + (let* ((order (if (plist-member rest :ordered) + (prog1 + (plist-get rest :ordered) + (setq rest + (mocker--plist-remove + rest :ordered))) + (oref-default 'mocker-mock + :ordered)))) + (list :ordered order))) + (if (plist-member rest :records) + (plist-get rest :records) + (car rest))))) + mockspecs)) + +;;;###autoload +(defmacro mocker-let (mockspecs &rest body) + "Generate temporary bindings according to MOCKSPECS then eval +BODY. The value of the last form in BODY is returned. +Each element of MOCKSPECS is a list (FUNC ARGS [OPTIONS] +RECORDS). + +FUNC is the name of the function to bind, whose original + definition must accept arguments compatible with ARGS. +OPTIONS can be :ordered nil if the records can be executed out of +order (by default, order is enforced). +RECORDS is a list ([:record-cls CLASS] ARG1 ARG2...). + +Each element of RECORDS will generate a record for the +corresponding mock. By default, records are objects of the +`mocker-record' class, but CLASS is used instead if specified. +The rest of the arguments are used to construct the record +object. They will be passed to method `mocker-read-record' for +the used CLASS. This method must return a valid list of +parameters for the CLASS constructor. This allows to implement +specialized mini-languages for specific record classes. +" + (declare (indent 1) (debug t)) + (let* ((mocks (mocker-gen-mocks mockspecs)) + (vars (mapcar #'(lambda (m) + `(,(car m) ,(cadr m))) + mocks)) + (specs (mapcar + #'(lambda (m) + (let* ((mock-sym (car m)) + (mock (cadr m)) + (func (oref mock :function)) + (spec (oref mock :argspec)) + (call (or (and (member '&rest spec) 'apply) + 'funcall)) + (args (loop for el in spec + if (or (not (symbolp el)) + (not (equal + (elt (symbol-name el) 0) + ?&))) + collect el))) + (list func + spec + `(,call #'mocker-run ,mock-sym ,@args)))) + mocks)) + (inits (mapcar #'(lambda (m) + (cons 'progn + (mapcar #'(lambda (rec) + `(mocker-add-record ,(car m) + ,@rec)) + (nth 2 m)))) + mocks)) + (verifs (mapcar #'(lambda (m) + `(mocker-verify ,(car m))) + mocks))) + `(let (,@vars) + ,@inits + (prog1 + ,(macroexpand `(mocker-flet (,@specs) + ,@body)) + ,@verifs)))) + +(provide 'mocker) +;;; mocker.el ends here diff --git a/core/libs/page-break-lines.el b/core/libs/page-break-lines.el new file mode 100644 index 0000000..c8b3b9a --- /dev/null +++ b/core/libs/page-break-lines.el @@ -0,0 +1,165 @@ +;;; page-break-lines.el --- Display ugly ^L page breaks as tidy horizontal lines + +;; Copyright (C) 2012-2015 Steve Purcell + +;; Author: Steve Purcell +;; URL: https://github.com/purcell/page-break-lines +;; Package-Version: 20160109.1813 +;; Package-X-Original-Version: DEV +;; Keywords: convenience, faces + +;; 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 this program. If not, see . + +;;; Commentary: + +;; This library provides a global mode which displays form feed +;; characters as horizontal rules. + +;; Install from Melpa or Marmalade, or add to `load-path' and use +;; (require 'page-break-lines). + +;; Use `page-break-lines-mode' to enable the mode in specific buffers, +;; or customize `page-break-lines-modes' and enable the mode globally with +;; `global-page-break-lines-mode'. + +;; Issues and limitations: + +;; If `page-break-lines-char' is displayed at a different width to +;; regular characters, the rule may be either too short or too long: +;; rules may then wrap if `truncate-lines' is nil. On some systems, +;; Emacs may erroneously choose a different font for the page break +;; symbol, which choice can be overridden using code such as: + +;; (set-fontset-font "fontset-default" +;; (cons page-break-lines-char page-break-lines-char) +;; (face-attribute 'default :family)) + +;; Use `describe-char' on a page break char to determine whether this +;; is the case. + +;; Additionally, the use of `text-scale-increase' or +;; `text-scale-decrease' will cause the rule width to be incorrect, +;; because the reported window width (in characters) will continue to +;; be the width in the frame's default font, not the scaled font used to +;; display the rule. + +;; Adapted from code http://www.emacswiki.org/emacs/PageBreaks + +;;; Code: + +(defgroup page-break-lines nil + "Display ugly ^L page breaks as tidy horizontal lines." + :prefix "page-break-lines-" + :group 'faces) + +(defcustom page-break-lines-char ?─ + "Character used to render page break lines." + :type 'character + :group 'page-break-lines) + +(defcustom page-break-lines-lighter " PgLn" + "Mode-line indicator for `page-break-lines-mode'." + :type '(choice (const :tag "No lighter" "") string) + :group 'page-break-lines) + +(defcustom page-break-lines-modes + '(emacs-lisp-mode lisp-mode scheme-mode compilation-mode outline-mode help-mode) + "Modes in which to enable `page-break-lines-mode'." + :type '(repeat symbol) + :group 'page-break-lines) + +(defface page-break-lines + '((t :inherit font-lock-comment-face :bold nil :italic nil)) + "Face used to colorize page break lines. +If using :bold or :italic, please ensure `page-break-lines-char' +is available in that variant of your font, otherwise it may be +displayed as a junk character." + :group 'page-break-lines) + + + +;;;###autoload +(define-minor-mode page-break-lines-mode + "Toggle Page Break Lines mode. + +In Page Break mode, page breaks (^L characters) are displayed as a +horizontal line of `page-break-string-char' characters." + :lighter page-break-lines-lighter + :group 'page-break-lines + (page-break-lines--update-display-tables)) + +;;;###autoload +(defun turn-on-page-break-lines-mode () + "Enable `page-break-lines-mode' in this buffer." + (page-break-lines-mode 1)) + +;;;###autoload +(defun turn-off-page-break-lines-mode () + "Disable `page-break-lines-mode' in this buffer." + (page-break-lines-mode -1)) + + +(dolist (hook '(window-configuration-change-hook + after-setting-font-hook)) + (add-hook hook 'page-break-lines--update-display-tables)) + + + +(defun page-break-lines--update-display-table (window) + "Modify a display-table that displays page-breaks prettily. +If the buffer inside WINDOW has `page-break-lines-mode' enabled, +its display table will be modified as necessary." + (with-current-buffer (window-buffer window) + (if page-break-lines-mode + (progn + (unless buffer-display-table + (setq buffer-display-table (make-display-table))) + (let* ((width (- (window-width window) 1)) + (glyph (make-glyph-code page-break-lines-char 'page-break-lines)) + (new-display-entry (vconcat (make-list width glyph)))) + (unless (equal new-display-entry (elt buffer-display-table ?\^L)) + (aset buffer-display-table ?\^L new-display-entry)))) + (when buffer-display-table + (aset buffer-display-table ?\^L nil))))) + +(defun page-break-lines--update-display-tables () + "Function called for updating display table." + (mapc 'page-break-lines--update-display-table (window-list nil 'no-minibuffer))) + + + +;;;###autoload +(defun page-break-lines-mode-maybe () + "Enable `page-break-lines-mode' in the current buffer if desired. +When `major-mode' is listed in `page-break-lines-modes', then +`page-break-lines-mode' will be enabled." + (if (and (not (minibufferp)) + (apply 'derived-mode-p page-break-lines-modes)) + (page-break-lines-mode 1))) + +;;;###autoload +(define-global-minor-mode global-page-break-lines-mode + page-break-lines-mode page-break-lines-mode-maybe + :group 'page-break-lines) + + +(provide 'page-break-lines) + +;; Local Variables: +;; coding: utf-8 +;; byte-compile-warnings: (not cl-functions) +;; checkdoc-minor-mode: t +;; End: + +;;; page-break-lines.el ends here diff --git a/core/templates/.spacemacs.template b/core/templates/.spacemacs.template new file mode 100644 index 0000000..76d942e --- /dev/null +++ b/core/templates/.spacemacs.template @@ -0,0 +1,305 @@ +;; -*- mode: emacs-lisp -*- +;; This file is loaded by Spacemacs at startup. +;; It must be stored in your home directory. + +(defun dotspacemacs/layers () + "Configuration Layers declaration. +You should not put any user code in this function besides modifying the variable +values." + (setq-default + ;; Base distribution to use. This is a layer contained in the directory + ;; `+distribution'. For now available distributions are `spacemacs-base' + ;; or `spacemacs'. (default 'spacemacs) + dotspacemacs-distribution 'spacemacs + ;; Lazy installation of layers (i.e. layers are installed only when a file + ;; with a supported type is opened). Possible values are `all', `unused' + ;; and `nil'. `unused' will lazy install only unused layers (i.e. layers + ;; not listed in variable `dotspacemacs-configuration-layers'), `all' will + ;; lazy install any layer that support lazy installation even the layers + ;; listed in `dotspacemacs-configuration-layers'. `nil' disable the lazy + ;; installation feature and you have to explicitly list a layer in the + ;; variable `dotspacemacs-configuration-layers' to install it. + ;; (default 'unused) + dotspacemacs-enable-lazy-installation 'unused + ;; If non-nil then Spacemacs will ask for confirmation before installing + ;; a layer lazily. (default t) + dotspacemacs-ask-for-lazy-installation t + ;; If non-nil layers with lazy install support are lazy installed. + ;; List of additional paths where to look for configuration layers. + ;; Paths must have a trailing slash (i.e. `~/.mycontribs/') + dotspacemacs-configuration-layer-path '() + ;; List of configuration layers to load. + dotspacemacs-configuration-layers + '( + ;; ---------------------------------------------------------------- + ;; Example of useful layers you may want to use right away. + ;; Uncomment some layer names and press (Vim style) or + ;; (Emacs style) to install them. + ;; ---------------------------------------------------------------- + helm + ;; auto-completion + ;; better-defaults + emacs-lisp + ;; git + ;; markdown + ;; org + ;; (shell :variables + ;; shell-default-height 30 + ;; shell-default-position 'bottom) + ;; spell-checking + ;; syntax-checking + ;; version-control + ) + ;; List of additional packages that will be installed without being + ;; wrapped in a layer. If you need some configuration for these + ;; packages, then consider creating a layer. You can also put the + ;; configuration in `dotspacemacs/user-config'. + dotspacemacs-additional-packages '() + ;; A list of packages that cannot be updated. + dotspacemacs-frozen-packages '() + ;; A list of packages that will not be installed and loaded. + dotspacemacs-excluded-packages '() + ;; Defines the behaviour of Spacemacs when installing packages. + ;; Possible values are `used-only', `used-but-keep-unused' and `all'. + ;; `used-only' installs only explicitly used packages and uninstall any + ;; unused packages as well as their unused dependencies. + ;; `used-but-keep-unused' installs only the used packages but won't uninstall + ;; them if they become unused. `all' installs *all* packages supported by + ;; Spacemacs and never uninstall them. (default is `used-only') + dotspacemacs-install-packages 'used-only)) + +(defun dotspacemacs/init () + "Initialization function. +This function is called at the very startup of Spacemacs initialization +before layers configuration. +You should not put any user code in there besides modifying the variable +values." + ;; This setq-default sexp is an exhaustive list of all the supported + ;; spacemacs settings. + (setq-default + ;; If non nil ELPA repositories are contacted via HTTPS whenever it's + ;; possible. Set it to nil if you have no way to use HTTPS in your + ;; environment, otherwise it is strongly recommended to let it set to t. + ;; This variable has no effect if Emacs is launched with the parameter + ;; `--insecure' which forces the value of this variable to nil. + ;; (default t) + dotspacemacs-elpa-https t + ;; Maximum allowed time in seconds to contact an ELPA repository. + dotspacemacs-elpa-timeout 5 + ;; If non nil then spacemacs will check for updates at startup + ;; when the current branch is not `develop'. Note that checking for + ;; new versions works via git commands, thus it calls GitHub services + ;; whenever you start Emacs. (default nil) + dotspacemacs-check-for-update nil + ;; If non-nil, a form that evaluates to a package directory. For example, to + ;; use different package directories for different Emacs versions, set this + ;; to `emacs-version'. + dotspacemacs-elpa-subdirectory nil + ;; One of `vim', `emacs' or `hybrid'. + ;; `hybrid' is like `vim' except that `insert state' is replaced by the + ;; `hybrid state' with `emacs' key bindings. The value can also be a list + ;; with `:variables' keyword (similar to layers). Check the editing styles + ;; section of the documentation for details on available variables. + ;; (default 'vim) + dotspacemacs-editing-style 'vim + ;; If non nil output loading progress in `*Messages*' buffer. (default nil) + dotspacemacs-verbose-loading nil + ;; Specify the startup banner. Default value is `official', it displays + ;; the official spacemacs logo. An integer value is the index of text + ;; banner, `random' chooses a random text banner in `core/banners' + ;; directory. A string value must be a path to an image format supported + ;; by your Emacs build. + ;; If the value is nil then no banner is displayed. (default 'official) + dotspacemacs-startup-banner 'official + ;; List of items to show in startup buffer or an association list of + ;; the form `(list-type . list-size)`. If nil then it is disabled. + ;; Possible values for list-type are: + ;; `recents' `bookmarks' `projects' `agenda' `todos'." + ;; List sizes may be nil, in which case + ;; `spacemacs-buffer-startup-lists-length' takes effect. + dotspacemacs-startup-lists '((recents . 5) + (projects . 7)) + ;; True if the home buffer should respond to resize events. + dotspacemacs-startup-buffer-responsive t + ;; Default major mode of the scratch buffer (default `text-mode') + dotspacemacs-scratch-mode 'text-mode + ;; List of themes, the first of the list is loaded when spacemacs starts. + ;; Press T n to cycle to the next theme in the list (works great + ;; with 2 themes variants, one dark and one light) + dotspacemacs-themes '(spacemacs-dark + spacemacs-light) + ;; If non nil the cursor color matches the state color in GUI Emacs. + dotspacemacs-colorize-cursor-according-to-state t + ;; Default font, or prioritized list of fonts. `powerline-scale' allows to + ;; quickly tweak the mode-line size to make separators look not too crappy. + dotspacemacs-default-font '("Source Code Pro" + :size 13 + :weight normal + :width normal + :powerline-scale 1.1) + ;; The leader key + dotspacemacs-leader-key "SPC" + ;; The key used for Emacs commands (M-x) (after pressing on the leader key). + ;; (default "SPC") + dotspacemacs-emacs-command-key "SPC" + ;; The key used for Vim Ex commands (default ":") + dotspacemacs-ex-command-key ":" + ;; The leader key accessible in `emacs state' and `insert state' + ;; (default "M-m") + dotspacemacs-emacs-leader-key "M-m" + ;; Major mode leader key is a shortcut key which is the equivalent of + ;; pressing ` m`. Set it to `nil` to disable it. (default ",") + dotspacemacs-major-mode-leader-key "," + ;; Major mode leader key accessible in `emacs state' and `insert state'. + ;; (default "C-M-m") + dotspacemacs-major-mode-emacs-leader-key "C-M-m" + ;; These variables control whether separate commands are bound in the GUI to + ;; the key pairs C-i, TAB and C-m, RET. + ;; Setting it to a non-nil value, allows for separate commands under + ;; and TAB or and RET. + ;; In the terminal, these pairs are generally indistinguishable, so this only + ;; works in the GUI. (default nil) + dotspacemacs-distinguish-gui-tab nil + ;; If non nil `Y' is remapped to `y$' in Evil states. (default nil) + dotspacemacs-remap-Y-to-y$ nil + ;; If non-nil, the shift mappings `<' and `>' retain visual state if used + ;; there. (default t) + dotspacemacs-retain-visual-state-on-shift t + ;; If non-nil, J and K move lines up and down when in visual mode. + ;; (default nil) + dotspacemacs-visual-line-move-text nil + ;; If non nil, inverse the meaning of `g' in `:substitute' Evil ex-command. + ;; (default nil) + dotspacemacs-ex-substitute-global nil + ;; Name of the default layout (default "Default") + dotspacemacs-default-layout-name "Default" + ;; If non nil the default layout name is displayed in the mode-line. + ;; (default nil) + dotspacemacs-display-default-layout nil + ;; If non nil then the last auto saved layouts are resume automatically upon + ;; start. (default nil) + dotspacemacs-auto-resume-layouts nil + ;; Size (in MB) above which spacemacs will prompt to open the large file + ;; literally to avoid performance issues. Opening a file literally means that + ;; no major mode or minor modes are active. (default is 1) + dotspacemacs-large-file-size 1 + ;; Location where to auto-save files. Possible values are `original' to + ;; auto-save the file in-place, `cache' to auto-save the file to another + ;; file stored in the cache directory and `nil' to disable auto-saving. + ;; (default 'cache) + dotspacemacs-auto-save-file-location 'cache + ;; Maximum number of rollback slots to keep in the cache. (default 5) + dotspacemacs-max-rollback-slots 5 + ;; If non nil, `helm' will try to minimize the space it uses. (default nil) + dotspacemacs-helm-resize nil + ;; if non nil, the helm header is hidden when there is only one source. + ;; (default nil) + dotspacemacs-helm-no-header nil + ;; define the position to display `helm', options are `bottom', `top', + ;; `left', or `right'. (default 'bottom) + dotspacemacs-helm-position 'bottom + ;; Controls fuzzy matching in helm. If set to `always', force fuzzy matching + ;; in all non-asynchronous sources. If set to `source', preserve individual + ;; source settings. Else, disable fuzzy matching in all sources. + ;; (default 'always) + dotspacemacs-helm-use-fuzzy 'always + ;; If non nil the paste micro-state is enabled. When enabled pressing `p` + ;; several times cycle between the kill ring content. (default nil) + dotspacemacs-enable-paste-transient-state nil + ;; Which-key delay in seconds. The which-key buffer is the popup listing + ;; the commands bound to the current keystroke sequence. (default 0.4) + dotspacemacs-which-key-delay 0.4 + ;; Which-key frame position. Possible values are `right', `bottom' and + ;; `right-then-bottom'. right-then-bottom tries to display the frame to the + ;; right; if there is insufficient space it displays it at the bottom. + ;; (default 'bottom) + dotspacemacs-which-key-position 'bottom + ;; If non nil a progress bar is displayed when spacemacs is loading. This + ;; may increase the boot time on some systems and emacs builds, set it to + ;; nil to boost the loading time. (default t) + dotspacemacs-loading-progress-bar t + ;; If non nil the frame is fullscreen when Emacs starts up. (default nil) + ;; (Emacs 24.4+ only) + dotspacemacs-fullscreen-at-startup nil + ;; If non nil `spacemacs/toggle-fullscreen' will not use native fullscreen. + ;; Use to disable fullscreen animations in OSX. (default nil) + dotspacemacs-fullscreen-use-non-native nil + ;; If non nil the frame is maximized when Emacs starts up. + ;; Takes effect only if `dotspacemacs-fullscreen-at-startup' is nil. + ;; (default nil) (Emacs 24.4+ only) + dotspacemacs-maximized-at-startup nil + ;; A value from the range (0..100), in increasing opacity, which describes + ;; the transparency level of a frame when it's active or selected. + ;; Transparency can be toggled through `toggle-transparency'. (default 90) + dotspacemacs-active-transparency 90 + ;; A value from the range (0..100), in increasing opacity, which describes + ;; the transparency level of a frame when it's inactive or deselected. + ;; Transparency can be toggled through `toggle-transparency'. (default 90) + dotspacemacs-inactive-transparency 90 + ;; If non nil show the titles of transient states. (default t) + dotspacemacs-show-transient-state-title t + ;; If non nil show the color guide hint for transient state keys. (default t) + dotspacemacs-show-transient-state-color-guide t + ;; If non nil unicode symbols are displayed in the mode line. (default t) + dotspacemacs-mode-line-unicode-symbols t + ;; If non nil smooth scrolling (native-scrolling) is enabled. Smooth + ;; scrolling overrides the default behavior of Emacs which recenters point + ;; when it reaches the top or bottom of the screen. (default t) + dotspacemacs-smooth-scrolling t + ;; If non nil line numbers are turned on in all `prog-mode' and `text-mode' + ;; derivatives. If set to `relative', also turns on relative line numbers. + ;; (default nil) + dotspacemacs-line-numbers nil + ;; Code folding method. Possible values are `evil' and `origami'. + ;; (default 'evil) + dotspacemacs-folding-method 'evil + ;; If non-nil smartparens-strict-mode will be enabled in programming modes. + ;; (default nil) + dotspacemacs-smartparens-strict-mode nil + ;; If non-nil pressing the closing parenthesis `)' key in insert mode passes + ;; over any automatically added closing parenthesis, bracket, quote, etc… + ;; This can be temporary disabled by pressing `C-q' before `)'. (default nil) + dotspacemacs-smart-closing-parenthesis nil + ;; Select a scope to highlight delimiters. Possible values are `any', + ;; `current', `all' or `nil'. Default is `all' (highlight any scope and + ;; emphasis the current one). (default 'all) + dotspacemacs-highlight-delimiters 'all + ;; If non nil, advise quit functions to keep server open when quitting. + ;; (default nil) + dotspacemacs-persistent-server nil + ;; List of search tool executable names. Spacemacs uses the first installed + ;; tool of the list. Supported tools are `ag', `pt', `ack' and `grep'. + ;; (default '("ag" "pt" "ack" "grep")) + dotspacemacs-search-tools '("ag" "pt" "ack" "grep") + ;; The default package repository used if no explicit repository has been + ;; specified with an installed package. + ;; Not used for now. (default nil) + dotspacemacs-default-package-repository nil + ;; Delete whitespace while saving buffer. Possible values are `all' + ;; to aggressively delete empty line and long sequences of whitespace, + ;; `trailing' to delete only the whitespace at end of lines, `changed'to + ;; delete only whitespace for changed lines or `nil' to disable cleanup. + ;; (default nil) + dotspacemacs-whitespace-cleanup nil + )) + +(defun dotspacemacs/user-init () + "Initialization function for user code. +It is called immediately after `dotspacemacs/init', before layer configuration +executes. + This function is mostly useful for variables that need to be set +before packages are loaded. If you are unsure, you should try in setting them in +`dotspacemacs/user-config' first." + ) + +(defun dotspacemacs/user-config () + "Configuration function for user code. +This function is called at the very end of Spacemacs initialization after +layers configuration. +This is the place where most of your configurations should be done. Unless it is +explicitly specified that a variable should be set before a package is loaded, +you should place your code here." + ) + +;; Do not write anything past this comment. This is where Emacs will +;; auto-generate custom variable definitions. diff --git a/core/templates/README.org.template b/core/templates/README.org.template new file mode 100644 index 0000000..c5cf7ba --- /dev/null +++ b/core/templates/README.org.template @@ -0,0 +1,30 @@ +#+TITLE: %LAYER_NAME% layer + +# The maximum height of the logo should be 200 pixels. +[[img/%LAYER_NAME%.png]] + +# TOC links should be GitHub style anchors. +* Table of Contents :TOC_4_gh:noexport: + - [[#decsription][Description]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + +* Description +This layer does wonderful things: + - thing01 + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =%LAYER_NAME%= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key bindings + +| Key Binding | Description | +|-------------+----------------| +| ~SPC x x x~ | Does thing01 | +# Use GitHub URLs if you wish to link a Spacemacs documentation file or its heading. +# Examples: +# [[https://github.com/syl20bnr/spacemacs/blob/master/doc/VIMUSERS.org#sessions]] +# [[https://github.com/syl20bnr/spacemacs/blob/master/layers/%2Bfun/emoji/README.org][Link to Emoji layer README.org]] +# If space-doc-mode is enabled, Spacemacs will open a local copy of the linked file. diff --git a/core/templates/REPORTING.template b/core/templates/REPORTING.template new file mode 100644 index 0000000..5b0be96 --- /dev/null +++ b/core/templates/REPORTING.template @@ -0,0 +1,21 @@ +<> +#### Description :octocat: +<> + +#### Reproduction guide :beetle: +- Start Emacs +- <> + +*Observed behaviour:* :eyes: :broken_heart: +<> + +*Expected behaviour:* :heart: :smile: +<> + +(%LAST_KEYS%) +%SYSTEM_INFO% + +#### Backtrace :paw_prints: +``` +%BACKTRACE% +``` diff --git a/core/templates/packages.el.template b/core/templates/packages.el.template new file mode 100644 index 0000000..af6bce2 --- /dev/null +++ b/core/templates/packages.el.template @@ -0,0 +1,62 @@ +;;; packages.el --- %LAYER_NAME% layer packages file for Spacemacs. +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: %USER_FULL_NAME% <%USER_MAIL_ADDRESS%> +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;;; Commentary: + +;; See the Spacemacs documentation and FAQs for instructions on how to implement +;; a new layer: +;; +;; SPC h SPC layers RET +;; +;; +;; Briefly, each package to be installed or configured by this layer should be +;; added to `%LAYER_NAME%-packages'. Then, for each package PACKAGE: +;; +;; - If PACKAGE is not referenced by any other Spacemacs layer, define a +;; function `%LAYER_NAME%/init-PACKAGE' to load and initialize the package. + +;; - Otherwise, PACKAGE is already referenced by another Spacemacs layer, so +;; define the functions `%LAYER_NAME%/pre-init-PACKAGE' and/or +;; `%LAYER_NAME%/post-init-PACKAGE' to customize the package as it is loaded. + +;;; Code: + +(defconst %LAYER_NAME%-packages + '() + "The list of Lisp packages required by the %LAYER_NAME% layer. + +Each entry is either: + +1. A symbol, which is interpreted as a package to be installed, or + +2. A list of the form (PACKAGE KEYS...), where PACKAGE is the + name of the package to be installed or loaded, and KEYS are + any number of keyword-value-pairs. + + The following keys are accepted: + + - :excluded (t or nil): Prevent the package from being loaded + if value is non-nil + + - :location: Specify a custom installation location. + The following values are legal: + + - The symbol `elpa' (default) means PACKAGE will be + installed using the Emacs package manager. + + - The symbol `local' directs Spacemacs to load the file at + `./local/PACKAGE/PACKAGE.el' + + - A list beginning with the symbol `recipe' is a melpa + recipe. See: https://github.com/milkypostman/melpa#recipe-format") + + +;;; packages.el ends here diff --git a/core/tools/spacefmt/spacefmt b/core/tools/spacefmt/spacefmt new file mode 100755 index 0000000..de742c0 --- /dev/null +++ b/core/tools/spacefmt/spacefmt @@ -0,0 +1,77 @@ +#!/bin/bash +# ---------------------------------------------------------------------- +# Formatting/Migration tool for Spacemacs +# ---------------------------------------------------------------------- +# +# Authors: Eugene Yaremenko and Sylvain Benner +# +# Arguments: +# $1: action name can be `all`, `doc`, `config` +# `doc` formats documentation files +# `config` format configuration files +# `all` performs all actions +# $2: if equal to `test` then use test files as input + +# TODO a function to add headers to config.el, packages.el etc... + +if ! [ -d "./.git" ] +then + echo "Should be executed from the repo root." + exit 1 +fi + +#Use "sed" or "gsed" if avaliable. +seder="sed" +if hash gsed 2>/dev/null; then + seder="gsed" +fi + +#Use md5 or md5sum +mdfive="md5sum" +if hash md5 2>/dev/null; then + mdfive="md5" +fi + + +if [[ $2 = "test" ]] +then + places=("./core/tools/spacefmt/tests") +else + places=("./doc" "./layers") +fi + +for place in "${places[@]}" +do : + before_md5="foo" + after_md5="bar" + while ! [ "$before_md5" = "$after_md5" ] + do + # Calculate md5 of the files in $place before formating + before_md5=$(find $place -type f -exec $mdfive {} \; | sort -k 2 | $mdfive) + + if [ $1 = "all" ] || [ $1 == "doc" ] + then + # Remove trailing delimiters in headlines + find $place -name "*.org" -type f -exec $seder -i 's/^\(*\+\s\+.*\)[;,.]$/\1/g' {} \; + # Remove trailing spaces + find $place -name "*.org" -type f -exec $seder -i 's/[ \t]*$//' {} \; + # Remove #+HTML_HEAD_EXTRA: ... readtheorg.css" /> + find $place -name "*.org" -type f -exec $seder -i '/#+HTML_HEAD_EXTRA.*readtheorg.css.*/d' {} \; + # Replace multiply empty lines with a single empty line + find $place -name "*.org" -type f -exec $seder -i '/^$/N;/^\n$/D' {} \; + # Replace :TOC_4_org: with :TOC_4_gh: + find $place -name "*.org" -type f -exec $seder -i 's/:TOC_4_org:/:TOC_4_gh:/' {} \; + # apply toc-org + find $place -name "*.org" -type f -exec emacs -batch -l ./core/tools/spacefmt/spacefmt.el '{}' -f apply-all \; + fi + + if [ $1 = "all" ] || [ $1 == "config" ] + then + # migrate packages lists to config.el + find $place -name "packages.el" -type f -exec emacs -batch -l ./core/tools/spacefmt/spacefmt.el '{}' -f move-packages-to-config \; + fi + + # Calculate md5 of the files in $place after formating + after_md5=$(find $place -type f -exec $mdfive {} \; | sort -k 2 | $mdfive) + done +done diff --git a/core/tools/spacefmt/spacefmt.el b/core/tools/spacefmt/spacefmt.el new file mode 100644 index 0000000..cb3ea0a --- /dev/null +++ b/core/tools/spacefmt/spacefmt.el @@ -0,0 +1,169 @@ +;;; fmt.el --- .org file formatter. +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + +(load-file "./core/tools/spacefmt/toc-org.el") + +(require 'cl) +(require 'files) +(require 'org) +(require 'thingatpt) + +(defconst empty-line-regexp "^[ \t]*$") + +(defconst toc-heading-head "* Table of Contents") +(defconst toc-heading-tail ":TOC_4_gh:noexport:") +(defconst toc-headline (format "%-41s%s" + toc-heading-head + toc-heading-tail)) + +(defun apply-all () + "Apply all filters." + (remove-empty-lines-at-the-beginning) + (insert-title) + (insert-toc) + (apply-toc) + (remove-empty-lines-after-headlines) + ;; Multiply empty lines are handled by + ;; the bash script. + (insert-empty-line-before-tables) + (insert-empty-line-after-tables) + (insert-empty-line-after-sections) + (insert-empty-line-at-the-end) + (align-tables) + (save-buffer 0)) + +(defun remove-empty-lines-at-the-beginning () + "Remove empty lines at the begging of the buffer." + (goto-char (point-min)) + (while (looking-at-p empty-line-regexp) + (delete-blank-lines))) + +(defun insert-empty-line-at-the-end () + "Insert an empty line at the end of the buffer." + (goto-char (point-max)) + (unless (looking-at-p empty-line-regexp) + (open-line 1))) + +(defun insert-title() + "Insert #TITLE:{DIR_NAME} if the buffer doesn't have one." + (goto-char (point-min)) + (unless (looking-at-p "^#\\+TITLE:.*$") + (insert (format "#+TITLE:%s\n" + (clj/->> (buffer-file-name) + file-name-directory + directory-file-name + file-name-base))))) + +(defun insert-toc () + "Insert toc if the buffer doesn't have one." + (goto-char (point-min)) + (unless (re-search-forward toc-org-toc-org-regexp nil t) + (goto-char (point-max)) + ;; Skip from the end of the buffer to the first headling. + (while (re-search-backward org-heading-regexp nil t)) + (open-line 3) + (forward-line 1) + (insert-string toc-headline))) + +(defun remove-empty-lines-after-headlines() + "Remove empty liners after each headline." + (goto-char (point-min)) + (while (re-search-forward org-heading-regexp nil t) + (unless (= (forward-line) 0) + (while (looking-at-p empty-line-regexp) + (delete-blank-lines))))) + +(defun insert-empty-line-before-tables () + "Insert an empty line before each org table." + (goto-char (point-min)) + (while (goto-next-table) + (forward-line -1) + (unless (looking-at-p empty-line-regexp) + (end-of-line) + (open-line 1)) + (forward-line 1))) + +(defun insert-empty-line-after-sections () + "Insert an empty line after each section." + (goto-char (point-min)) + (while (re-search-forward org-heading-regexp nil t) + (forward-line -1) + (unless (or (looking-at-p empty-line-regexp) + (looking-at-p org-heading-regexp)) + (end-of-line) + (open-line 1)) + (forward-line 2))) + +(defun insert-empty-line-after-tables () + "Insert an empty line after each table." + (goto-char (point-min)) + (while (goto-next-table) + ;; Skip current table. + (while (looking-at-p org-table-any-line-regexp) + (forward-line)) + (unless (looking-at-p empty-line-regexp) + (beginning-of-line) + (open-line 1) + (forward-line)))) + +(defun align-tables () + "Align all tables" + (goto-char (point-min)) + (while (goto-next-table) + (org-table-align))) + +(defun apply-toc () + "Apply current toc-org TAG to TOC." + (goto-char (point-min)) + (toc-org-insert-toc)) + +(defun goto-next-table () + "Goto next org table. +Returns nil if no more tables left." + ;; Skip current table. + (while (looking-at-p org-table-any-line-regexp) + (forward-line)) + ;; Skip to the next table. + (when (re-search-forward org-table-hline-regexp nil t) + (forward-line -1 ))) + +(defun move-packages-to-config () + "Move xxx-packages list to config.el." + (let ((config-file (concat default-directory "config.el"))) + (when (or (re-search-forward "(setq.*-packages" nil t) + (re-search-forward "(defcustom.*-packages" nil t)) + (re-search-backward "(") + (kill-sexp) + (with-current-buffer (find-file-noselect config-file) + (when (file-exists-p config-file) + (re-search-forward ";;; License: GPLv3") + (newline) + (forward-line 2)) + (yank) + ;; config.el + (save-buffer 0)) + ;; packages.el + (save-buffer 0)))) + +(defmacro clj/->> (o &rest forms) + "Threads the expr through the forms. +Inserts o as the last item in the first form, +making a list of it if it is not a list already. +If there are more forms, inserts the first form +as the last item in second form, etc." + (cond ((not forms) o) + ((= 1 (length forms)) + (let ((f (first forms))) + (append (if (symbolp f) + (list f) f) + (list o)))) + (:else `(clj/->> (clj/->> ,o ,(first forms)) ,@(rest forms))))) diff --git a/core/tools/spacefmt/tests/config.el b/core/tools/spacefmt/tests/config.el new file mode 100644 index 0000000..4bc681b --- /dev/null +++ b/core/tools/spacefmt/tests/config.el @@ -0,0 +1,7 @@ +;;; packages.el --- test layer configuration file for Spacemacs. +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 diff --git a/core/tools/spacefmt/tests/packages.el b/core/tools/spacefmt/tests/packages.el new file mode 100644 index 0000000..f2f74de --- /dev/null +++ b/core/tools/spacefmt/tests/packages.el @@ -0,0 +1,9 @@ +;; Test file for packages.el formatting and migrations + +(setq mylayer-packages + '( + package1 + package2 + package3 + package4 + )) diff --git a/core/tools/spacefmt/tests/test.org b/core/tools/spacefmt/tests/test.org new file mode 100644 index 0000000..851f05c --- /dev/null +++ b/core/tools/spacefmt/tests/test.org @@ -0,0 +1,28 @@ + + + +#+HTML_HEAD_EXTRA: + + +* Links, +[[https://github.com/syl20bnr/spacemacs/blob/master/doc/FAQ.org#os-x][Link to FAQ "OS X" heading]] +[[https://www.google.com][Link to www.google.com]] +[[https://github.com/syl20bnr/spacemacs/blob/master/doc/VIMUSERS.org#sessions]] +[[https://github.com/syl20bnr/spacemacs/blob/master/layers/%2Bfun/emoji/README.org][Link to Emoji layer README.org]] +* FOO; +| Key Binding | Description | +|-------------+--------------------------------------------| + | ~SPC m d~ | lookup thing at point in lua documentation | +| ~SPC m s b~ | send buffer contents to REPL | +| ~SPC m s f~ | send current function to REPL | +| ~SPC m s l~ | send current line to REPL | +| ~SPC m s r~ | send current region to REPL | +=========================================================================== +** Org: +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed conseq +* BAR +** SUBBAR ; , . +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed conseq +* BAZ +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus. Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi. Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed conseq +* FOOBAZ diff --git a/core/tools/spacefmt/toc-org.el b/core/tools/spacefmt/toc-org.el new file mode 100644 index 0000000..30bb306 --- /dev/null +++ b/core/tools/spacefmt/toc-org.el @@ -0,0 +1,409 @@ +;;; toc-org.el --- add table of contents to org-mode files (formerly, org-toc) + +;; Copyright (C) 2014 Sergei Nosov + +;; Author: Sergei Nosov +;; Version: 1.0 +;; Keywords: org-mode org-toc toc-org org toc table of contents +;; URL: https://github.com/snosov1/toc-org + +;; 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: + +;; toc-org helps you to have an up-to-date table of contents in org files +;; without exporting (useful primarily for readme files on GitHub). + +;; NOTE: Previous name of the package is org-toc. It was changed because of a +;; name conflict with one of the org contrib modules. + +;; After installation put into your .emacs file something like + +;; (if (require 'toc-org nil t) +;; (add-hook 'org-mode-hook 'toc-org-enable) +;; (warn "toc-org not found")) + +;; And every time you'll be saving an org file, the first headline with a :TOC: +;; tag will be updated with the current table of contents. + +;; For details, see https://github.com/snosov1/toc-org + +;;; Code: + +(require 'ert) +(require 'org) + +(defgroup toc-org nil + "toc-org is a utility to have an up-to-date table of contents +in the org files without exporting (useful primarily for readme +files on GitHub)" + :group 'org) + +;; just in case, simple regexp "^*.*:toc:\\($\\|[^ ]*:$\\)" +(defconst toc-org-toc-org-regexp "^*.*:toc\\([@_][0-9]\\|\\([@_][0-9][@_][a-zA-Z]+\\)\\)?:\\($\\|[^ ]*:$\\)" + "Regexp to find the heading with the :toc: tag") +(defconst toc-org-tags-regexp "\s*:[[:word:]:@]*:\s*$" + "Regexp to find tags on the line") +(defconst toc-org-states-regexp "^*+\s+\\(TODO\s+\\|DONE\s+\\)" + "Regexp to find states on the line") +(defconst toc-org-links-regexp "\\[\\[\\(.*?\\)\\]\\[\\(.*?\\)\\]\\]" + "Regexp to find states on the line") +(defconst toc-org-special-chars-regexp "[^[:alnum:]_-]" + "Regexp with the special characters (which are omitted in hrefs + by GitHub)") + +(defcustom toc-org-max-depth 2 + "Maximum depth of the headings to use in the table of +contents. The default of 2 uses only the highest level headings +and their subheadings (one and two stars)." + :group 'toc-org) + +(defcustom toc-org-hrefify-default "gh" + "Default hrefify function to use." + :group 'toc-org) + +(defcustom toc-org-enable-links-opening t + "With this option, org-open-at-point (C-c C-o) should work on +the TOC links (even if the style is different from org)." + :group 'toc-org) + +(defvar-local toc-org-hrefify-hash nil + "Buffer local hash-table that is used to enable links +opening. The keys are hrefified headings, the values are original +headings.") + +(defun toc-org-raw-toc () + "Return the \"raw\" table of contents of the current file, +i.e. simply flush everything that's not a heading and strip +tags." + (let ((content (buffer-substring-no-properties + (point-min) (point-max)))) + (with-temp-buffer + (insert content) + (goto-char (point-min)) + (keep-lines "^\*+[ ]") + + ;; don't include the TOC itself + (goto-char (point-min)) + (re-search-forward toc-org-toc-org-regexp nil t) + (beginning-of-line) + (delete-region (point) (progn (forward-line 1) (point))) + + ;; strip states + (goto-char (point-min)) + (while (re-search-forward toc-org-states-regexp nil t) + (replace-match "" nil nil nil 1)) + + ;; strip tags + ;; TODO :export: and :noexport: tags semantic should be probably + ;; implemented + (goto-char (point-min)) + (while (re-search-forward toc-org-tags-regexp nil t) + (replace-match "" nil nil)) + + ;; flatten links + (goto-char (point-min)) + (while (re-search-forward toc-org-links-regexp nil t) + (replace-match "\\2" nil nil)) + + (buffer-substring-no-properties + (point-min) (point-max))))) + +(ert-deftest toc-org-test-raw-toc () + "Test the `toc-org-raw-toc' function" + + (defun toc-org-test-raw-toc-gold-test (content gold) + (should (equal + (with-temp-buffer + (insert content) + (toc-org-raw-toc)) + gold))) + (declare-function toc-org-test-raw-toc-gold-test "toc-org") ;; suppress compiler warning + + (let ((beg "* TODO [[http://somewhere.com][About]]\n:TOC:\n drawer\n:END:\n\ntoc-org is a utility to have an up-to-date table of contents in the\norg files without exporting (useful primarily for readme files on\nGitHub).\n\nIt is similar to the [[https://github.com/ardumont/markdown-toc][markdown-toc]] package, but works for org files.\n:TOC:\n drawer\n:END:\n\n* Table of Contents ") + (gold "* About\n")) + + ;; different TOC styles + (toc-org-test-raw-toc-gold-test (concat beg ":TOC:" ) gold) + (toc-org-test-raw-toc-gold-test (concat beg ":TOC_1:" ) gold) + (toc-org-test-raw-toc-gold-test (concat beg ":TOC_1_qqq:" ) gold) + (toc-org-test-raw-toc-gold-test (concat beg ":TOC@1:" ) gold) + (toc-org-test-raw-toc-gold-test (concat beg ":TOC@1@cxv:" ) gold) + (toc-org-test-raw-toc-gold-test (concat beg ":TOC@1_hello:" ) gold) + + ;; trailing symbols + (toc-org-test-raw-toc-gold-test (concat beg ":TOC@1_hello:" "\n\n\n") gold) + (toc-org-test-raw-toc-gold-test (concat beg ":TOC@1_hello:" "\n\n\nsdfd") gold)) + + ;; more complex case + (toc-org-test-raw-toc-gold-test + "* About\n:TOC:\n drawer\n:END:\n\ntoc-org is a utility to have an up-to-date table of contents in the\norg files without exporting (useful primarily for readme files on\nGitHub).\n\nIt is similar to the [[https://github.com/ardumont/markdown-toc][markdown-toc]] package, but works for org files.\n:TOC:\n drawer\n:END:\n\n* Table of Contents :TOC:\n - [[#about][About]]\n - [[#use][Use]]\n - [[#different-href-styles][Different href styles]]\n - [[#example][Example]]\n\n* Installation\n** via package.el\nThis is the simplest method if you have the package.el module\n(built-in since Emacs 24.1) you can simply use =M-x package-install=\nand then put the following snippet in your ~/.emacs file\n#+BEGIN_SRC elisp\n (eval-after-load \"toc-org-autoloads\"\n '(progn\n (if (require 'toc-org nil t)\n (add-hook 'org-mode-hook 'toc-org-enable)\n (warn \"toc-org not found\"))))\n#+END_SRC\n** Manual :Hello:\n- Create folder ~/.emacs.d if you don't have it\n- Go to it and clone toc-org there\n #+BEGIN_SRC sh\n git clone https://github.com/snosov1/toc-org.git\n #+END_SRC\n- Put this in your ~/.emacs file\n #+BEGIN_SRC elisp\n (add-to-list 'load-path \"~/.emacs.d/toc-org\")\n (when (require 'toc-org nil t)\n (add-hook 'org-mode-hook 'toc-org-enable))\n #+END_SRC\n\n* Use\n\nAfter the installation, every time you'll be saving an org file, the\nfirst headline with a :TOC: tag will be updated with the current table\nof contents.\n\nTo add a TOC tag, you can use the command =org-set-tags-command=.\n\nIn addition to the simple :TOC: tag, you can also use the following\ntag formats:\n\n- :TOC@2: - sets the max depth of the headlines in the table of\n contents to 2 (the default)\n\n- :TOC@2@gh: - sets the max depth as in above and also uses the\n GitHub-style hrefs in the table of contents (the default). The other\n supported href style is 'org', which is the default org style (you\n can use C-c C-o to go to the headline at point).\n\nYou can also use =_= as separator, instead of =@=.\n\n* Different href styles\n\nCurrently, only 2 href styles are supported: =gh= and =org=. You can easily\ndefine your own styles. If you use the tag =:TOC@2@STYLE:= (=STYLE= being a\nstyle name), then the package will look for a function named\n=toc-org-hrefify-STYLE=, which accepts a heading string and returns a href\ncorresponding to that heading.\n\nE.g. for =org= style it simply returns input as is:\n\n#+BEGIN_SRC emacs-lisp\n (defun toc-org-hrefify-org (str)\n \"Given a heading, transform it into a href using the org-mode\n rules.\"\n str)\n#+END_SRC\n\n* Example\n\n#+BEGIN_SRC org\n * About\n * Table of Contents :TOC:\n - [[#about][About]]\n - [[#installation][Installation]]\n - [[#via-packageel][via package.el]]\n - [[#manual][Manual]]\n - [[#use][Use]]\n * Installation\n ** via package.el\n ** Manual\n * Use\n * Example\n#+END_SRC\n" + "* About\n* Installation\n** via package.el\n** Manual\n* Use\n* Different href styles\n* Example\n")) + +(defun toc-org-hrefify-gh (str) + "Given a heading, transform it into a href using the GitHub +rules." + (let* ((spc-fix (replace-regexp-in-string " " "-" str)) + (upcase-fix (replace-regexp-in-string "[A-Z]" 'downcase spc-fix t)) + (special-chars-fix (replace-regexp-in-string toc-org-special-chars-regexp "" upcase-fix t))) + (concat "#" special-chars-fix))) + +(ert-deftest toc-org-test-hrefify-gh () + "Test the `toc-org-hrefify-gh' function" + (should (equal (toc-org-hrefify-gh "About") "#about")) + (should (equal (toc-org-hrefify-gh "!h@#$%^&*(){}|][:;\"'/?.>,<`~") "#h")) + (should (equal (toc-org-hrefify-gh "!h@#$% ^&*(S){}|][:;\"'/?.>,<`~") "#h-s"))) + +(defun toc-org-hrefify-org (str) + "Given a heading, transform it into a href using the org-mode +rules." + str) + +(defun toc-org-unhrefify (type path) + "Looks for a value in toc-org-hrefify-hash using path as a key." + (let ((ret-type type) + (ret-path path) + (original-path (and (not (eq toc-org-hrefify-hash nil)) + (gethash + (concat + ;; Org 8.3 and above provides type as "custom-id" + ;; and strips the leading hash symbol + (if (equal type "custom-id") "#" "") + (substring-no-properties path)) + toc-org-hrefify-hash + nil)))) + (when toc-org-enable-links-opening + (when original-path + ;; Org 8.2 and below provides type as "thisfile" + (when (equal type "thisfile") + (setq ret-path original-path)) + (when (equal type "custom-id") + (setq ret-type "fuzzy") + (setq ret-path original-path)))) + (cons ret-type ret-path))) + +(defun toc-org-hrefify-toc (toc hrefify &optional hash) + "Format the raw `toc' using the `hrefify' function to transform +each heading into a link." + (with-temp-buffer + (insert toc) + (goto-char (point-min)) + + (while + (progn + (when (looking-at "\\*") + (delete-char 1) + + (while (looking-at "\\*") + (delete-char 1) + (insert (make-string + (+ 2 (or (bound-and-true-p org-list-indent-offset) 0)) + ?\s))) + + (skip-chars-forward " ") + (insert "- ") + + (let* ((beg (point)) + (end (line-end-position)) + (heading (buffer-substring-no-properties + beg end)) + (hrefified (funcall hrefify heading))) + (insert "[[") + (insert hrefified) + (insert "][") + (end-of-line) + (insert "]]") + + ;; maintain the hash table, if provided + (when hash + (puthash hrefified heading hash))) + (= 0 (forward-line 1))))) + + (buffer-substring-no-properties + (point-min) (point-max)))) + +(ert-deftest toc-org-test-hrefify-toc () + (let ((hash (make-hash-table :test 'equal))) + (should (equal (toc-org-hrefify-toc "* About\n" 'upcase hash) + " - [[ABOUT][About]]\n")) + (should (equal (gethash "ABOUT" hash) "About"))) + (let ((hash (make-hash-table :test 'equal))) + (should (equal (toc-org-hrefify-toc "* About\n* Installation\n** via package.el\n** Manual\n* Use\n* Different href styles\n* Example\n" 'upcase hash) + " - [[ABOUT][About]]\n - [[INSTALLATION][Installation]]\n - [[VIA PACKAGE.EL][via package.el]]\n - [[MANUAL][Manual]]\n - [[USE][Use]]\n - [[DIFFERENT HREF STYLES][Different href styles]]\n - [[EXAMPLE][Example]]\n")) + (should (equal (gethash "ABOUT" hash) "About")) + (should (equal (gethash "INSTALLATION" hash) "Installation")) + (should (equal (gethash "VIA PACKAGE.EL" hash) "via package.el")) + (should (equal (gethash "MANUAL" hash) "Manual")) + (should (equal (gethash "USE" hash) "Use")) + (should (equal (gethash "DIFFERENT HREF STYLES" hash) "Different href styles")) + (should (equal (gethash "EXAMPLE" hash) "Example")))) + +(defun toc-org-flush-subheadings (toc max-depth) + "Flush subheadings of the raw `toc' deeper than `max-depth'." + (with-temp-buffer + (insert toc) + (goto-char (point-min)) + + (let ((re "^")) + (dotimes (i (1+ max-depth)) + (setq re (concat re "\\*"))) + (flush-lines re)) + + (buffer-substring-no-properties + (point-min) (point-max)))) + +(ert-deftest toc-org-test-flush-subheadings () + (should (equal (toc-org-flush-subheadings "* About\n" 0) + "")) + (should (equal (toc-org-flush-subheadings "* About\n" 1) + "* About\n")) + (should (equal (toc-org-flush-subheadings "* About\n" 2) + "* About\n")) + + (should (equal (toc-org-flush-subheadings "* About\n* Installation\n** via package.el\n** Manual\n* Use\n* Different href styles\n* Example\n" 0) + "")) + (should (equal (toc-org-flush-subheadings "* About\n* Installation\n** via package.el\n** Manual\n* Use\n* Different href styles\n* Example\n" 1) + "* About\n* Installation\n* Use\n* Different href styles\n* Example\n")) + (should (equal (toc-org-flush-subheadings "* About\n* Installation\n** via package.el\n** Manual\n* Use\n* Different href styles\n* Example\n" 2) + "* About\n* Installation\n** via package.el\n** Manual\n* Use\n* Different href styles\n* Example\n")) + (should (equal (toc-org-flush-subheadings "* About\n* Installation\n** via package.el\n** Manual\n* Use\n* Different href styles\n* Example\n" 3) + "* About\n* Installation\n** via package.el\n** Manual\n* Use\n* Different href styles\n* Example\n"))) + +(defun toc-org-insert-toc (&optional dry-run) + "Looks for a headline with the TOC tag and updates it with the +current table of contents. + +If optional second argument DRY-RUN is provided, then the buffer +is not modified at all. Only the internal hash-table is updated +to enable `org-open-at-point' for TOC links. + +To add a TOC tag, you can use the command +`org-set-tags-command' (C-c C-q). + +In addition to the simple :TOC: tag, you can also use the +following tag formats: + +- :TOC_2: - sets the max depth of the headlines in the table of + contents to 2 (the default) + +- :TOC_2_gh: - sets the max depth as in above and also uses the + GitHub-style hrefs in the table of contents (this style is + default). The other supported href style is 'org', which is the + default org style." + + (interactive) + (when (eq major-mode 'org-mode) + (save-excursion + (goto-char (point-min)) + (let ((case-fold-search t)) + ;; find the first heading with the :TOC: tag + (when (re-search-forward toc-org-toc-org-regexp (point-max) t) + (let* ((tag (match-string 1)) + (depth (if tag + (- (aref tag 1) ?0) ;; is there a better way to convert char to number? + toc-org-max-depth)) + (hrefify-tag (if (and tag (>= (length tag) 4)) + (downcase (substring tag 3)) + toc-org-hrefify-default)) + (hrefify-string (concat "toc-org-hrefify-" hrefify-tag)) + (hrefify (intern-soft hrefify-string))) + (if hrefify + (let ((new-toc + (toc-org-hrefify-toc + (toc-org-flush-subheadings (toc-org-raw-toc) depth) + hrefify + (when toc-org-hrefify-hash + (clrhash toc-org-hrefify-hash))))) + (unless dry-run + (newline (forward-line 1)) + + ;; insert newline if TOC is currently empty + (when (looking-at "^\\*") + (open-line 1)) + + ;; find TOC boundaries + (let ((beg (point)) + (end + (save-excursion + (when (search-forward-regexp "^\\*" (point-max) t) + (forward-line -1)) + (end-of-line) + (point)))) + ;; update the TOC, but only if it's actually different + ;; from the current one + (unless (equal + (buffer-substring-no-properties beg end) + new-toc) + (delete-region beg end) + (insert new-toc))))) + (message (concat "Hrefify function " hrefify-string " is not found"))))))))) + +;;;###autoload +(defun toc-org-enable () + "Enable toc-org in this buffer." + (add-hook 'before-save-hook 'toc-org-insert-toc nil t) + + ;; conservatively set org-link-translation-function + (when (and (equal toc-org-enable-links-opening t) + (or + (not (fboundp org-link-translation-function)) + (equal org-link-translation-function 'toc-org-unhrefify))) + (setq toc-org-hrefify-hash (make-hash-table :test 'equal)) + (setq org-link-translation-function 'toc-org-unhrefify) + (toc-org-insert-toc t))) + +(ert-deftest toc-org-test-insert-toc () + "Test the `toc-org-insert-toc' function" + + (defun toc-org-test-insert-toc-gold-test (content gold) + (with-temp-buffer + (org-mode) + (insert content) + (toc-org-raw-toc) + (toc-org-insert-toc) + (should (equal + (buffer-substring-no-properties + (point-min) (point-max)) + gold)))) + (declare-function toc-org-test-insert-toc-gold-test "toc-org") ;; suppress compiler warning + + (let ((beg "* About\n:TOC:\n drawer\n:END:\n\ntoc-org is a utility to have an up-to-date table of contents in the\norg files without exporting (useful primarily for readme files on\nGitHub).\n\nIt is similar to the [[https://github.com/ardumont/markdown-toc][markdown-toc]] package, but works for org files.\n:TOC:\n drawer\n:END:\n* Hello\n** Good-bye\n*** Salut\n* Table of Contents ")) + (toc-org-test-insert-toc-gold-test + (concat beg ":TOC:") + "* About\n:TOC:\n drawer\n:END:\n\ntoc-org is a utility to have an up-to-date table of contents in the\norg files without exporting (useful primarily for readme files on\nGitHub).\n\nIt is similar to the [[https://github.com/ardumont/markdown-toc][markdown-toc]] package, but works for org files.\n:TOC:\n drawer\n:END:\n* Hello\n** Good-bye\n*** Salut\n* Table of Contents :TOC:\n - [[#about][About]]\n - [[#hello][Hello]]\n - [[#good-bye][Good-bye]]\n") + + (toc-org-test-insert-toc-gold-test + (concat beg ":TOC_1:") + "* About\n:TOC:\n drawer\n:END:\n\ntoc-org is a utility to have an up-to-date table of contents in the\norg files without exporting (useful primarily for readme files on\nGitHub).\n\nIt is similar to the [[https://github.com/ardumont/markdown-toc][markdown-toc]] package, but works for org files.\n:TOC:\n drawer\n:END:\n* Hello\n** Good-bye\n*** Salut\n* Table of Contents :TOC_1:\n - [[#about][About]]\n - [[#hello][Hello]]\n") + + (toc-org-test-insert-toc-gold-test + (concat beg ":TOC_3:") + "* About\n:TOC:\n drawer\n:END:\n\ntoc-org is a utility to have an up-to-date table of contents in the\norg files without exporting (useful primarily for readme files on\nGitHub).\n\nIt is similar to the [[https://github.com/ardumont/markdown-toc][markdown-toc]] package, but works for org files.\n:TOC:\n drawer\n:END:\n* Hello\n** Good-bye\n*** Salut\n* Table of Contents :TOC_3:\n - [[#about][About]]\n - [[#hello][Hello]]\n - [[#good-bye][Good-bye]]\n - [[#salut][Salut]]\n") + + (toc-org-test-insert-toc-gold-test + (concat beg ":TOC_1_org:") + "* About\n:TOC:\n drawer\n:END:\n\ntoc-org is a utility to have an up-to-date table of contents in the\norg files without exporting (useful primarily for readme files on\nGitHub).\n\nIt is similar to the [[https://github.com/ardumont/markdown-toc][markdown-toc]] package, but works for org files.\n:TOC:\n drawer\n:END:\n* Hello\n** Good-bye\n*** Salut\n* Table of Contents :TOC_1_org:\n - [[About][About]]\n - [[Hello][Hello]]\n") + + (toc-org-test-insert-toc-gold-test + (concat beg ":TOC_3_org:") + "* About\n:TOC:\n drawer\n:END:\n\ntoc-org is a utility to have an up-to-date table of contents in the\norg files without exporting (useful primarily for readme files on\nGitHub).\n\nIt is similar to the [[https://github.com/ardumont/markdown-toc][markdown-toc]] package, but works for org files.\n:TOC:\n drawer\n:END:\n* Hello\n** Good-bye\n*** Salut\n* Table of Contents :TOC_3_org:\n - [[About][About]]\n - [[Hello][Hello]]\n - [[Good-bye][Good-bye]]\n - [[Salut][Salut]]\n"))) + +;; Local Variables: +;; compile-command: "emacs -batch -l ert -l *.el -f ert-run-tests-batch-and-exit && emacs -batch -f batch-byte-compile *.el 2>&1 | sed -n '/Warning\|Error/p' | xargs -r ls" +;; End: + +(provide 'toc-org) +;;; toc-org.el ends here diff --git a/doc/CONVENTIONS.org b/doc/CONVENTIONS.org new file mode 100644 index 0000000..76cfc4f --- /dev/null +++ b/doc/CONVENTIONS.org @@ -0,0 +1,376 @@ +#+TITLE: Spacemacs Conventions + +* Spacemacs conventions :TOC_4_gh:noexport: + - [[#code-guidelines][Code guidelines]] + - [[#spacemacs-core-and-layer][Spacemacs core and layer]] + - [[#all-layers][All layers]] + - [[#use-package][Use-package]] + - [[#key-bindings-conventions][Key bindings conventions]] + - [[#reserved-prefix][Reserved prefix]] + - [[#user-prefix][User prefix]] + - [[#major-mode-prefix][Major mode prefix]] + - [[#transient-state][Transient-state]] + - [[#evilified-buffers][Evilified buffers]] + - [[#navigation][Navigation]] + - [[#n-and-n][n and N]] + - [[#code-navigation][Code Navigation]] + - [[#insert-state-buffers][=insert state= buffers]] + - [[#confirm-and-abort][Confirm and Abort]] + - [[#evaluation][Evaluation]] + - [[#repls][REPLs]] + - [[#send-code][Send code]] + - [[#in-terminal][In terminal]] + - [[#building-and-compilation][Building and Compilation]] + - [[#debugging][Debugging]] + - [[#plain-text-markup-languages][Plain Text Markup Languages]] + - [[#headers][Headers]] + - [[#insertion-of-common-elements][Insertion of common elements]] + - [[#text-manipulation][Text manipulation]] + - [[#movement-in-normal-mode][Movement in normal mode]] + - [[#promotion-demotion-and-element-movement][Promotion, Demotion and element movement]] + - [[#table-editing][Table editing]] + - [[#tests][Tests]] + - [[#all-languages][All languages]] + - [[#language-specific][Language specific]] + - [[#toggles][Toggles]] + - [[#refactoring][Refactoring]] + - [[#code-formatting][Code Formatting]] + - [[#help-or-documentation][Help or Documentation]] + - [[#writing-documentation][Writing documentation]] + - [[#spacing-in-documentation][Spacing in documentation]] + +* Code guidelines +** Spacemacs core and layer +Function names follow these conventions: + - =spacemacs/xxx= is an interactive function called =xxx= + - =spacemacs//xxx= is a private function called =xxx= (implementation details) + - =spacemacs|xxx= is a /macro/ called =xxx= + +Variables follow these conventions: + - =spacemacs-xxx= is a variable + - =spacemacs--xxx= is a private variable (implementation details) + +** All layers +A package is initialized in a function with name =/init-xxx= where: + - == is the layer name + - =xxx= is the package name + +** Use-package +- Always use =progn= when a code block requires multiple lines for =:init= or + =:config= keywords. +- If there is only one line of code then try to keep =:init= or =:config= + keywords on the same line. +- Don't nest multiple =use-package= calls unless you have a very good reason + to do it. + +* Key bindings conventions +** Reserved prefix +*** User prefix +~SPC o~ and ~SPC m o~ must not be used by any layer. They are reserved for the +user. + +*** Major mode prefix +~SPC m~ is reserved for the current major mode. Three keys bindings are not an +issue (ie. ~SPC m h d~) since ~SPC m~ can be accessed via ~​,​~. + +*** Transient-state +Whenever possible a transient-state should be enabled with ~M-SPC~ and ~s-M-SPC~. We +need the latter bindings on OS X since ~M-SPC~ is used by the OS for spotlight. + +For instance transient-states dedicated to special buffers like =helm= or =ido= +buffers are good candidates to be put on ~M-SPC~ and ~s-M-SPC~. + +It is recommended to add ~q~ to leave the transient-state. + +** Evilified buffers +/Evilifying/ a buffer is to set the =evilified state= as the default +state for the major mode of the buffer. + +The =evilified state= is derived from the =emacs state= and modify the +map to: +- add ~hjkl~ navigation +- add scrolling feature on ~C-f~, ~C-b~, ~C-d~ and ~C-u~ +- ~G~ and ~gg~ to go to the end and beginning of the buffer +- add incremental search with ~/~, ~n~ and ~N~ +- enabling =evil-ex= on ~:~ +- add =visual state= and =visual line state= on ~v~ and ~V~ +- add yank on ~y~ _in visual state only_ +- activate evil-leader key on ~SPC~ + +Setting the =evilified state= to a mode is done by calling the macro +=spacemacs|evilify-map=. + +/Evilification/ rebinds shadowed key bindings according to the following +rules: +- alphabetic key bindings: ~x~ -> ~X~ -> ~C-x~ -> ~C-X~ +- ~SPC~ -> ~​'​~ +- ~/~ -> ~\~ +- ~:~ -> ~|~ +- ~C-g~ cannot be shadowed + +If a key binding cannot be remapped then it is ignored and a warning message +is displayed in =*Messages*=. + +** Navigation +*** n and N +To be consistent with the Vim way, ~n~ and ~N~ are favored over Emacs ~n~ and +~p~. + +Ideally a transient-state should be provided to smooth the navigation +experience. A transient-state allows to repeat key bindings without entering +each time the prefix commands. More info on transient-states in the +[[file:DOCUMENTATION.org::Transient-states][documentation]]. + +*** Code Navigation +The prefix for going to something is ~SPC m g~. + +| Key | Description | +|---------+-------------------------------------------------| +| ~m g a~ | go to alternate file (i.e. =.h <--> .cpp=) | +| ~m g b~ | go back to previous location (before last jump) | +| ~m g g~ | go to things under point | +| ~m g G~ | go to things under point in other window | +| ~m g t~ | go to corresponding test file if any | + +*** =insert state= buffers +Navigation in buffers like =Helm= and =ido= which are in =insert state= +should be performed with ~C-j~ and ~C-k~ bindings for vertical movements. + +| Key | Description | +|-------+-------------| +| ~C-j~ | go down | +| ~C-k~ | go up | + +** Confirm and Abort +Confirming and aborting actions which are bound to ~C-c C-c~ and ~C-c C-k~ +in raw Emacs are mirrored in Spacemacs to: + +| Key | Description | +|-------------------------+---------------------------| +| ~SPC m ​,​~ and ~SPC m c~ | Valid/Confirm the message | +| ~SPC m a~ and ~SPC m k~ | Abort/Discard the message | + +Some example of these modes are =magit= commit messages, =message-mode= for +mails or =org-mode= notes. + +** Evaluation +Live evaluation of code is under the prefix ~SPC m e~. + +| Key | Description | +|---------+-----------------------------------------------| +| ~m e $~ | put point at the end of the line and evaluate | +| ~m e b~ | evaluate buffer | +| ~m e e~ | evaluate last expression | +| ~m e f~ | evaluate function | +| ~m e l~ | evaluate line | +| ~m e r~ | evaluate region | + +** REPLs +*** Send code +A lot of languages can interact with a REPL. To help keeping a +consistent behavior between those languages the following conventions +should be followed: + - ~SPC m s~ is the prefix for sending code. This allows fast interaction with + the REPL whenever it is possible + - lower case key bindings keep the focus on the current buffer + - upper case key bindings move the focus to the REPL buffer + +| Key | Description | +|---------+--------------------------------------------------------------| +| ~m s b~ | send buffer | +| ~m s B~ | send buffer and switch to REPL | +| ~m s d~ | first key to send buffer and switch to REPL to debug (step) | +| ~m s D~ | second key to send buffer and switch to REPL to debug (step) | +| ~m s f~ | send function | +| ~m s F~ | send function and switch to REPL | +| ~m s i~ | start/switch to REPL inferior process | +| ~m s l~ | send line | +| ~m s L~ | send line and switch to REPL | +| ~m s r~ | send region | +| ~m s R~ | send region and switch to REPL | + +Note: we don't distinguish between the file and the buffer. + +*** In terminal +History navigation in shells or REPLs buffers should be bound as well to +~C-j~ and ~C-k~. + + | Key | Description | + |-------+----------------------------| + | ~C-j~ | next item in history | + | ~C-k~ | previous item in history | + | ~C-l~ | clear screen | + | ~C-r~ | search backward in history | + +** Building and Compilation +The base prefix for major mode specific compilation is ~SPC m c~. + + | Key Binding | Description | + |-------------+-------------------| + | ~m c b~ | compile buffer | + | ~m c c~ | compile | + | ~m c r~ | clean and compile | + +Note: we don't distinguish between the file and the buffer. We can +implement an auto-save of the buffer before compiling the buffer. + +** Debugging +The base prefix for debugging commands is ~SPC d~. + +| Key Binding | Description | +|-------------+-------------------------| +| ~m d a~ | abandon current process | +| ~m d b~ | toggle a breakpoint | +| ~m d B~ | clear all breakpoints | +| ~m d c~ | continue | +| ~m d d~ | start debug session | +| ~m d i~ | inspect value at point | +| ~m d l~ | local variables | +| ~m d n~ | next | +| ~m d r~ | run | +| ~m d s~ | step | + +Notes: + - Ideally a transient-state for breakpoint navigation should be provided. + - If there is no toggle breakpoint function, then it should be implemented at + the spacemacs level and ideally the function should be proposed as a patch + upstream (major mode repository). + +** Plain Text Markup Languages +For layers supporting markup languages please follow the following +keybindings whenever applicable. + +*** Headers +All header functionality should be grouped under ~SPC m h~ + +| Key Binding | Description | +|-------------+--------------------------------------------------| +| ~m h i~ | Insert a header | +| ~m h I~ | Insert a header alternative method (if existing) | +| ~m h 1..10~ | Insert a header of level 1..10 (if possible) | + +*** Insertion of common elements +Insertion of common elements like links or footnotes should be grouped +under ~SPC m i~ + +| Key Binding | Description | +|-------------+------------------| +| ~m i f~ | Insert footnote | +| ~m i i~ | Insert image | +| ~m i l~ | Insert link | +| ~m i u~ | Insert url | +| ~m i w~ | Insert wiki-link | + +*** Text manipulation +Manipulation of text regions should be grouped under ~SPC m x~ + +| Key Binding | Description | +|-------------+-------------------------------| +| ~m x b~ | Make region bold | +| ~m x c~ | Make region code | +| ~m x i~ | Make region italic | +| ~m x q~ | Quote a region | +| ~m x r~ | Remove formatting from region | +| ~m x s~ | Make region strike-through | +| ~m x u~ | Make region underlined | +| ~m x v~ | Make region verbose | + +*** Movement in normal mode +In normal mode Vim style movement should be enabled with these keybindings: + +| Key Binding | Description | +|-------------+----------------------------------------| +| ~g h~ | Move up one level in headings | +| ~g j~ | Move to next heading on same level | +| ~g k~ | Move to previous heading on same level | +| ~g l~ | Move down one level in headings | + +*** Promotion, Demotion and element movement +Promotion, demotion and movement of headings or list elements (whatever is +possible) should be enabled with the following keys in any mode + +| Key Binding | Description | +|-------------+------------------------------| +| ~M-h~ | Promote heading by one level | +| ~M-j~ | Move element down | +| ~M-k~ | Move element up | +| ~M-l~ | Demote heading by one level | + +*** Table editing +If table specific commands are available the they are grouped under the +~SPC m t~ group. + +** Tests +A lot of languages have their own test frameworks. These frameworks +share common actions that we can unite under the same key bindings: + - ~SPC m t~ is the prefix for test execution. + - ~SPC m t X~ is used to execute ~SPC m t x~ but in debug mode (if supported). + +*** All languages + +| Key | Description | +|---------+--------------------------------------------------------------| +| ~m t a~ | execute all the tests of the current project | +| ~m t A~ | execute all the tests of the current project in debug | +| ~m t b~ | execute all the tests of the current buffer | +| ~m t B~ | execute all the tests of the current buffer in debug | +| ~m t t~ | execute the current test (thing at point, function) | +| ~m t T~ | execute the current test in debug (thing at point, function) | + +Note: we don't distinguish between the file and the buffer. We can +implement an auto-save of the buffer before executing the tests of +buffer. + +*** Language specific + +| Key | Description | +|---------+--------------------------------------------------| +| ~m t m~ | execute the tests of the current module | +| ~m t M~ | execute the tests of the current module in debug | +| ~m t s~ | execute the tests of the current suite | +| ~m t S~ | execute the tests of the current suite in debug | + +Note that there are overlaps, depending on the language we will choose +one or more bindings for the same thing + +** Toggles +- Global toggles are under ~SPC t~, ~SPC T~ and ~SPC C-t~ +- Major mode toggles are only under ~SPC m T~ + +** Refactoring +Refactoring prefix is ~SPC m r~. + +** Code Formatting +Major-mode code formatting is under prefix ~SPC m =~. + +| Key Binding | Description | +|-------------+--------------------------| +| ~m = =~ | format thing under point | +| ~m = b~ | format current buffer | +| ~m = f~ | format current function | + +** Help or Documentation +The base prefix for help commands is ~SPC h~. Documentation is considered +as an help command. + +| Key | Description | +|---------+------------------------------------| +| ~m h h~ | documentation of thing under point | +| ~m h r~ | documentation of selected region | + +* Writing documentation +Spacemacs provides an example layer =README.org= file in +=~/.emacs.d/core/templates/README.org.template=. + +** Spacing in documentation +- Spacemacs tries to keep the documentation consistent between all layers by + providing some rules for spacing: + - After each header, you should not add an empty line + - *Exception*: If the first item under the header is a table, add an empty + line after it + - At the end of each header node, there should be an empty line + - Note: Many layer =READMEs= do not follow this convention yet. Please fix + them if you can. + +- To keep things readable only mention the prefix ~SPC~ when documenting + key bindings, you don't need to mention ~M-m~. diff --git a/doc/DOCUMENTATION.org b/doc/DOCUMENTATION.org new file mode 100644 index 0000000..7e4d4b6 --- /dev/null +++ b/doc/DOCUMENTATION.org @@ -0,0 +1,3258 @@ +#+TITLE: Spacemacs documentation + +* Spacemacs documentation :TOC_4_gh:noexport: + - [[#core-pillars][Core Pillars]] + - [[#mnemonic][Mnemonic]] + - [[#discoverable][Discoverable]] + - [[#consistent][Consistent]] + - [[#crowd-configured][Crowd-Configured]] + - [[#highlighted-feature][Highlighted feature]] + - [[#screenshots][Screenshots]] + - [[#who-can-benefit-from-this][Who can benefit from this?]] + - [[#update-and-rollback][Update and Rollback]] + - [[#update-spacemacs-repository][Update Spacemacs repository]] + - [[#automatic-updates][Automatic Updates]] + - [[#updating-from-the-spacemacs-buffer][Updating from the Spacemacs Buffer]] + - [[#updating-manually-with-git][Updating Manually with git]] + - [[#update-packages][Update packages]] + - [[#configuration-layers][Configuration layers]] + - [[#purpose][Purpose]] + - [[#structure][Structure]] + - [[#configure-packages][Configure packages]] + - [[#with-a-layer][With a layer]] + - [[#declaration][Declaration]] + - [[#initialization][Initialization]] + - [[#exclusion][Exclusion]] + - [[#without-a-layer][Without a layer]] + - [[#packages-synchronization][Packages synchronization]] + - [[#types-of-configuration-layers][Types of configuration layers]] + - [[#submitting-a-configuration-layer-upstream][Submitting a configuration layer upstream]] + - [[#example-themes-megapack-example][Example: Themes Megapack example]] + - [[#managing-private-configuration-layers][Managing private configuration layers]] + - [[#using-the-private-directory][Using the private directory]] + - [[#using-an-external-git-repository][Using an external Git repository]] + - [[#using-a-personal-branch][Using a personal branch]] + - [[#tips-for-writing-layers][Tips for writing layers]] + - [[#dotfile-configuration][Dotfile Configuration]] + - [[#dotfile-installation][Dotfile Installation]] + - [[#alternative-dotdirectory][Alternative dotdirectory]] + - [[#synchronization-of-dotfile-changes][Synchronization of dotfile changes]] + - [[#testing-the-dotfile][Testing the dotfile]] + - [[#dotfile-contents][Dotfile Contents]] + - [[#configuration-functions][Configuration functions]] + - [[#custom-variables][Custom variables]] + - [[#declaring-configuration-layers][Declaring Configuration layers]] + - [[#setting-configuration-layers-variables][Setting configuration layers variables]] + - [[#disabling-layer-services-in-other-layers][Disabling layer services in other layers]] + - [[#selectingignoring-packages-of-a-layer][Selecting/Ignoring packages of a layer]] + - [[#excluding-packages][Excluding packages]] + - [[#concepts][Concepts]] + - [[#editing-styles][Editing Styles]] + - [[#vim][Vim]] + - [[#emacs][Emacs]] + - [[#hybrid][Hybrid]] + - [[#states][States]] + - [[#evilified-modes][Evilified modes]] + - [[#evil-leader][Evil leader]] + - [[#universal-argument][Universal argument]] + - [[#transient-states][Transient-states]] + - [[#differences-between-vim-evil-and-spacemacs][Differences between Vim, Evil and Spacemacs]] + - [[#the-vim-surround-case][The vim-surround case]] + - [[#evil-plugins][Evil plugins]] + - [[#binding-keys][Binding keys]] + - [[#gui-elements][GUI Elements]] + - [[#color-themes][Color themes]] + - [[#font][Font]] + - [[#gui-toggles][GUI Toggles]] + - [[#global-line-numbers][Global line numbers]] + - [[#mode-line][Mode-line]] + - [[#powerline-font-installation-for-terminal-mode-users][Powerline font installation for terminal-mode users]] + - [[#flycheck-integration][Flycheck integration]] + - [[#anzu-integration][Anzu integration]] + - [[#battery-status-integration][Battery status integration]] + - [[#powerline-separators][Powerline separators]] + - [[#minor-modes][Minor Modes]] + - [[#customizing-the-mode-line][Customizing the mode-line]] + - [[#layouts-and-workspaces][Layouts and workspaces]] + - [[#layouts][Layouts]] + - [[#the-default-layout][The default layout]] + - [[#project-layouts][Project layouts]] + - [[#custom-layouts][Custom Layouts]] + - [[#saveload-layouts-into-a-file][Save/Load layouts into a file]] + - [[#layout-key-bindings][Layout key bindings]] + - [[#workspaces][Workspaces]] + - [[#workspace-key-bindings][Workspace key bindings]] + - [[#commands][Commands]] + - [[#vim-key-bindings][Vim key bindings]] + - [[#escaping][Escaping]] + - [[#executing-vim-and-emacs-exm-x-commands][Executing Vim and Emacs ex/M-x commands]] + - [[#leader-key][Leader key]] + - [[#additional-text-objects][Additional text objects]] + - [[#reserved-prefix-command-for-user][Reserved prefix command for user]] + - [[#completion][Completion]] + - [[#helm][Helm]] + - [[#c-z-and-tab-switch][C-z and Tab switch]] + - [[#helm-focus][Helm focus]] + - [[#helm-transient-state][Helm transient state]] + - [[#discovering][Discovering]] + - [[#key-bindings][Key bindings]] + - [[#which-key][Which-key]] + - [[#helm-describe-key-bindings][Helm describe key bindings]] + - [[#getting-help][Getting help]] + - [[#available-layers][Available layers]] + - [[#available-packages-in-spacemacs][Available packages in Spacemacs]] + - [[#new-packages-from-elpa-repositories][New packages from ELPA repositories]] + - [[#toggles][Toggles]] + - [[#navigating][Navigating]] + - [[#pointcursor][Point/Cursor]] + - [[#smooth-scrolling][Smooth scrolling]] + - [[#vim-motions-with-avy][Vim motions with avy]] + - [[#ace-link-mode][ace-link mode]] + - [[#unimpaired-bindings][Unimpaired bindings]] + - [[#jumping-joining-and-splitting][Jumping, Joining and Splitting]] + - [[#jumping][Jumping]] + - [[#joining-and-splitting][Joining and splitting]] + - [[#window-manipulation][Window manipulation]] + - [[#window-manipulation-key-bindings][Window manipulation key bindings]] + - [[#window-manipulation-transient-state][Window manipulation transient state]] + - [[#golden-ratio][Golden ratio]] + - [[#buffers-and-files][Buffers and Files]] + - [[#buffers-manipulation-key-bindings][Buffers manipulation key bindings]] + - [[#buffers-manipulation-transient-state][Buffers manipulation transient state]] + - [[#special-buffers][Special Buffers]] + - [[#files-manipulations-key-bindings][Files manipulations key bindings]] + - [[#emacs-and-spacemacs-files][Emacs and Spacemacs files]] + - [[#browsing-files-with-helm][Browsing files with Helm]] + - [[#ido][Ido]] + - [[#ido-transient-state][Ido transient state]] + - [[#neotree-file-tree][NeoTree file tree]] + - [[#neotree-navigation][NeoTree navigation]] + - [[#opening-files-with-neotree][Opening files with NeoTree]] + - [[#other-neotree-key-bindings][Other NeoTree key bindings]] + - [[#neotree-mode-line][NeoTree mode-line]] + - [[#neotree-source-control-integration][NeoTree Source Control Integration]] + - [[#neotree-theme][NeoTree Theme]] + - [[#bookmarks][Bookmarks]] + - [[#docview-mode][DocView mode]] + - [[#auto-saving][Auto-saving]] + - [[#frequency-of-auto-saving][Frequency of auto-saving]] + - [[#location-of-auto-saved-files][Location of auto-saved files]] + - [[#disable-auto-save][Disable auto-save]] + - [[#searching][Searching]] + - [[#with-an-external-tool][With an external tool]] + - [[#useful-key-bindings][Useful key bindings]] + - [[#searching-in-current-file][Searching in current file]] + - [[#searching-in-all-open-buffers-visiting-files][Searching in all open buffers visiting files]] + - [[#searching-in-files-in-an-arbitrary-directory][Searching in files in an arbitrary directory]] + - [[#searching-in-a-project][Searching in a project]] + - [[#searching-the-web][Searching the web]] + - [[#persistent-highlighting][Persistent highlighting]] + - [[#highlight-current-symbol][Highlight current symbol]] + - [[#visual-star][Visual Star]] + - [[#listing-symbols-by-semantic][Listing symbols by semantic]] + - [[#helm-swoop][Helm-swoop]] + - [[#editing][Editing]] + - [[#paste-text][Paste text]] + - [[#paste-transient-state][Paste Transient-state]] + - [[#auto-indent-pasted-text][Auto-indent pasted text]] + - [[#text-manipulation-commands][Text manipulation commands]] + - [[#text-insertion-commands][Text insertion commands]] + - [[#smartparens-strict-mode][Smartparens Strict mode]] + - [[#zooming][Zooming]] + - [[#text][Text]] + - [[#frame][Frame]] + - [[#increasedecrease-numbers][Increase/Decrease numbers]] + - [[#spell-checking][Spell checking]] + - [[#region-selection][Region selection]] + - [[#expand-region][Expand-region]] + - [[#indent-text-object][Indent text object]] + - [[#region-narrowing][Region narrowing]] + - [[#replacing-text-with-iedit][Replacing text with iedit]] + - [[#iedit-states-key-bindings][iedit states key bindings]] + - [[#examples][Examples]] + - [[#replacing-text-in-several-files][Replacing text in several files]] + - [[#renaming-files-in-a-directory][Renaming files in a directory]] + - [[#commenting][Commenting]] + - [[#regular-expressions][Regular expressions]] + - [[#deleting-files][Deleting files]] + - [[#editing-lisp-code][Editing Lisp code]] + - [[#lisp-key-bindings][Lisp Key Bindings]] + - [[#mouse-usage][Mouse usage]] + - [[#managing-projects][Managing projects]] + - [[#registers][Registers]] + - [[#errors-handling][Errors handling]] + - [[#compiling][Compiling]] + - [[#modes][Modes]] + - [[#major-mode-leader-key][Major Mode leader key]] + - [[#helm-1][Helm]] + - [[#emacs-server][Emacs Server]] + - [[#connecting-to-the-emacs-server][Connecting to the Emacs server]] + - [[#keeping-the-server-alive][Keeping the server alive]] + - [[#troubleshoot][Troubleshoot]] + - [[#loading-fails][Loading fails]] + - [[#upgradingdowngrading-emacs-version][Upgrading/Downgrading Emacs version]] + - [[#achievements][Achievements]] + - [[#issues][Issues]] + - [[#merged-pull-requests][Merged Pull Requests]] + - [[#stars-forks-and-watchers][Stars, forks and watchers]] + - [[#gitter-chat][Gitter chat]] + - [[#first-times][First times]] + - [[#special-mentions][Special Mentions]] + - [[#special-titles][Special Titles]] + - [[#thank-you][Thank you]] + +* Core Pillars +Four core pillars: Mnemonic, Discoverable, Consistent and "Crowd-Configured". + +If any of these core pillars is violated open an issue and we'll try our best +to fix it. + +** Mnemonic +Key bindings are organized using mnemonic prefixes like ~b~ for buffer, ~p~ for +project, ~s~ for search, ~h~ for help, etc... + +** Discoverable +Innovative real-time display of available key bindings. Simple query +system to quickly find available layers, packages, and more. + +** Consistent +Similar functionalities have the same key binding everywhere thanks to a +clearly defined set of conventions. Documentation is mandatory for any layer +that ships with Spacemacs. + +** Crowd-Configured +Community-driven configuration provides curated packages tuned by power users +and bugs are fixed quickly. + +* Highlighted feature +- *Bring the efficiency of modal editing* to the powerful Emacs lisp platform. + Modal UX is optional and Spacemacs can be used with only Emacs key bindings. + +- Integrate nicely with =Evil= states (=Vim= modes). + +- *Keep your fingers on the home row* for quicker editing with support for + QWERTY and BEPO layouts. + +- *Minimalistic and nice graphical UI* keeps your available screen space for + what matters: your text files. + +- *Fast boot time*: packages and configuration are lazy-loaded as much as + possible. + +- *Lower the risk of RSI* by heavily using the space bar instead of modifiers. + If you have issues with your thumbs you can still use Spacemacs using + modifiers. + +- Contribute easily your improvements and new configuration layers. + +- *Very active and helpful community* on =Gitter= and =IRC= + (via Gitter IRC bridge) + +* Screenshots + +[[file:img/spacemacs-python.png]] +/Python/ + +*Note*: Even though screenshots are updated frequently, Spacemacs is evolving +quickly and the screenshots may not reflect exactly the current state of the +project. + +* Who can benefit from this? +- Spacemacs was initially intended to be used by *Vim users* who want to go to + the next level by using Emacs (see [[./VIMUSERS.org][guide]] for Vimmers). But it is now + perfectly *usable by non Vim users* by choosing the =emacs= editing style. + +- It is also a good fit for people wanting to *lower the [[http://en.wikipedia.org/wiki/Repetitive_strain_injury][risk of RSI]]* induced by + the default Emacs key bindings. (This is an assumption, there are no official + studies to prove this!) If you have issues using your thumbs you can still + use the =emacs= editing style which puts the leader key on a modifier + combination. + +- Emacs users wanting to learn *a different way to edit files* or wanting to + learn Vim key bindings or even wanting to mix both editing styles by setting + their style to =hybrid=. + +- Emacs users wanting a simple but deep configuration system that greatly + *lower the risk of .emacs bankruptcy*. + +- *Pair-programming* users thanks to out of the box support for dynamic + switching of editing style. A Vim user and an Emacs user can use the same + Spacemacs comfortably. + +* Update and Rollback +** Update Spacemacs repository +There are several methods of updating the core files and layer information for +Spacemacs. It is recommended to update the packages first; see the next section. + +*** Automatic Updates +Spacemacs will automatically check for a new version every startup. When it +detects that a new version is available an arrow will appear in the modeline. +Click it to update Spacemacs. You must restart Emacs after updating. +[[file:img/powerline-update.png]] +/Update Button/ + +*Note*: If you use the =develop= branch of Spacemacs, automatic update is +disabled---you have to update manually using git. + +*** Updating from the Spacemacs Buffer +Use the button labeled "Update Spacemacs" in the Spacemacs buffer. You will be +prompted for the version you would like to use. + +*Note*: If you use the =develop= branch of Spacemacs, you cannot use this method. + +*** Updating Manually with git +To update manually close Emacs and update the git repository: + +#+BEGIN_SRC sh +$ git pull origin master +#+END_SRC + +*Note*: The master branch is considered to be immutable in the sense that you +must not modify it by adding your own commit. If you do so you will break the +automatic update of Spacemacs on the master branch. To fork Spacemacs code you +have to use a custom branch that you manage manually. + +** Update packages +To update the Emacs packages used by Spacemacs press RET (enter) or click on the +link =[Update Packages]= in the startup page under the banner then restart +Emacs. If you prefer, you can use the command +=configuration-layer/update-packages= instead of the button. + +If anything goes wrong you should be able to rollback the update by pressing +~RET~ or clicking on the =[Rollback Package Update]= link in the startup page +and choosing a rollback slot (sorted by date). This button uses the command +=configuration-layer/rollback=. + +* Configuration layers +This section is an overview of layers. A more extensive introduction to writing +configuration layers can be found [[file:LAYERS.org][here]] (recommended reading!). + +** Purpose +Layers help collect related packages together to provide features. For example, +the =python= layer provides auto-completion, syntax checking, and REPL support +for python files. This approach helps keep configuration organized and reduces +overhead for the user by keeping them from having to think about what packages +to install. To install all the =python= features the user has just to add the +=python= layer to their dotfile. + +** Structure +Configuration is organized in layers. Each layer has the following structure: + +#+BEGIN_EXAMPLE + [layer_name] + |__ [local] + | |__ [package 1] + | | ... + | |__ [package n] + |-- layers.el + |__ packages.el + |__ funcs.el + |__ config.el + |__ keybindings.el + + [] = directory +#+END_EXAMPLE + +Where: + +| File | Usage | +|----------------+--------------------------------------------------------------------------------------------------| +| layers.el | The place to declare additional layers | +| packages.el | The list of packages and their configuration functions (init, post-init, etc...) | +| funcs.el | All functions defined in the layer (used in package configuration for instance) | +| config.el | Layer configuration (defines the layer variables default values and setup some config variables) | +| keybindings.el | General key bindings no tied to a specific package configuration | + +=Packages= can be: +- =ELPA= packages installed from an =ELPA= compliant repository +- local packages in a layer's =local= folder +- installed from an online source using [[https://github.com/quelpa/quelpa][quelpa]]. + +** Configure packages +*** With a layer +**** Declaration +=Packages= are declared in a variable called =-packages= where == +is the name of the layer. + +Example: + +#+BEGIN_SRC emacs-lisp +(setq -packages '(package1 package2 ...) +#+END_SRC + +All packages from all layers are processed in alphabetical order so sometimes +you'll have to use some =with-eval-after-load= black magic to configure them +properly. For instance if package =A= depends on =B= then you can configure +=A= with: + +#+BEGIN_SRC emacs-lisp +(with-eval-after-load 'B ...) +#+END_SRC + +For details on installing packages using quelpa or local packages see [[file:LAYERS.org::packages.el][LAYERS]]. + +**** Initialization +To initialize a package =xxx=, define a function with this format in +=packages.el=: + +#+BEGIN_SRC emacs-lisp +(defun /init-xxx () ...body ) +#+END_SRC + +It is common to define the body with the [[https://github.com/jwiegley/use-package][use-package]] macro. + +**** Exclusion +It is possible to exclude some packages from Spacemacs on a per-layer basis. +This is useful when a configuration layer aims to replace a stock package +declared in the Spacemacs layer. + +To do so add the package names to exclude to the variable +=-excluded-packages=. + +Example: + +#+BEGIN_SRC emacs-lisp +(setq -excluded-packages '(package1 package2 ...) +#+END_SRC + +*** Without a layer +Sometimes a layer can be an unnecessary overhead, this is the case if you just +want to install a package with very few configuration associated to it. A good +example is some niche language where you are only interested in syntax +highlighting. + +You can install such packages by adding them to the variable +=dotspacemacs-additional-packages= under the =dotspacemacs/layers= function in your dotfile. + +For example, to install =llvm-mode= and =dts-mode=: +#+BEGIN_SRC emacs-lisp +(defun dotspacemacs/layers () + "Configuration Layers declaration..." + (setq-default + ;; ... + dotspacemacs-additional-packages '(llvm-mode dts-mode) + ;; ... + )) +#+END_SRC + +If you want to add some configuration for them then put the configuration in +the =dotspacemacs/user-config= function or consider creating a layer. + +** Packages synchronization +Spacemacs will only install the packages that are explicitly used by the user. +A package is considered to be used if its layer is used (i.e. listed in +=dotspacemacs-configuration-layers=). +Any packages that are not used is considered to be orphan and is deleted at +the next startup of Emacs. + +** Types of configuration layers +There are two types of configuration layers: + - distributed layers (in the =layers= directory, those layers are contributions shared + by the community and merged upstream) + - private (in the =private= directory, they are ignored by Git) + +** Submitting a configuration layer upstream +If you decide to provide a configuration layer, please check the contribution +guidelines first in [[file:../CONTRIBUTING.org][CONTRIBUTING]]. + +** Example: Themes Megapack example +This is a simple configuration layer listing a bunch of themes which you can +find [[../layers/themes-megapack/README.org][here]]. + +To install it, just add =themes-megapack= to your =~/.spacemacs= like so: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers '(themes-megapack)) +#+END_SRC + +Adding this layer will install around 100 themes; to uninstall them remove the +layer from the =dotspacemacs-configuration-layers= and press ~SPC f e R~. + +** Managing private configuration layers +Spacemacs's configuration system is flexible enough to let you manage your +private layers in different ways. + +*** Using the private directory +Everything in the private directory is ignored by Git so it is a good place to +store private layers. There is a huge drawback to this approach though: /your +layers are not source controlled/. + +*** Using an external Git repository +This is the recommended way to manage your private layers. + +The best approach is to store all your private layers into an external Git +repository. It is especially a good practice to store them in your =dotfiles= +repository if you have one. Put also your =~/.spacemacs= file in it. + +Then you are free to symlink your layers into =~/emacs.d/private= /or/ let them +anywhere you want and reference the parent directory in the variable +=dotspacemacs-configuration-layer-path= of your =~/.spacemacs=. + +Note that you could also have a dedicated repository for all your private layers +and then directly clone this repository in =~/.emacs.d/private=. + +*** Using a personal branch +The final main way to manage your private layers is to push them in a personal +branch that you keep up to date with upstream =master= or =develop=. + +** Tips for writing layers +Please refer to [[file:LAYERS.org][this]] introduction for some tips on writing layers, and how to +best make them fit with the Spacemacs philosophy and loading strategy. + +* Dotfile Configuration +User configuration can be stored in your =~/.spacemacs= file. + +** Dotfile Installation +The very first time Spacemacs starts up, it will ask you several questions +and then install the =.spacemacs= in your =HOME= directory. + +** Alternative dotdirectory +A dotdirectory =~/.spacemacs.d/= can be used instead of a dotfile. +If you want to use this option, move =~/.spacemacs= to =~/.spacemacs.d/init.el=. + +It is also possible to override the location of =~/.spacemacs.d/= using the +environment variable =SPACEMACSDIR=. Of course you can also use symlinks to +change the location of this directory. + +*Note:* =~/.spacemacs= will always take priority over =~/.spacemacs.d/init.el=, +so =~/.spacemacs= must not exist for =~/.spacemacs.d/init.el= to be used by +Spacemacs. + +** Synchronization of dotfile changes +To apply the modifications made in =~/.spacemacs= press ~SPC f e R~. It will +re-execute the Spacemacs initialization process. + +*Note*: A synchronization re-executes the functions =dotspacemacs/init=, +=dotspacemacs/user-init= and =dotspacemacs/user-config=. +Depending on the content of this functions you may encounter some unwanted side +effects. For instance if you use a toggle in =dotspacemac/user-config= to enable +some behavior, this behavior will be turned off whenever the dotfile is +re-synchronized. To avoid these side-effects it is recommended to either use +=setq= expressions instead of toggle functions, or to use the =on= or =off= +versions instead (i.e. instead of =spacemacs/toggle-=, use +=spacemacs/toggle--on= or =spacemacs/toggle--off=). + +It is possible to /skip/ the execution of =dotspacemacs/user-config= with the +universal argument (~SPC u SPC f e R~). + +** Testing the dotfile +You can use the command =SPC SPC dotspacemacs/test-dotfile= to check if your +=~/.spacemacs= looks correct. This will check, among other things, whether the +declared layers can be found and that the variables have sensible values. These +tests are also run automatically when you synchronize with ~SPC f e R~. + +** Dotfile Contents +*** Configuration functions +Three special functions in the =~/.spacemacs= file can be used to perform +configuration at the beginning and end of Spacemacs loading process: + +- =dotspacemacs/layers= is called at the very startup of Spacemacs initilialization, + this is where you set the Spacemacs distribution and declare layers to be used + in your configuration. You can also add or excluded packages of your choice + and tweak some behavior of Spacemacs loading. +- =dotspacemacs/init= is called at the very startup of Spacemacs initialization + before layers configuration. *You should not put any user code* in there + besides modifying the Spacemacs variable values prefixed with =dotspacemacs-=. +- =dotspacemacs/user-init= is called immediately after =dotspacemacs/init=, + before layer configuration. This function is mostly useful for variables + that need to be set before packages are loaded. +- =dotspacemacs/user-config= is called at the very end of Spacemacs + initialization after layers configuration. This is the place where most of + your configurations should be done. Unless it is explicitly specified that a + variable should be set before a package is loaded, you should place your code + here. + +*** Custom variables +Custom variables configuration from =M-x customize-group= built-in Emacs feature +are automatically saved by Emacs at the end of your =~/.spacemacs= file. + +** Declaring Configuration layers +To use a configuration layer, declare it in your dotfile by adding it to the +=dotspacemacs-configuration-layers= variable of your =~/.spacemacs=. + +*Note:* In this documentation a =used layer= is equivalent to a =declared +layer=. + +For instance, [[Thank you][RMS]] can add his private configuration layer like this: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers + '( + ;; other layers + ;; rms layer added at the end of the list + rms + )) +#+END_SRC + +Official layers shipped with Spacemacs are stored in =~/.emacs.d/layers=. The +directory =~/.emacs.d/private= is a drop-in location for your private layers. +It is possible to put layers at the location of your choice provided you tell +Spacemacs where to look for them. This is done by setting the list +=dotspacemacs-configuration-layer-path= in your =~/.spacemacs=. For instance +to add some layers in =~/.myconfig=, set the variable like this: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layer-path '("~/.myconfig/")) +#+END_SRC + +*** Setting configuration layers variables +Some configuration layers have configuration variables to enable specific +feature. For instance the [[../layers/%2Bsource-control/git][git layer]] has several configuration variables, they +can be set directly in the =dotspacemacs-configuration-layers= like this: + +#+BEGIN_SRC emacs-lisp +(defun dotspacemacs/layers () + ;; List of configuration layers to load. + (setq-default dotspacemacs-configuration-layers + '(auto-completion + (git :variables + git-magit-status-fullscreen t + git-variable-example nil) + smex))) +#+END_SRC + +The =:variables= keyword is a convenience to keep layer configuration close to +their declaration. Setting layer variables in the =dotspacemacs/user-init= +function of your dotfile is also a perfectly valid way to configure a layer. + +*** Disabling layer services in other layers +Often layers enable services that other layers can use. For instance if you use +the layer =auto-completion= then every other layers supporting =auto-completion= +will have this feature enabled. + +Sometimes you may want to disable a service added by a layer in some specific +layers. Say you want to disable =auto-completion= in =org= and =git= layers, +you can do it with the following layer declaration. + +#+BEGIN_SRC emacs-lisp +(defun dotspacemacs/layers () + ;; List of configuration layers to load. + (setq-default dotspacemacs-configuration-layers + '(org git + (auto-completion :disabled-for org git)))) +#+END_SRC + +You can also use the =:enabled-for= construct to disable it for /all/ layers +/except/ those explicitly identified. + +#+BEGIN_SRC emacs-lisp +(defun dotspacemacs/layers () + ;; List of configuration layers to load. + (setq-default dotspacemacs-configuration-layers + '(java python c-c++ + (auto-completion :enabled-for java python)))) +#+END_SRC + +Note that =:enabled-for= may be an empty list. + +#+BEGIN_SRC emacs-lisp +(defun dotspacemacs/layers () + ;; List of configuration layers to load. + (setq-default dotspacemacs-configuration-layers + '(java python c-c++ + (auto-completion :enabled-for)))) +#+END_SRC + +=:enabled-for= takes precedence over =:disabled-for= if both are present. + +*** Selecting/Ignoring packages of a layer +By default a declared layer installs/configures all its associated packages. You +may want to select only some of them or ignoring some of them. This is possible +with the =:packages= keyword. + +For instance to ignore the =neotree= and =fancy-battery= packages from +=spacemacs-ui-visual= layer: + +#+BEGIN_SRC emacs-lisp +(defun dotspacemacs/layers () + ;; List of configuration layers to load. + (setq-default dotspacemacs-configuration-layers + '(auto-completion + (spacemacs-ui-visual :packages (not neotree fancy-battery)))) +#+END_SRC + +The opposite would be to ignore all packages except =neotree= and +=fancy-battery=: + +#+BEGIN_SRC emacs-lisp +(defun dotspacemacs/layers () + ;; List of configuration layers to load. + (setq-default dotspacemacs-configuration-layers + '(auto-completion + (spacemacs-ui-visual :packages neotree fancy-battery))) +#+END_SRC + +*Note:* Ignoring a package from a layer is different than excluding a package. +An excluded packages is completely removed from your configuration whereas an +ignored package is ignored only for a given layer but it can remain on your +system. It happens that if the given layer is the owner of the package then +ignoring this package is the same as excluding it (because the package becomes +orphan so it is considered unused by Spacemacs). + +*** Excluding packages +You can exclude packages you don't want to install with the variable +=dotspacemacs-excluded-packages= (see [[Configuration layers][Configuration layers]] for more info +on packages). + +For instance, to disable the =rainbow-delimiters= package: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-excluded-packages '(rainbow-delimiters)) +#+END_SRC + +When you exclude a package, Spacemacs will automatically delete it for you the +next time you launch Emacs or at the next dotfile synchronization. All the +orphan dependencies are also deleted automatically. Excluding a package +effectively remove _all_ references to it in Spacemacs without breaking the rest +of the configuration, this is a powerful feature which allows you to quickly +remove any feature from Spacemacs. + +*Note:* A few packages are essential for Spacemacs to correctly operate, those +packages are protected and cannot be excluded or unsintalled even if they become +orphans or are excluded. =use-package= is an example of a protected package that +cannot be removed from Spacemacs. + +* Concepts +** Editing Styles +Spacemacs comes with several editing styles which can be switched dynamically +providing an easier way to do pair programming, for instance between a Vim user +and an Emacs user. + +Three styles are available: +- Vim, +- Emacs, +- Hybrid (a mix between Vim and Emacs). + +*** Vim +Spacemacs behaves like in Vim using [[https://gitorious.org/evil/pages/Home][Evil]] mode package to emulate Vim key bindings. +This is the default style of Spacemacs; it can be set explicitly by setting +the =dotspacemacs-editing-style= variable to =vim= in the dotfile. + +To bind keys in Vim editing style (=insert state=): + +#+BEGIN_SRC emacs-lisp +(define-key evil-insert-state-map (kbd "C-]") 'forward-char) +#+END_SRC + +*** Emacs +Spacemacs behaves like in raw Emacs using the Holy mode which configures Evil to +make the =emacs state= the default state everywhere. +Set the =dotspacemacs-editing-style= variable to =emacs= in the dotfile. + +In Emacs style the leader is available on ~M-m~. It is possible to toggle it on +and off with ~SPC t E e~ and ~M-m t E e~. When off the =vim= style is enabled. + +To bind keys in Emacs editing style (=emacs state=): + +#+BEGIN_SRC emacs-lisp +(define-key evil-emacs-state-map (kbd "C-]") 'forward-char) +#+END_SRC + +*** Hybrid +The hybrid editing style is like the Vim style except that =insert state= is +replaced by a new state called =hybrid state=. In =hybrid state= all the Emacs +key bindings are available; this is like replacing the =insert state= with the +=emacs state= but provides an isolated key map =evil-hybrid-state-map=. + +To bind keys in Hybrid editing style (=hybrid state=): + +#+BEGIN_SRC emacs-lisp +(define-key evil-hybrid-state-map (kbd "C-]") 'forward-char) +#+END_SRC + +This style can be tweaked to be more like Emacs or more like Vim depending +on the user preferences. The following variable are available to change the +style configuration: + +- =hybrid-mode-default-state= The default state when opening a new buffer, + default is =normal=. Set it to =emacs= for a more emacsy style. +- =hybrid-mode-enable-hjkl-bindings= If non nil then packages will configure + =h j k l= key bindings for navigation. +- =hybrid-mode-enable-evilified-state= If non nil buffer are =evilified= when + supported, if nil then =emacs= state is enabled in those buffers instead. + +Default configuration is: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-editing-style '(hybrid :variables + hybrid-mode-enable-evilified-state t + hybrid-mode-enable-hjkl-bindings nil + hybrid-mode-default-state 'normal) +#+END_SRC + +To toggle the hybrid style on and off use ~SPC t E h~ and ~M-m t E h~. When +off the =vim= style is enabled. + +** States +Spacemacs has 10 states: + +| State | Default Color | Description | +|--------------+---------------+------------------------------------------------------------------------------------------------------------| +| normal | orange | like the =normal mode of Vim=, used to execute and combine commands | +| insert | green | like the =insert mode of Vim=, used to actually insert text | +| visual | gray | like the =visual mode of Vim=, used to make text selection | +| motion | purple | exclusive to =Evil=, used to navigate read only buffers | +| emacs | blue | exclusive to =Evil=, using this state is like using a regular Emacs without Vim | +| replace | chocolate | exclusive to =Evil=, overwrites the character under point instead of inserting a new one | +| hybrid | blue | exclusive to Spacemacs, this is like the insert state except that all the emacs key bindings are available | +| evilified | light brown | exclusive to Spacemacs, this is an =emacs state= modified to bring Vim navigation, selection and search. | +| lisp | pink | exclusive to Spacemacs, used to navigate Lisp code and modify it (more [[Editing Lisp code][info]]) | +| iedit | red | exclusive to Spacemacs, used to navigate between multiple regions of text using =iedit= (more [[Replacing text with iedit][info]]) | +| iedit-insert | red | exclusive to Spacemacs, used to replace multiple regions of text using =iedit= (more [[Replacing text with iedit][info]]) | + +Note: Technically speaking there is also the =operator= evil state. + +** Evilified modes +Some buffers are not for editing text and provide their own keybindings for +certain operations. These often conflict with Vim bindings. To make such buffers +behave more like Vim in a consistent manner, they use a special state called +/evilified/ state. In evilified state, a handful of keys work as in Evil, namely +=/=, =:=, =h=, =j=, =k=, =l=, =n=, =N=, =v=, =V=, =gg=, =G=, =C-f=, =C-b=, +=C-d=, =C-e=, =C-u=, =C-y= and =C-z=. All other keys work as intended by the +underlying mode. + +Shadowed keys are moved according to the pattern: =a= → =A= → =C-a= → =C-A= + +For example, if the mode binds a function to =n=, that is found under =C-n= in +evilified state, since both =n= and =N= are reserved, but =C-n= is not. On the +other hand, anything originally bound to =k= will be found on =K=, since =k= is +reserved but =K= is not. If there is a binding on =K=, that will be moved to +=C-k=. + +In addition to this, =C-g=, being an important escape key in Emacs, is skipped. +So anything bound to =g= originally will be found on =C-G=, since =g=, =G= and +=C-g= are all reserved. + +** Evil leader +Spacemacs uses a leader key to bind almost all its key bindings. + +This leader key is commonly set to ~​,​~ by Vim users, in Spacemacs the leader +key is set on ~SPC~ (the space bar, hence the name =spacemacs=). This key is the +most accessible key on a keyboard and it is pressed with the thumb which is a +good choice to lower the risk of [[http://en.wikipedia.org/wiki/Repetitive_strain_injury][RSI]]. It can be customized to any other key +using the variable =dotspacemacs-leader-key= and =dotspacemacs-emacs-leader-key=. + +With Spacemacs there is no need to remap your keyboard modifiers to attempt +to reduce the risk of RSI, every command can be executed very easily while you +are in =normal= mode by pressing the ~SPC~ leader key, here are a few examples: + +- Save a buffer: ~SPC f s~ +- Save all opened buffers: ~SPC f S~ +- Open (switch) to a buffer with =helm=: ~SPC b b~ + +** Universal argument +The universal argument ~C-u~ is an important command in Emacs but it is also a +very handy Vim key binding to scroll up. + +Spacemacs binds ~C-u~ to =scroll-up= and change the universal argument binding +to ~SPC u~. + +*Note*: ~SPC u~ is not working before =helm-M-x= (~SPC SPC~). Instead, call +=helm-M-x= first, select the command you want to run, and press ~C-u~ before +pressing ~RETURN~. For instance: ~SPC SPC org-reload C-u RET~ + +** Transient-states +Spacemacs defines a wide variety of =transient states= (temporary overlay maps) +where it makes sense. This prevents one from doing repetitive and tedious +presses on the ~SPC~ key. + +When a =transient state= is active, a documentation is displayed in the +minibuffer. Additional information may as well be displayed in the minibuffer. + +Auto-highlight-symbol transient state: +[[file:img/spacemacs-ahs-transient-state.png]] +[[Text][Text scale transient state]]: + +[[file:img/spacemacs-scale-transient-state.png]] + +* Differences between Vim, Evil and Spacemacs +- The ~​,​~ key does "repeat last ~f~, ~t~, ~F~, or ~T~ command in + opposite direction in =Vim=, but in Spacemacs it is the major mode specific + leader key by default (which can be set on another key binding in the + dotfile). + +Send a PR to add the differences you found in this section. + +** The vim-surround case +There is one obvious visible difference though. It is not between =Evil= and +=Vim= but between Spacemacs and [[https://github.com/tpope/vim-surround][vim-surround]]: in visual mode the =surround= command is on ~S~ +in =vim-surround= whereas it is on ~s~ in Spacemacs. + +This is something that can surprise some Vim users so here are some motivations +behind this change: + - ~s~ and ~c~ do the same thing in =visual state=, + - ~s~ is only useful to delete /one/ character and add more than one character + which is a /very/ narrow use case + - ~c~ accept motions and can do everything ~s~ can do in =normal state= + (note that this is also true for ~r~ but ~r~ is more useful because it + stays in =normal state=) + - =surround= command is just a more powerful command than ~s~. + +If you are not convinced, then here is the snippet to revert back to the default +=Vim + vim-surround= setup (add it to your =dotspacemacs/user-config= function or +your =~/.spacemacs=): + +#+BEGIN_SRC emacs-lisp +(evil-define-key 'visual evil-surround-mode-map "s" 'evil-substitute) +(evil-define-key 'visual evil-surround-mode-map "S" 'evil-surround-region) +#+END_SRC + +* Evil plugins +Spacemacs ships with the following evil plugins: + +| Mode | Description | +|-------------------------------+--------------------------------------------| +| [[https://github.com/wcsmith/evil-args][evil-args]] | motions and text objects for arguments | +| [[https://github.com/Dewdrops/evil-exchange][evil-exchange]] | port of [[https://github.com/tommcdo/vim-exchange][vim-exchange]] | +| [[https://github.com/cofi/evil-indent-textobject][evil-indent-textobject]] | add text object based on indentation level | +| [[https://github.com/redguardtoo/evil-matchit][evil-matchit]] | port of [[http://www.vim.org/scripts/script.php?script_id=39][matchit.vim]] | +| [[https://github.com/redguardtoo/evil-nerd-commenter][evil-nerd-commenter]] | port of [[https://github.com/scrooloose/nerdcommenter][nerdcommenter]] | +| [[https://github.com/cofi/evil-numbers][evil-numbers]] | like ~C-a~ and ~C-x~ in vim | +| [[https://github.com/juanjux/evil-search-highlight-persist][evil-search-highlight-persist]] | emulation of hlsearch behavior | +| [[https://github.com/timcharper/evil-surround][evil-surround]] | port of [[https://github.com/tpope/vim-surround][vim-surround]] | +| [[https://github.com/bling/evil-visualstar][evil-visualstar]] | search for current selection with ~*~ | +| [[https://github.com/jaypei/emacs-neotree][NeoTree]] | mimic [[https://github.com/scrooloose/nerdtree][NERD Tree]] | + +* Binding keys +Key sequences are bound to commands in Emacs in various keymaps. The most basic +map is the =global-map=. Setting a key binding in the =global-map= is achieved +with the function =global-set-key=. Example to bind a key to the command +=forward-char=: + +#+BEGIN_SRC emacs-lisp +(global-set-key (kbd "C-]") 'forward-char) +#+END_SRC + +The =kbd= macro accepts a string describing a key sequence. The =global-map= is +often shadowed by other maps. For example, =evil-mode= defines keymaps that +target states (or modes in vim terminology). Here is an example that creates the +same binding as above but only in =insert state= (=define-key= is a built-in +function. =Evil-mode= has its own functions for defining keys). + +#+BEGIN_SRC emacs-lisp +(define-key evil-insert-state-map (kbd "C-]") 'forward-char) +#+END_SRC + +Perhaps most importantly for Spacemacs is the use of the bind-map package to +bind keys behind a leader key. +This is where most of the Spacemacs bindings live. Binding keys behind the +leader key is achieved with the functions =spacemacs/set-leader-keys= and +=spacemacs/set-leader-keys-for-major-mode=, example: + +#+BEGIN_SRC emacs-lisp +(spacemacs/set-leader-keys "C-]" 'forward-char) +(spacemacs/set-leader-keys-for-major-mode 'emacs-lisp-mode "C-]" 'forward-char) +#+END_SRC + +These functions use a macro like =kbd= to translate the key sequences for you. +The second function, =spacemacs/set-leader-keys-for-major-mode=, binds the key +only in the specified mode. The second key binding is active only when the +major mode is =emacs-lisp=. + +Finally, one should be aware of prefix keys. Essentially, all keymaps can be +nested. Nested keymaps are used extensively in spacemacs, and in vanilla Emacs +for that matter. For example, ~SPC a~ points to key bindings for "applications", +like ~SPC a c~ for =calc-dispatch=. Nesting bindings is easy. + +#+BEGIN_SRC emacs-lisp +(spacemacs/declare-prefix "]" "bracket-prefix") +(spacemacs/set-leader-keys "]]" 'double-bracket-command) +#+END_SRC + +The first line declares ~SPC ]~ to be a prefix and the second binds the key +sequence ~SPC ]]~ to the corresponding command. The first line is actually +unnecessary to create the prefix, but it will give your new prefix a name that +key-discovery tools can use (e.g., which-key). + +There is much more to say about bindings keys, but these are the basics. Keys +can be bound in your =~/.spacemacs= file or in individual layers. + +* GUI Elements +Spacemacs has a minimalistic and distraction free graphical UI: + - custom [[https://github.com/milkypostman/powerline][powerline]] mode-line [[Flycheck integration][with color feedback]] according to current [[https://github.com/flycheck/flycheck][Flycheck]] status + - Unicode symbols for minor mode lighters which appear in the mode-line + - [[Errors handling][custom fringe bitmaps]] and error feedbacks for [[https://github.com/flycheck/flycheck][Flycheck]] + +** Color themes +The official Spacemacs theme is [[https://github.com/nashamri/spacemacs-theme][spacemacs-dark]] and it is the default theme +installed when you first started Spacemacs. There are two variants of the +theme, a dark one and a light one. Some aspect of these themes can be customized +in the function =dotspacemacs/user-init= of your =~/.spacemacs=: + - the comment background with the boolean =spacemacs-theme-comment-bg= + - the height of org section titles with =spacemacs-theme-org-height= + +It is possible to define your default themes in your =~/.spacemacs= with the +variable =dotspacemacs-themes=. For instance, to specify =spacemacs-light=, +=leuven= and =zenburn=: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-themes '(spacemacs-light leuven zenburn)) +#+END_SRC + +| Key Binding | Description | +|-------------+-------------------------------------------------------| +| ~SPC T n~ | switch to next theme listed in =dotspacemacs-themes=. | +| ~SPC T s~ | select a theme using a =helm= buffer. | + +You can see samples of all included themes in this [[http://themegallery.robdor.com][theme gallery]] from [[http://www.twitter.com/robmerrell][Rob Merrell]]. + +*Note*: + - You don't need to explicitly list in a layer the theme packages you are + defining in =dotspacemacs-themes=, Spacemacs is smart enough to remove those + packages from the list of orphans. + - Due to the inner working of themes in Emacs, switching theme during the same + session may have some weird side effects. Although these side effects should + be pretty rare. + - In the terminal version of Emacs, color themes will not render correctly as + colors are rendered by the terminal and not by emacs. You will probably have + to change your terminal color palette. More explanations can be found on + [[https://github.com/sellout/emacs-color-theme-solarized#important-note-for-terminal-users][emacs-color-theme-solarized webpage]]. + +*Hint*: If you are an =Org= user, [[https://github.com/fniessen/emacs-leuven-theme][leuven-theme]] is amazing ;-) + +** Font +The default font used by Spacemacs is [[https://github.com/adobe-fonts/source-code-pro][Source Code Pro]] by Adobe. It is +recommended to install it on your system if you wish to use it. + +To change the default font set the variable =dotspacemacs-default-font= in your +=.spacemacs= file. By default its value is: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-default-font '("Source Code Pro" + :size 13 + :weight normal + :width normal + :powerline-scale 1.1)) +#+END_SRC + +If the specified font is not found, the fallback one will be used (depends on +your system). Also note that changing this value has no effect if you are +running Emacs in terminal. + +The properties should be pretty straightforward, it is possible to set any valid +property of a [[http://www.gnu.org/software/emacs/manual/html_node/elisp/Low_002dLevel-Font.html][font-spec]]: + - =:family= Font family or fontset (a string). + - =:width= Relative character width. This should be one of the symbols: + - ultra-condensed + - extra-condensed + - condensed + - semi-condensed + - normal + - semi-expanded + - expanded + - extra-expanded + - ultra-expanded + - =:height= The height of the font. In the simplest case, this is an integer + in units of 1/10 point. + - =:weight= Font weight- one of the symbols (from densest to faintest): + - ultra-bold + - extra-bold + - bold + - semi-bold + - normal + - semi-light + - light + - extra-light + - ultra-light + - =:slant= Font slant- one of the symbols: + - italic + - oblique + - normal + - reverse-italic + - reverse-oblique + - =:size= The font size- either a non-negative integer that specifies the + pixel size, or a floating-point number that specifies the point size. + - =:adstyle= Additional typographic style information for the font, such as + 'sans'. The value should be a string or a symbol. + - =:registry= The charset registry and encoding of the font, such as + 'iso8859-1'. The value should be a string or a symbol. + - =:script= The script that the font must support (a symbol). + +The special property =:powerline-scale= is Spacemacs specific and it is for +quick tweaking of the mode-line height in order to avoid crappy rendering of the +separators like on the following screenshot (default value is 1.1). + +[[file:img/crappy-powerline-separators.png]] +/Ugly separators/ + +** GUI Toggles +Some graphical UI indicators can be toggled on and off (toggles start with ~t~ +and ~T~): + +| Key Binding | Description | +|-------------+-------------------------------------------------------------------| +| ~SPC t 8~ | highlight any character past the 80th column | +| ~SPC t f~ | display the fill column (by default the fill column is set to 80) | +| ~SPC t h h~ | toggle highlight of the current line | +| ~SPC t h i~ | toggle highlight indentation levels | +| ~SPC t h c~ | toggle highlight indentation current column | +| ~SPC t i~ | toggle indentation guide at point | +| ~SPC t l~ | toggle truncate lines | +| ~SPC t L~ | toggle visual lines | +| ~SPC t n~ | toggle line numbers | +| ~SPC t v~ | toggle smooth scrolling | + +| Key Binding | Description | +|-------------+------------------------------------------------------------------| +| ~SPC T ~~ | display =~= in the fringe on empty lines | +| ~SPC T F~ | toggle frame fullscreen | +| ~SPC T f~ | toggle display of the fringe | +| ~SPC T m~ | toggle menu bar | +| ~SPC T M~ | toggle frame maximize | +| ~SPC T t~ | toggle tool bar | +| ~SPC T T~ | toggle frame transparency and enter transparency transient state | + +*Note*: These toggles are all available via the =helm-spacemacs-help= interface +(press ~SPC h SPC~ to display the =helm-spacemacs-help= buffer). + +**** Global line numbers +Line numbers can be toggled on in all =prog-mode= and =text-mode= buffers by +setting the =dotspacemacs-line-numbers= variable in your =~/.spacemacs= +to something different than =nil=. + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-line-numbers t) +#+END_SRC + +If it is set to =relative=, line numbers are show in a relative way: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-line-numbers 'relative) +#+END_SRC + +** Mode-line +The mode line is a heavily customized [[https://github.com/milkypostman/powerline][powerline]] with the following capabilities: + - show the window number + - color code for current state + - show the number of search occurrences via anzu + - toggle flycheck info + - toggle battery info + - toggle minor mode lighters + +Reminder of the color codes for the states: + +| Evil State | Color | +|--------------------+-----------| +| Normal | Orange | +| Insert | Green | +| Visual | Grey | +| Emacs | Blue | +| Motion | Purple | +| Replace | Chocolate | +| Lisp | Pink | +| Iedit/Iedit-Insert | Red | + +Some elements can be dynamically toggled: + +| Key Binding | Description | +|-------------+-----------------------------------------------------------------| +| ~SPC t m b~ | toggle the battery status | +| ~SPC t m c~ | toggle the =org= task clock (available in =org= layer) | +| ~SPC t m m~ | toggle the minor mode lighters | +| ~SPC t m M~ | toggle the major mode | +| ~SPC t m n~ | toggle the cat! (if =colors= layer is declared in your dotfile) | +| ~SPC t m p~ | toggle the point character position | +| ~SPC t m t~ | toggle the mode line itself | +| ~SPC t m v~ | toggle the version control info | +| ~SPC t m V~ | toggle the new version lighter | + +**** Powerline font installation for terminal-mode users +Users who run Emacs in terminal mode may need to install the [[https://github.com/powerline/fonts][Powerline patched +fonts]] and configure their terminal clients to use them to make the Powerline +separators render correctly. + +**** Flycheck integration +When [[https://github.com/flycheck/flycheck][Flycheck]] minor mode is enabled, a new element appears showing the number of +errors, warnings and info. + +[[file:img/powerline-wave.png]] +/Flycheck integration in mode-line/ + +**** Anzu integration +[[https://github.com/syohex/emacs-anzu][Anzu]] shows the number of occurrence when performing a search. Spacemacs +integrates nicely the Anzu status by displaying it temporarily when ~n~ or ~N~ +are being pressed. See the =5/6= segment on the screenshot below. + +[[file:img/powerline-anzu.png]] +/Anzu integration in mode-line/ + +**** Battery status integration +[[https://github.com/lunaryorn/fancy-battery.el][fancy-battery]] displays the percentage of total charge of the battery as well as +the time remaining to charge or discharge completely the battery. + +A color code is used for the battery status: + +| Battery State | Color | +|---------------+--------| +| Charging | Green | +| Discharging | Orange | +| Critical | Red | + +Note the these colors may vary depending on your theme. + +**** Powerline separators +It is possible to easily customize the =powerline separator= by setting the +=powerline-default-separator= variable in your =~./spacemacs= and then +recompiling the modeline. For instance if you want to set back the separator to +the well-known =arrow= separator add the following snippet to your configuration +file: + +#+BEGIN_SRC emacs-lisp +(defun dotspacemacs/user-config () + "This is were you can ultimately override default Spacemacs configuration. +This function is called at the very end of Spacemacs initialization." + (setq powerline-default-separator 'arrow)) +#+END_SRC + +To save you the time to try all the possible separators provided by the +powerline, here is an exhaustive set of screenshots: + +| Separator | Screenshot | +|--------------+-----------------------------------| +| =alternate= | [[file:img/powerline-alternate.png]] | +| =arrow= | [[file:img/powerline-arrow.png]] | +| =arrow-fade= | [[file:img/powerline-arrow-fade.png]] | +| =bar= | [[file:img/powerline-bar.png]] | +| =box= | [[file:img/powerline-box.png]] | +| =brace= | [[file:img/powerline-brace.png]] | +| =butt= | [[file:img/powerline-butt.png]] | +| =chamfer= | [[file:img/powerline-chamfer.png]] | +| =contour= | [[file:img/powerline-contour.png]] | +| =curve= | [[file:img/powerline-curve.png]] | +| =rounded= | [[file:img/powerline-rounded.png]] | +| =roundstub= | [[file:img/powerline-roundstub.png]] | +| =slant= | [[file:img/powerline-slant.png]] | +| =wave= | [[file:img/powerline-wave.png]] | +| =zigzag= | [[file:img/powerline-zigzag.png]] | +| =nil= | [[file:img/powerline-nil.png]] | + +**** Minor Modes +Spacemacs uses [[http://www.emacswiki.org/emacs/DiminishedModes][diminish]] mode to reduce the size of minor mode indicators: + +The minor mode area can be toggled on and off with ~SPC t m m~ + +Unicode symbols are displayed by default. Setting the variable +=dotspacemacs-mode-line-unicode-symbols= to =nil= in your =~/.spacemacs= will +display ASCII characters instead (may be useful in terminal if you cannot set an +appropriate font). + +The letters displayed in the mode-line correspond to the key bindings used to +toggle them. + +Some toggle have two flavors: local and global. The global version of the toggle +can be reached using the =control= key. + +| Key Binding | Unicode | ASCII | Mode | +|-------------+---------+-------+----------------------------------------------------------------------| +| ~SPC t -~ | =⊝= | - | [[http://emacswiki.org/emacs/centered-cursor-mode.el][centered-cursor]] mode | +| ~SPC t 8~ | =⑧= | 8 | toggle highlight of characters for long lines | +| ~SPC t C-8~ | =⑧= | 8 | global toggle highlight of characters for long lines | +| ~SPC t C--~ | =⊝= | - | global centered cursor | +| ~SPC t a~ | =ⓐ= | a | auto-completion | +| ~SPC t c~ | =ⓒ= | c | camel case motion with subword mode | +| =none= | =ⓔ= | e | [[https://github.com/edwtjo/evil-org-mode][evil-org]] mode | +| ~SPC t E e~ | =Ⓔe= | Ee | emacs editing style (holy mode) | +| ~SPC t E h~ | =Ⓔh= | Eh | hybrid editing style (hybrid mode) | +| ~SPC t f~ | =ⓕ= | f | fill-column-indicator mode | +| ~SPC t F~ | =Ⓕ= | F | auto-fill mode | +| ~SPC t g~ | =ⓖ= | g | [[https://github.com/roman/golden-ratio.el][golden-ratio]] mode | +| ~SPC t h i~ | =ⓗi= | hi | toggle highlight indentation levels | +| ~SPC t h c~ | =ⓗc= | hc | toggle highlight indentation current column | +| ~SPC t i~ | =ⓘ= | i | indentation guide | +| ~SPC t C-i~ | =ⓘ= | i | global indentation guide | +| ~SPC t I~ | =Ⓘ= | I | aggressive indent mode | +| ~SPC t K~ | =Ⓚ= | K | which-key mode | +| ~SPC t p~ | =ⓟ= | p | [[https://github.com/Fuco1/smartparens][smartparens]] mode | +| ~SPC t C-p~ | =ⓟ= | p | global smartparens | +| ~SPC t s~ | =ⓢ= | s | syntax checking (flycheck) | +| ~SPC t S~ | =Ⓢ= | S | enabled in [[../layers/spell-checking][spell checking layer]] (flyspell) | +| ~SPC t w~ | =ⓦ= | w | whitespace mode | +| ~SPC t C-w~ | =ⓦ= | w | global whitespace | +| ~SPC t W~ | =Ⓦ= | W | automatic whitespace cleanup (see =dotspacemacs-whitespace-cleanup=) | +| ~SPC t C-W~ | =Ⓦ= | W | automatic whitespace cleanup globally | +| ~SPC t y~ | =ⓨ= | y | [[https://github.com/capitaomorte/yasnippet][yasnippet]] mode | + +**** Customizing the mode-line +Spacemacs uses [[https://github.com/TheBB/spaceline][Spaceline]] to provide its mode-line. It consists of a number of +/segments/ arranged on the left and right sides. These are defined in the +variables =spaceline-left= and =spaceline-right=. Segments can be defined using +=spaceline-define-segment=, and added to the appropriate location in the left or +right hand side variables. + +Please see the Spaceline documentation for more information. + +* Layouts and workspaces +Layouts are window configurations with buffer isolation, each layout can define +several workspaces (think of them as sub-layouts) sharing the same list of +buffers as their parent layout. + +** Layouts +A layout is a window configuration associated with a list of buffers. The list +of buffers can be an arbitrarily chosen set of buffers. Spacemacs provides +some facilities to create meaningful sets of buffers, for instance the buffers +related to a projectile project. + +The name of the current layout appears in the mode-line at the far left (first +element of the mode-line). + +To create a new layout type a layout number that does not exist yet. +For instance if you have two layouts currently then type ~SPC l 3~ to create a +third layout. + +*** The default layout +The =default= layout (the layout created at the startup of Emacs) is not +displayed in the mode-line but it is possible to display it by setting the +variable =dotspacemacs-display-default-layout= to =t=. + +Its name is "default" by default but it can be changed by setting the variable +=dotspacemacs-default-layout-name=. + +The =default= layout is special because it has a global scope which means that +all the opened buffers belong to it. So using only the =default= layout feels +like not using layouts at all. + +*** Project layouts +A project layout is bound to a projectile project. To create a project layout +use ~SPC p l~. + +The name of the layout is the name of the project root directory. + +*** Custom Layouts +Custom layouts can be defined using the macro ~spacemacs|define-custom-layout~, +they are accessible via ~SPC l o~. + +By convention the name of a custom layout should start with =@=. + +Example of custom layout definition for =ERC= buffers: + +#+BEGIN_SRC emacs-lisp + (spacemacs|define-custom-layout "@ERC" + :binding "E" + :body + (progn + ;; hook to add all ERC buffers to the layout + (defun spacemacs-layouts/add-erc-buffer-to-persp () + (persp-add-buffer (current-buffer) + (persp-get-by-name + erc-spacemacs-layout-name))) + (add-hook 'erc-mode-hook #'spacemacs-layouts/add-erc-buffer-to-persp) + ;; Start ERC + (call-interactively 'erc))) +#+END_SRC + +Then use ~SPC l o E~ to start ERC inside its own layout. Any new ERC buffer +will be part of the custom layout. + +Some custom layouts that ship with Spacemacs: + +| Name | Key Binding | Description | +|------------+-------------+---------------------------------------------------------------------------------| +| @Spacemacs | ~e~ | Custom perspective containing all buffers of =~/.emacs.d= | +| @ERC | ~E~ | Custom perspective containing all ERC buffers (needs the erc layer enabled) | +| @RCIRC | ~i~ | Custom perspective containing all RCIRC buffers (needs the rcirc layer enabled) | +| @Org | ~o~ | Custom perspective containing all the =org-agenda= buffers | + +*** Save/Load layouts into a file +With ~SPC l s~ and ~SPC l L~ you can save and load layouts to/from a file. + +*Note:* By default, Spacemacs will automatically save the layouts under the name +=persp-auto-save=. + +Setting the variable =dotspacemacs-auto-resume-layouts= to =t= will +automatically resume the last saved layouts. + +*** Layout key bindings +The key bindings are registered in a transient state. The docstring of the +transient state displays the existing layouts and the currently active +layout has square brackets. Pressing a layout number will activate it (or +create a new one) and exit the transient state. It is possible to just preview a +layout with ~Ctrl-~. Pressing ~TAB~ will activate the previously +selected layout. + +Press ~?~ to toggle the full help. + +| Key Binding | Description | +|-------------------+------------------------------------------------------------| +| ~SPC l~ | activate the transient- state | +| ~?~ | toggle the documentation | +| ~[1..9, 0]~ | switch to nth layout | +| ~[C-1..C-9, C-0]~ | switch to nth layout and keep the transient state active | +| ~~ | switch to the latest layout | +| ~a~ | add a buffer to the current layout | +| ~A~ | add all the buffers from another layout in the current one | +| ~b~ | select a buffer in the current layout | +| ~d~ | delete the current layout and keep its buffers | +| ~D~ | delete the other layouts and keep their buffers | +| ~h~ | go to default layout | +| ~C-h~ | previous layout in list | +| ~l~ | select/create a layout with helm | +| ~L~ | load layouts from file | +| ~C-l~ | next layout in list | +| ~n~ | next layout in list | +| ~N~ | previous layout in list | +| ~o~ | open a custom layout | +| ~p~ | previous layout in list | +| ~r~ | remove current buffer from layout | +| ~R~ | rename current layout | +| ~s~ | save layouts | +| ~t~ | display a buffer without adding it to the current layout | +| ~w~ | workspaces transient state (needs eyebrowse layer enabled) | +| ~x~ | kill current layout with its buffers | +| ~X~ | kill other layouts with their buffers | + +** Workspaces +Workspaces are sub-layouts, they allow to define multiple layouts into a given +layout, those layouts share the same buffer as the parent layout. + +The currently active workspace number is displayed before the window number, +for instance "➊|➍" or "1|4" means the fourth window of the first workspace. + +Any new layout comes with a default workspace which is the workspace 1. + +Switching to a workspace that does not exist in the current layout will create a +new one. For instance at startup you can press ~SPC l w 2~ to create the +workspace 2 in the =default= layout. + +When created a workspace is anonymous, you can give them a name with +~SPC l w R~. + +*** Workspace key bindings +The key bindings are registered in a transient state. The docstring of the +transient state displays the existing workspaces and the currently active +workspace has square brackets. Pressing a workspace number will activate it (or +create a new one) and exit the transient state. It is possible to just preview a +workspace with ~Ctrl-~. Pressing ~TAB~ will activate the previously +selected workspace. + +Press ~?~ to toggle the full help. + +| Key Binding | Description | +|-------------------+-------------------------------------------------------------| +| ~SPC l w~ | activate the transient state | +| ~?~ | toggle the documentation | +| ~[1..9, 0]~ | switch to nth workspace | +| ~[C-1..C-9, C-0]~ | switch to nth workspace and keep the transient state active | +| ~TAB~ | switch to last active workspace | +| ~d~ | close current workspace | +| ~n~ or ~l~ | switch to next workspace | +| ~N~ or ~p~ or ~h~ | switch to previous workspace | +| ~R~ | set a tag to the current workspace | +| ~w~ | switched to tagged workspace | + +There are also some handy globally available key bindings related to workspaces: + +| Key Binding | Description | +|-------------+--------------------------------------| +| ~gt~ | go to next workspace | +| ~gT~ | got to previous workspace | +| ~SPC b W~ | go to workspace and window by buffer | + +* Commands +** Vim key bindings +Spacemacs is based on =Vim= modal user interface to navigate and edit text. If +you are not familiar with the =Vim= way of editing text you can try the +[[https://github.com/syl20bnr/evil-tutor][evil-tutor]] lessons by pressing ~SPC h T~ at any time. + +*** Escaping +Spacemacs uses [[https://github.com/syl20bnr/evil-escape][evil-escape]] to +easily switch between =insert state= and =normal state= by quickly pressing the +~fd~ keys. + +The choice of ~fd~ was made to be able to use the same sequence to escape from +"everything" in Emacs: + - escape from all stock evil states to normal state + - escape from evil-lisp-state to normal state + - escape from evil-iedit-state to normal state + - abort evil ex command + - quit minibuffer + - abort isearch + - quit magit buffers + - quit help buffers + - quit apropos buffers + - quit ert buffers + - quit undo-tree buffer + - quit paradox + - quit gist-list menu + - quit helm-ag-edit + - hide neotree buffer + +If you find yourself in a buffer where the Spacemacs (~SPC~) or Vim keybindings +don't work you can use this to get back to =normal state= (for example in ~SPC +SPC customize~ press ~fd~ to make ~SPC b b~ work again). + +This sequence can be customized in your =~/.spacemacs=. +Example to set it to ~jj~: + +#+BEGIN_SRC emacs-lisp +(defun dotspacemacs/user-config () + (setq-default evil-escape-key-sequence "jj")) +#+END_SRC + +*Note*: Although ~jj~ or ~jk~ are popular choices of vim users, these key +sequences are not optimal for Spacemacs. Indeed it is very easy in =visual +state= to press quickly ~jj~ and inadvertently escape to =normal state=. + +*** Executing Vim and Emacs ex/M-x commands + +| Command | Key Binding | +|------------------+-------------| +| Vim (ex-command) | ~:~ | +| Emacs (M-x) | ~SPC SPC~ | + +The emacs command key ~SPC~ (executed after the leader key) can be changed +with the variable =dotspacemacs-emacs-command-key= of your =~/.spacemacs=. + +*** Leader key +On top of =Vim= modes (modes are called states in Spacemacs) there is a +special key called the leader key which once pressed gives a whole new keyboard +layer. The leader key is by default ~SPC~ (space). It is possible to change this +key with the variable =dotspacemacs-leader-key=. + +*** Additional text objects +Additional text objects are defined in Spacemacs: + +| Object | Description | +|---------+----------------------------| +| ~a~ | an argument | +| ~g~ | the entire buffer | +| ~$~ | text between =$= | +| ~*~ | text between =*= | +| ~8~ | text between =/*= and =*/= | +| ~%~ | text between =%= | +| ~\vert~ | text between =\vert= | + +** Reserved prefix command for user +~SPC o~ and ~SPC m o~ are reserved for the user. Setting key bindings behind +these is *guaranteed* to never conflict with Spacemacs default key bindings. + +*Example:* Put =(spacemacs/set-leader-keys "oc" 'org-capture)= inside +=dotspacemacs/user-config= in your =~/.spacemacs= file, to be able to use ~SPC o +c~ to run org mode capture. + +** Completion +Spacemacs is powered by one of two incremental completion and selection +narrowing frameworks: [[https://github.com/emacs-helm/helm][Helm]] (default) or [[https://github.com/abo-abo/swiper][Ivy]]. To use Ivy, add the =ivy= layer to +your list of enabled layers. If the =ivy= layer is not enabled, Helm will be +enabled automatically. (Please note that, as Helm is the more mature of the two, +some functions may be unavailable if you choose Ivy.) + +These completion systems are the central control towers of Spacemacs, they are +used to manage buffers, projects, search results, configuration layers, toggles +and more... + +Mastering your choice of completion system will make you a Spacemacs power user. + +*** Helm +Do not hesitate to read the [[https://github.com/emacs-helm/helm/wiki][Helm documentation wiki]]. + +**** C-z and Tab switch +The command bound to ~C-z~ is much more useful than the one bound to Tab, so it +makes sense to swap them. It's also recommended [[http://tuhdo.github.io/helm-intro.html][here]]. + +**** Helm focus +If you find yourself unable to return focus to Helm (after a careless +mouse-click for example), use ~SPC w b~ to return focus to the minibuffer. + +**** Helm transient state +Spacemacs defines a [[Transient-states][transient state]] for =Helm= to make it work like [[https://github.com/Shougo/unite.vim][Vim's Unite]] +plugin. + +Initiate the transient state with ~M-SPC~ or ~s-M-SPC~ while in a =Helm= buffer. + +| Key Binding | Description | +|----------------------+------------------------------------------------------| +| ~M-SPC~ or ~s-M-SPC~ | initiate the transient state | +| ~q~ | quit transient state | +| ~TAB~ | switch to actions page and leave the transient state | +| ~1~ | execute action 0 | +| ~2~ | execute action 1 | +| ~3~ | execute action 2 | +| ~4~ | execute action 3 | +| ~5~ | execute action 4 | +| ~6~ | execute action 5 | +| ~7~ | execute action 6 | +| ~8~ | execute action 7 | +| ~9~ | execute action 8 | +| ~0~ | execute action 9 | +| ~a~ | switch to actions page | +| ~g~ | go to first candidate | +| ~G~ | go to last candidate | +| ~h~ | go to previous source | +| ~j~ | select next candidate | +| ~k~ | select previous candidate | +| ~l~ | go to next source | +| ~t~ | mark current candidate | +| ~T~ | mark all candidates | +| ~v~ | execute persistent action | + +** Discovering +*** Key bindings +**** Which-key +A help buffer is displayed each time the ~SPC~ key is pressed in normal mode. +It lists the available key bindings and their associated commands. + +By default the [[https://github.com/justbur/emacs-which-key][which-key]] buffer will be displayed quickly after the key has been +pressed. You can change the delay by setting the variable +=dotspacemacs-which-key-delay= to your liking (the value is in second). + +**** Helm describe key bindings +It is possible to search for specific key bindings by pressing ~SPC ?~. + +To narrow the list to some key bindings using the leader key type a pattern like +this regular expression: ~SPC\ b~ which would list all =buffer= related +bindings. + +*** Getting help +=Describe functions= are powerful Emacs introspection commands to get +information about functions, variables, modes etc. These commands are bound +thusly: + +| Key Binding | Description | +|-------------+-----------------------------------------------------------| +| ~SPC h d b~ | describe bindings in a =helm= buffer | +| ~SPC h d c~ | describe current character under point | +| ~SPC h d d~ | describe current expression under point | +| ~SPC h d f~ | describe a function | +| ~SPC h d F~ | describe a face | +| ~SPC h d k~ | describe a key | +| ~SPC h d K~ | describe a keymap | +| ~SPC h d l~ | copy last pressed keys that you can paste in gitter chat | +| ~SPC h d m~ | describe current modes | +| ~SPC h d p~ | describe a package (Emacs built-in function) | +| ~SPC h d P~ | describe a package (Spacemacs layer information) | +| ~SPC h d s~ | copy system information that you can paste in gitter chat | +| ~SPC h d t~ | describe a theme | +| ~SPC h d v~ | describe a variable | + +Other help key bindings: + +| Key Binding | Description | +|-------------+--------------------------------------------------------------------| +| ~SPC h SPC~ | discover Spacemacs documentation, layers and packages using =helm= | +| ~SPC h i~ | search in info pages with the symbol at point | +| ~SPC h k~ | show top-level bindings with =which-key= | +| ~SPC h m~ | search available man pages | +| ~SPC h n~ | browse emacs news | + +Navigation key bindings in =help-mode=: + +| Key Binding | Description | +|--------------+-----------------------------------------------------| +| ~g b~ or ~[~ | go back (same as clicking on =[back]= button) | +| ~g f~ or ~]~ | go forward (same as clicking on =[forward]= button) | +| ~g h~ | go to help for symbol under point | + +Reporting an issue: + +| Key Binding | Description | +|-----------------+------------------------------------------------------------------------------------------| +| ~SPC h I~ | Open Spacemacs GitHub issue page with pre-filled information | +| ~SPC u SPC h I~ | Open Spacemacs GitHub issue page with pre-filled information - include last pressed keys | + +/Note:/ If these two bindings are used with the =*Backtrace*= buffer open, the +backtrace is automatically included + +*** Available layers +All layers can be easily discovered via =helm-spacemacs-help= accessible with +~SPC h SPC~. + +The following helm actions are available: + - default: open the layer =README.org= + - 2nd: open the layer =packages.el= + +**** Available packages in Spacemacs +=helm-spacemacs-help= also lists all the packages available in Spacemacs. The +entry format is =(layer) packages=. If you type =flycheck= you'll be able to see +all the layers where =flycheck= is used. + +The following helm actions are available on packages: + - default: go the package init function + +**** New packages from ELPA repositories +=package-list-packages= is where you can browse for all available packages in the +different Elpa repositories. It is possible to upgrade packages from there but +it is not recommended, use the =[Update Packages]= link on the Spacemacs startup +page instead. + +Spacemacs uses [[https://github.com/Bruce-Connor/paradox][Paradox]] instead of =package-list-packages= to list available +ELPA packages. Paradox enhances the package list buffer with better feedbacks, +new filters and Github information like the number of stars. Optionally you can +also star packages directly in the buffer. + +*Important Note 1*: Installing a new package from =Paradox= won't make it +persistent. To install a package persistently you have to add it explicitly to a +configuration layer. + +*Important Note 2*: Don't /update/ your packages from =Paradox= or +=package-list-packages= because they don't support the rollback feature of +Spacemacs. + +| Key Binding | Description | +|-------------+-------------------------------------------------------| +| ~SPC a k~ | launch =paradox= | +| ~/~ | evil-search | +| ~f k~ | filter by keywords | +| ~f r~ | filter by regexp | +| ~f u~ | display only installed package with updates available | +| ~h~ | go left | +| ~H~ | show help (not accurate) | +| ~j~ | go down | +| ~k~ | go up | +| ~l~ | go right | +| ~L~ | show last commits | +| ~n~ | next search occurrence | +| ~N~ | previous search occurrence | +| ~o~ | open package homepage | +| ~r~ | refresh | +| ~S P~ | sort by package name | +| ~S S~ | sort by status (installed, available, etc...) | +| ~S *~ | sort by Github stars | +| ~v~ | =visual state= | +| ~V~ | =visual-line state= | +| ~x~ | execute (action flags) | + +*** Toggles +=helm-spacemacs-help= is also a central place to discover the available toggles. +To display only the toggles source press ~C-l~ (or in [[Helm transient state][Helm transient state]] you can +press just ~l~). + +The following helm actions are available on packages: + - default: toggle on/off + +*Tips* Use ~SPC h l~ to resume the last helm session. It is handy to quickly +toggle on and off a toggle. + +** Navigating +*** Point/Cursor +Navigation is performed using the Vi key bindings ~hjkl~. + +| Key Binding | Description | +|-------------+-----------------------------------------------------------------------------------| +| ~h~ | move cursor left | +| ~j~ | move cursor down | +| ~k~ | move cursor up | +| ~l~ | move cursor right | +| ~H~ | move cursor to the top of the screen | +| ~L~ | move cursor to the bottom of the screen | +| ~SPC j 0~ | go to the beginning of line (and set a mark at the previous location in the line) | +| ~SPC j $~ | go to the end of line (and set a mark at the previous location in the line) | +| ~SPC t -~ | lock the cursor at the center of the screen | + +**** Smooth scrolling +[[https://github.com/aspiers/smooth-scrolling][smooth-scrolling]] prevent the point to jump when it reaches the top or +bottom of the screen. It is enabled by default. + +On Windows, you may want to disable it. To disable the smooth scrolling set the +=dotspacemacs-smooth-scrolling= variable in your =~/.spacemacs= to =nil=: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-smooth-scrolling nil) +#+END_SRC + +You can also toggle smooth scrolling with ~SPC t v~. + +*** Vim motions with avy +Spacemacs uses the =evil= integration of [[https://github.com/abo-abo/avy][avy]] which enables the +invocation of =avy= during motions. + +For instance, it is useful for deleting a set of visual lines from the current line. +Try the following sequence in a buffer containing some text: ~d SPC j l~, followed by +selecting an avy candidate. + +| Key Binding | Description | +|-------------+----------------------------------------------------| +| ~SPC j b~ | go back to the previous location (before the jump) | +| ~SPC j j~ | initiate avy jump char | +| ~SPC j w~ | initiate avy jump word | +| ~SPC j l~ | initiate avy jump line | + +**** ace-link mode +Similar to =avy=, [[https://github.com/abo-abo/ace-link][ace-link]] allows one to jump to any link in +=help-mode= and =info-mode= with two key strokes. + +| Key Binding | Description | +|-------------+-------------------------------------------------------| +| ~o~ | initiate ace link mode in =help-mode= and =info-mode= | + +*** Unimpaired bindings +Spacemacs comes with a built-in port of [[https://github.com/tpope/vim-unimpaired][tpope's vim-unimpaired]]. + +This plugin provides several pairs of bracket maps using ~[~ to denote +previous, and ~]~ as next. + +| KeyBindings | Description | +|-------------+----------------------------------| +| ~[ SPC~ | Insert space above | +| ~] SPC~ | Insert space below | +| ~[ b~ | Go to previous buffer | +| ~] b~ | Go to next buffer | +| ~[ f~ | Go to previous file in directory | +| ~] f~ | Go to next file in directory | +| ~[ l~ | Go to the previous error | +| ~] l~ | Go to the next error | +| ~[ h~ | Go to the previous vcs hunk | +| ~] h~ | Go to the next vcs hunk | +| ~[ q~ | Go to the previous error | +| ~] q~ | Go to the next error | +| ~[ t~ | Go to the previous frame | +| ~] t~ | Go to the next frame | +| ~[ w~ | Go to the previous window | +| ~] w~ | Go to the next window | +| ~[ e~ | Move line up | +| ~] e~ | Move line down | +| ~[ p~ | Paste above current line | +| ~] p~ | Paste below current line | +| ~g p~ | Select pasted text | + +*** Jumping, Joining and Splitting +The ~SPC j~ prefix is for jumping, joining and splitting. + +**** Jumping + +| Key Binding | Description | +|-------------+-----------------------------------------------------------------------------------| +| ~SPC j 0~ | go to the beginning of line (and set a mark at the previous location in the line) | +| ~SPC j $~ | go to the end of line (and set a mark at the previous location in the line) | +| ~SPC j b~ | undo a jump (go back to previous location) | +| ~SPC j d~ | jump to a listing of the current directory | +| ~SPC j D~ | jump to a listing of the current directory (other window) | +| ~SPC j f~ | jump to the definition of an Emacs Lisp function | +| ~SPC j i~ | jump to a definition in buffer (imenu) | +| ~SPC j I~ | jump to a definition in any buffer (imenu) | +| ~SPC j j~ | jump to a character in the buffer (works as an evil motion) | +| ~SPC j J~ | jump to a suite of two characters in the buffer (works as an evil motion) | +| ~SPC j k~ | jump to next line and indent it using auto-indent rules | +| ~SPC j l~ | jump to a line with avy (works as an evil motion) | +| ~SPC j q~ | show the dumb-jump quick look tooltip | +| ~SPC j u~ | jump to a URL in the current buffer | +| ~SPC j v~ | jump to the definition/declaration of an Emacs Lisp variable | +| ~SPC j w~ | jump to a word in the current buffer (works as an evil motion) | + +**** Joining and splitting + +| Key Binding | Description | +|-------------+--------------------------------------------------------------------------| +| ~J~ | join the current line with the next line | +| ~SPC j k~ | go to next line and indent it using auto-indent rules | +| ~SPC j n~ | split the current line at point, insert a new line and auto-indent | +| ~SPC j s~ | split a quoted string or s-expression in place | +| ~SPC j S~ | split a quoted string or s-expression, insert a new line and auto-indent | + +*** Window manipulation +**** Window manipulation key bindings +Every window has a number displayed at the start of the mode-line and +can be quickly accessed using =SPC number=. + +| Key Binding | Description | +|-------------+-----------------------| +| ~SPC 1~ | go to window number 1 | +| ~SPC 2~ | go to window number 2 | +| ~SPC 3~ | go to window number 3 | +| ~SPC 4~ | go to window number 4 | +| ~SPC 5~ | go to window number 5 | +| ~SPC 6~ | go to window number 6 | +| ~SPC 7~ | go to window number 7 | +| ~SPC 8~ | go to window number 8 | +| ~SPC 9~ | go to window number 9 | +| ~SPC 0~ | go to window number 0 | + +Windows manipulation commands (start with ~w~): + +| Key Binding | Description | +|------------------------+-----------------------------------------------------------------------------| +| ~SPC w =~ | balance split windows | +| ~SPC w b~ | force the focus back to the minibuffer (usefull with =helm= popups) | +| ~SPC w c~ | maximize/minimize a window and center it | +| ~SPC w C~ | maximize/minimize a window and center it using [[https://github.com/abo-abo/ace-window][ace-window]] | +| ~SPC w d~ | delete a window | +| ~SPC u SPC w d~ | delete a window and its current buffer (does not delete the file) | +| ~SPC w D~ | delete another window using [[https://github.com/abo-abo/ace-window][ace-window]] | +| ~SPC u SPC w D~ | delete another window and its current buffer using [[https://github.com/abo-abo/ace-window][ace-window]] | +| ~SPC w t~ | toggle window dedication (dedicated window cannot be reused by a mode) | +| ~SPC w f~ | toggle follow mode | +| ~SPC w F~ | create new frame | +| ~SPC w h~ | move to window on the left | +| ~SPC w H~ | move window to the left | +| ~SPC w j~ | move to window below | +| ~SPC w J~ | move window to the bottom | +| ~SPC w k~ | move to window above | +| ~SPC w K~ | move window to the top | +| ~SPC w l~ | move to window on the right | +| ~SPC w L~ | move window to the right | +| ~SPC w m~ | maximize/minimize a window (maximize is equivalent to delete other windows) | +| ~SPC w M~ | swap windows using [[https://github.com/abo-abo/ace-window][ace-window]] | +| ~SPC w o~ | cycle and focus between frames | +| ~SPC w p m~ | open messages buffer in a popup window | +| ~SPC w p p~ | close the current sticky popup window | +| ~SPC w r~ | rotate windows forward | +| ~SPC w R~ | rotate windows backward | +| ~SPC w s~ or ~SPC w -~ | horizontal split | +| ~SPC w S~ | horizontal split and focus new window | +| ~SPC w u~ | undo window layout (used to effectively undo a closed window) | +| ~SPC w U~ | redo window layout | +| ~SPC w v~ or ~SPC w /~ | vertical split | +| ~SPC w V~ | vertical split and focus new window | +| ~SPC w w~ | cycle and focus between windows | +| ~SPC w W~ | select window using [[https://github.com/abo-abo/ace-window][ace-window]] | + +**** Window manipulation transient state +A convenient window manipulation transient state allows performing most of the +actions listed above. The transient state allows additional actions as well like +window resizing. + +| Key Binding | Description | +|---------------+---------------------------------------------------------------| +| ~SPC w .~ | initiate transient state | +| ~?~ | display the full documentation in minibuffer | +| ~0~ | go to window number 0 | +| ~1~ | go to window number 1 | +| ~2~ | go to window number 2 | +| ~3~ | go to window number 3 | +| ~4~ | go to window number 4 | +| ~5~ | go to window number 5 | +| ~6~ | go to window number 6 | +| ~7~ | go to window number 7 | +| ~8~ | go to window number 8 | +| ~9~ | go to window number 9 | +| ~/~ | vertical split | +| ~-~ | horizontal split | +| ~[~ | shrink window horizontally | +| ~]~ | enlarge window horizontally | +| ~{~ | shrink window vertically | +| ~}~ | enlarge window vertically | +| ~d~ | delete window | +| ~D~ | delete other windows | +| ~g~ | toggle =golden-ratio= on and off | +| ~h~ | go to window on the left | +| ~j~ | go to window below | +| ~k~ | go to window above | +| ~l~ | go to window on the right | +| ~H~ | move window to the left | +| ~J~ | move window to the bottom | +| ~K~ | move bottom to the top | +| ~L~ | move window to the right | +| ~o~ | focus other frame | +| ~r~ | rotate windows forward | +| ~R~ | rotate windows backward | +| ~s~ | horizontal split | +| ~S~ | horizontal split and focus new window | +| ~u~ | undo window layout (used to effectively undo a closed window) | +| ~U~ | redo window layout | +| ~v~ | vertical split | +| ~V~ | horizontal split and focus new window | +| ~w~ | focus other window | +| Any other key | leave the transient state | + +**** Golden ratio +If you resize windows like crazy you may want to give a try to [[https://github.com/roman/golden-ratio.el][golden-ratio]]. + +=golden-ratio= resizes windows dynamically depending on whether they are +selected or not. By default =golden-ratio= is off. + +The mode can be toggled on and off with ~SPC t g~. + +*** Buffers and Files +By default Spacemacs uses =helm= to open files. + +**** Buffers manipulation key bindings +Buffer manipulation commands (start with ~b~): + +| Key Binding | Description | +|-----------------+--------------------------------------------------------------------------| +| ~SPC TAB~ | switch to alternate buffer in the current window (switch back and forth) | +| ~SPC b b~ | switch to a buffer using [[https://github.com/emacs-helm/helm][helm]] | +| ~SPC b d~ | kill the current buffer (does not delete the visited file) | +| ~SPC u SPC b d~ | kill the current buffer and window (does not delete the visited file) | +| ~SPC b D~ | kill a visible buffer using [[https://github.com/abo-abo/ace-window][ace-window]] | +| ~SPC u SPC b D~ | kill a visible buffer and its window using [[https://github.com/abo-abo/ace-window][ace-window]] | +| ~SPC b C-d~ | kill buffers using a regular expression | +| ~SPC b e~ | erase the content of the buffer (ask for confirmation) | +| ~SPC b h~ | open =*spacemacs*= home buffer | +| ~SPC b n~ | switch to next buffer avoiding special buffers | +| ~SPC b m~ | kill all buffers except the current one | +| ~SPC u SPC b m~ | kill all buffers and windows except the current one | +| ~SPC b M~ | kill all buffers matching the regexp | +| ~SPC b p~ | switch to previous buffer avoiding special buffers | +| ~SPC b P~ | copy clipboard and replace buffer (useful when pasting from a browser) | +| ~SPC b R~ | revert the current buffer (reload from disk) | +| ~SPC b s~ | switch to the =*scratch*= buffer (create it if needed) | +| ~SPC b w~ | toggle read-only (writable state) | +| ~SPC b Y~ | copy whole buffer to clipboard (useful when copying to a browser) | +| ~z f~ | Make current function or comments visible in buffer as much as possible | + +**** Buffers manipulation transient state +A convenient buffer manipulation transient state allows to quickly cycles through +the opened buffer and kill them. + +| Key Binding | Description | +|---------------+-----------------------------------------------| +| ~SPC b .~ | initiate transient state | +| ~K~ | kill current buffer | +| ~n~ | go to next buffer (avoid special buffers) | +| ~N~ | go to previous buffer (avoid special buffers) | +| Any other key | leave the transient state | + +**** Special Buffers +Unlike vim, emacs creates many buffers that most people do not need to see. Some +examples are =*Messages*= and =*Compile-Log*=. Spacemacs tries to automatically +ignore buffers that are not useful. However, you may want to change the way +Spacemacs marks buffers as useful. For instructions, see the [[file:FAQ.org::Change%20special%20buffer%20rules?][special buffer howto]]. + +**** Files manipulations key bindings +Files manipulation commands (start with ~f~): + +| Key Binding | Description | +|-------------+---------------------------------------------------------------------------------------------------------------------------------| +| ~SPC f b~ | go to file bookmarks | +| ~SPC f c~ | copy current file to a different location | +| ~SPC f C d~ | convert file from unix to dos encoding | +| ~SPC f C u~ | convert file from dos to unix encoding | +| ~SPC f D~ | delete a file and the associated buffer (ask for confirmation) | +| ~SPC f E~ | open a file with elevated privileges (sudo edit) | +| ~SPC f f~ | open file with =helm= | +| ~SPC f F~ | try to open the file under point =helm= | +| ~SPC f h~ | open binary file with =hexl= (a hex editor) | +| ~SPC f j~ | jump to the current buffer file in dired | +| ~SPC f J~ | open a junk file, in mode determined by the file extension provided (defaulting to =fundamental mode=), using =helm= (or =ivy=) | +| ~SPC f l~ | open file literally in =fundamental mode= | +| ~SPC f L~ | Locate a file (using =locate=) | +| ~SPC f o~ | open a file using the default external program | +| ~SPC f R~ | rename the current file | +| ~SPC f s~ | save a file | +| ~SPC f S~ | save all files | +| ~SPC f r~ | open a recent file with =helm= | +| ~SPC f t~ | toggle file tree side bar using [[https://github.com/jaypei/emacs-neotree][NeoTree]] | +| ~SPC f v d~ | add a directory variable | +| ~SPC f v f~ | add a local variable to the current file | +| ~SPC f v p~ | add a local variable to the first line of the current file | +| ~SPC f y~ | show and copy current file absolute path in the minibuffer | + +**** Emacs and Spacemacs files +Convenient key bindings are located under the prefix ~SPC f e~ to quickly +navigate between =Emacs= and Spacemacs specific files. + +| Key Binding | Description | +|-------------+-----------------------------------------------------------------| +| ~SPC f e d~ | open the spacemacs dotfile (=~/.spacemacs=) | +| ~SPC f e D~ | open =ediff= buffer of =~/.spacemacs= and =.spacemacs.template= | +| ~SPC f e f~ | discover the =FAQ= using =helm= | +| ~SPC f e i~ | open the all mighty =init.el= | +| ~SPC f e l~ | locate an Emacs library | +| ~SPC f e R~ | resync the dotfile with spacemacs | +| ~SPC f e v~ | display and copy the spacemacs version | + +**** Browsing files with Helm +In =vim= and =hybrid= styles, Spacemacs remap the navigation in Helm find-files +to keep finger on the home row. + +| Key Binding | Description | +|-------------+-----------------------------------| +| ~C-h~ | go up one level (parent directory | +| ~C-H~ | describe key (replace ~C-h~) | +| ~C-j~ | go to previous candidate | +| ~C-k~ | go to next candidate | +| ~C-l~ | enter current directory | + +*** Ido +Spacemacs displays the =ido= minibuffer vertically thanks to the +[[https://github.com/gempesaw/ido-vertical-mode.el][ido-vertical-mode]]. + +Basic =ido= operations can be done with ~Ctrl~ key: + +| Key Binding | Description | +|--------------------+---------------------------------------------------| +| ~C-~ | open a =dired buffer= | +| ~M-~ | open a =dired buffer= in terminal | +| ~C-d~ | delete selected file (ask for confirmation) | +| ~C-h~ | go to parent directory | +| ~C-j~ | select next file or directory | +| ~C-k~ | select previous file or directory | +| ~C-l~ | open the selected file | +| ~C-n~ | select next file or directory | +| ~C-o~ | open selected file in other window | +| ~C-p~ | select previous file or directory | +| ~C-s~ | open selected file in a vertically split window | +| ~C-t~ | open selected file in a new frame | +| ~C-v~ | open selected file in a horizontally split window | +| ~C-S-h~ | go to previous directory | +| ~C-S-j~ or ~C-S-n~ | next history element | +| ~C-S-k~ or ~C-S-p~ | previous history element | +| ~C-S-l~ | go to next directory | + +*** Ido transient state +Spacemacs defines a [[Transient-states][transient state]] for =ido=. + +Initiate the transient state with ~M-SPC~ or ~s-M-SPC~ while in an =ido= buffer. + +| Key Binding | Description | +|----------------------+---------------------------------------| +| ~M-SPC~ or ~s-M-SPC~ | initiate or leave the transient state | +| ~?~ | display help | +| ~e~ | open dired | +| ~h~ | delete backward or parent directory | +| ~j~ | next match | +| ~J~ | sub directory | +| ~k~ | previous match | +| ~K~ | parent directory | +| ~l~ | select match | +| ~n~ | next directory in history | +| ~o~ | open in other window | +| ~p~ | previous directory in history | +| ~q~ | quit transient state | +| ~s~ | open in a new horizontal split | +| ~t~ | open in other frame | +| ~v~ | open in a new vertical split | + +*** NeoTree file tree +Spacemacs provides a quick and simple way to navigate in an unknown project +file tree with [[https://github.com/jaypei/emacs-neotree][NeoTree]]. + +To toggle the =NeoTree= buffer press ~SPC f t~ or ~SPC p t~ (the latter open +NeoTree with the root set to the projectile project root). + +The NeoTree window always has the number =0= so it does not shift the current +number of the other windows. To select the NeoTree window you then use ~SPC 0~. + +VCS integration is supported, the file color will change depending on its +current state. With default =spacemacs-dark= theme: +- green: new file +- purple: modified file + +**** NeoTree navigation +Navigation is centered on the ~hjkl~ keys with the hope of providing a fast +navigation experience like in [[http://ranger.nongnu.org/][ranger]]: + +| Key Binding | Description | +|--------------+-------------------------------------------------------------------------------| +| ~h~ | collapse expanded directory or go to parent node | +| ~H~ | select previous sibling | +| ~j~ | select next file or directory | +| ~J~ | select next expanded directory on level down | +| ~k~ | select previous file or directory | +| ~K~ | select parent directory, when reaching the root change it to parent directory | +| ~l~ or ~RET~ | expand directory | +| ~L~ | select next sibling | +| ~R~ | make a directory the root directory | + +*Note*: Point is automatically set to the first letter of a node for a smoother +experience. + +**** Opening files with NeoTree +By default a file is opened in the last active window. It is possible to choose +window number where to open a file by using a numeric argument, for instance ~2 +l~ or ~2 RET~ will open the current file in window 2. It is also possible to +open the file in a split window with ~|~ and ~-~: + +| Key Binding | Description | +|------------------+-------------------------------------------| +| ~l~ or ~RET~ | open file in last active window | +| ~# l~ or ~# RET~ | open file in window number =#= | +| ~¦~ | open file in an vertically split window | +| ~-~ | open file in an horizontally split window | + +**** Other NeoTree key bindings + +| Key Binding | Description | +|-------------+---------------------------------| +| ~TAB~ | toggle stretching of the buffer | +| ~c~ | create a node | +| ~d~ | delete a node | +| ~gr~ | refresh | +| ~s~ | toggle showing of hidden files | +| ~q~ or ~fd~ | hide =NeoTree= buffer | +| ~r~ | rename a node | +| ~?~ | show help | + +**** NeoTree mode-line +The mode-line has the following format =[x/y] d (D:a, F:b)= where: + - =x= is the index of the current selected file or directory + - =y= the total number of items (file and directory) in the current directory + - =d= the name of the current directory + - =a= the number of directories in the current directory + - =b= the number of files in the current directory + +**** NeoTree Source Control Integration +If you would like NeoTree to show source control information, you can use the +setting =neo-vc-integration=. It is a list containing the possible values: + +| Setting | Description | +|---------+---------------------------------------------------------------------------| +| =face= | Show information by changing the color of the file/directory name. | +| =char= | Show information with a character to the left of the file/directory name. | + +The default is =nil= (do not show source control information), which is recommended. + +For example, + +#+BEGIN_SRC emacs-lisp +(setq neo-vc-integration 'face) +#+END_SRC + +*Note*: At this time, it is not recommended to set this to anything other +than =nil=. Otherwise, it will become very slow with larger source trees. +See https://github.com/jaypei/emacs-neotree/issues/126 for more information. + +**** NeoTree Theme +You can change the NeoTree theme by using the setting =neo-theme=. Possible +values are: + +| Setting | Description | +|-----------+------------------------------------------------------------------| +| =classic= | Use an icon to display items - only suitable for gui mode. | +| =ascii= | The simplest style, it will use =x=, =-= to display fold status. | +| =arrow= | Use unicode arrows to display fold status. | +| =nerd= | Use the NERDTree indentation mode and arrows. | + +The default is =classic=. + +Use =nerd= if you want it to look most like NERDTree in VIM. For example: + +#+BEGIN_SRC emacs-lisp +(setq neo-theme 'nerd) +#+END_SRC + +*** Bookmarks +Bookmarks can be set anywhere in a file. Bookmarks are persistent. They are very +useful to jump to/open a known project. Spacemacs uses =helm-bookmarks= to +manage them. + +Open an =helm= window with the current bookmarks by pressing: ~SPC f b~ + +Then in the =helm-bookmarks= buffer: + +| Key Binding | Description | +|-------------+----------------------------------------------| +| ~C-d~ | delete the selected bookmark | +| ~C-e~ | edit the selected bookmark | +| ~C-f~ | toggle filename location | +| ~C-o~ | open the selected bookmark in another window | + +To save a new bookmark, just type the name of the bookmark and press ~RET~. + +*** DocView mode +=doc-view-mode= is a built-in major mode to view DVI, PostScript (PS), PDF, +OpenDocument, and Microsoft Office documents. + +| Key Binding | Description | +|-------------+------------------------------------------| +| ~/~ | search forward | +| ~?~ | search backward | +| ~+~ | enlarge | +| ~-~ | shrink | +| ~gg~ | go to first page | +| ~G~ | go to last page | +| ~gt~ | go to page number | +| ~h~ | previous page | +| ~H~ | adjust to height | +| ~j~ | next line | +| ~k~ | previous line | +| ~K~ | kill proc and buffer | +| ~l~ | next page | +| ~n~ | go to next search occurrence | +| ~N~ | go to previous search occurrence | +| ~P~ | fit page to window | +| ~r~ | revert | +| ~W~ | adjust to width | +| ~C-d~ | scroll down | +| ~C-k~ | kill proc | +| ~C-u~ | scroll up | +| ~C-c C-c~ | toggle display text and image display | +| ~C-c C-t~ | open new buffer with doc's text contents | + +** Auto-saving +*** Frequency of auto-saving +By default auto-saving of files is performed every 300 characters and +every 30 seconds of idle time which can be changed by setting to a +new value the variables =auto-save-inteval= and =auto-save-timeout= +respectively. + +*** Location of auto-saved files +Auto-save of modified files can be performed in-place on the original file +itself /or/ in the cache directory (in this case the original file will remain +unsaved). By default Spacemacs auto-save the file in the cache directory. + +To modify the location set the variable =dotspacemacs-auto-save-file-location= +to =original= or =cache=. + +Local files are auto-saved in a sub-directory called =site= in the =cache= +directory whereas remote files (i.e. files edited over TRAMP) are auto-saved +in a sub-directory called =dist=. + +*** Disable auto-save +To disable auto-saving set the variable =dotspacemacs-auto-save-file-location= +to =nil=. + +You can toggle auto-save in a buffer by calling the command =auto-save-mode=. + +** Searching +*** With an external tool +Spacemacs can be interfaced with different search utilities like: + - ack + - grep + - [[https://github.com/ggreer/the_silver_searcher][ag]] + - [[https://github.com/monochromegane/the_platinum_searcher][pt]] + +The search commands in Spacemacs are organized under the ~SPC s~ prefix with the +next key is the tool to use and the last key is the scope. For instance ~SPC s a +b~ will search in all opened buffers using =ag=. + +If the last key (determining the scope) is uppercase then the current region or +symbol under point is used as default input for the search. For instance ~SPC s +a B~ will search with symbol under point (if there is no active region). + +If the tool key is omitted then a default tool will be automatically selected +for the search. This tool corresponds to the first tool found on the system of +the list =dotspacemacs-search-tools=, the default order is =ag=, =pt=, =ack= +then =grep=. For instance ~SPC s b~ will search in the opened buffers using =pt= +if =ag= has not been found on the system. + +The tool keys are: + +| Tool | Key | +|------+-----| +| ag | a | +| grep | g | +| ack | k | +| pt | t | + +The available scopes and corresponding keys are: + +| Scope | Key | +|----------------------------+-----| +| opened buffers | b | +| files in a given directory | f | +| current project | p | + +It is possible to search in the current file by double tapping the second key +of the sequence, for instance ~SPC s a a~ will search in the current +file with =ag=. + +*Notes*: +- =ag= and =pt= are optimized to be used in a source control repository but + they can be used in an arbitrary directory as well. +- It is also possible to search in several directories at once by marking + them in the helm buffer. + +*Beware* if you use =pt=, [[https://core.tcl.tk/tcllib/doc/trunk/embedded/www/tcllib/files/apps/pt.html][TCL parser tools]] also install a command line tool +called =pt=. + +**** Useful key bindings + +| Key Binding | Description | +|------------------------+---------------------------------------------------------------| +| ~F3~ | in a =helm= or =ivy= buffer, save results to a regular buffer | +| ~SPC r l~ | resume the last =completion= buffer | +| ~SPC r s~ or ~SPC s l~ | resume search buffer (completion or converted search buffer) | +| ~SPC s `~ | go back to the previous place reached with =helm-ag= | +| Prefix argument | will ask for file extensions | + +When results have been saved in a regular buffer with ~F3~, that buffer supports +browsing through the matches with Spacemacs’ =next-error= and =previous-error= +bindings (~SPC e n~ and ~SPC e p~) as well as the error transient state (~SPC e~). + +**** Searching in current file + +| Key Binding | Description | +|-------------+-----------------------------------------------------| +| ~SPC s s~ | search with the first found tool | +| ~SPC s S~ | search with the first found tool with default input | +| ~SPC s a a~ | =ag= | +| ~SPC s a A~ | =ag= with default input | +| ~SPC s g g~ | =grep= | +| ~SPC s g G~ | =grep= with default input | + +**** Searching in all open buffers visiting files + +| Key Binding | Description | +|-------------+-----------------------------------------------------| +| ~SPC s b~ | search with the first found tool | +| ~SPC s B~ | search with the first found tool with default input | +| ~SPC s a b~ | =ag= | +| ~SPC s a B~ | =ag= with default text | +| ~SPC s g b~ | =grep= | +| ~SPC s g B~ | =grep= with default text | +| ~SPC s k b~ | =ack= | +| ~SPC s k B~ | =ack= with default text | +| ~SPC s t b~ | =pt= | +| ~SPC s t B~ | =pt= with default text | + +**** Searching in files in an arbitrary directory + +| Key Binding | Description | +|-------------+-----------------------------------------------------| +| ~SPC s f~ | search with the first found tool | +| ~SPC s F~ | search with the first found tool with default input | +| ~SPC s a f~ | =ag= | +| ~SPC s a F~ | =ag= with default text | +| ~SPC s g f~ | =grep= | +| ~SPC s g F~ | =grep= with default text | +| ~SPC s k f~ | =ack= | +| ~SPC s k F~ | =ack= with default text | +| ~SPC s t f~ | =pt= | +| ~SPC s t F~ | =pt= with default text | + +**** Searching in a project + +| Key Binding | Description | +|-----------------------+-----------------------------------------------------| +| ~SPC /~ or ~SPC s p~ | search with the first found tool | +| ~SPC *~ or ~SPC s P~ | search with the first found tool with default input | +| ~SPC s a p~ | =ag= | +| ~SPC s a P~ | =ag= with default text | +| ~SPC s g p~ | =grep= with default text | +| ~SPC s k p~ | =ack= | +| ~SPC s k P~ | =ack= with default text | +| ~SPC s t p~ | =pt= | +| ~SPC s t P~ | =pt= with default text | + +*Hint*: It is also possible to search in a project without needing to open a +file beforehand. To do so use ~SPC p p~ and then ~C-s~ on a given project to +directly search into it like with ~SPC s p~. + +**** Searching the web + +| Key Binding | Description | +|-------------+----------------------------------------------------------------------| +| ~SPC s w g~ | Get Google suggestions in emacs. Opens Google results in Browser. | +| ~SPC s w w~ | Get Wikipedia suggestions in emacs. Opens Wikipedia page in Browser. | + +*** Persistent highlighting +Spacemacs uses =evil-search-highlight-persist= to keep the searched expression +highlighted until the next search. It is also possible to clear the highlighting +by pressing ~SPC s c~ or executing the ex command =:noh=. + +*** Highlight current symbol +Spacemacs supports highlighting of the current symbol on demand (provided by +[[https://github.com/emacsmirror/auto-highlight-symbol][auto-highlight-symbol]] mode) and adds a transient state to easily navigate and rename +this symbol. + +It is also possible to change the range of the navigation on the fly to: + - buffer + - function + - visible area + +To initiate the highlighting of the current symbol under point press ~SPC s h~. + +Navigation between the highlighted symbols can be done with the commands: + +| Key Binding | Description | +|-------------+------------------------------------------------------------------------------------| +| ~*~ | initiate navigation transient state on current symbol and jump forwards | +| ~#~ | initiate navigation transient state on current symbol and jump backwards | +| ~SPC s e~ | edit all occurrences of the current symbol(/) | +| ~SPC s h~ | highlight the current symbol and all its occurrence within the current range | +| ~SPC s H~ | go to the last searched occurrence of the last highlighted symbol | +| ~SPC t h a~ | toggle automatic highlight of symbol under point after =ahs-idle-interval= seconds | + +In 'Spacemacs' highlight symbol transient state: + +| Key Binding | Description | +|---------------+---------------------------------------------------------------| +| ~e~ | edit occurrences (*) | +| ~n~ | go to next occurrence | +| ~N~ | go to previous occurrence | +| ~d~ | go to next definition occurrence | +| ~D~ | go to previous definition occurrence | +| ~r~ | change range (=function=, =display area=, =whole buffer=) | +| ~R~ | go to home occurrence (reset position to starting occurrence) | +| Any other key | leave the navigation transient state | + +(*) using [[https://github.com/tsdh/iedit][iedit]] or the default implementation +of =auto-highlight-symbol= + +The transient state text in minibuffer display the following information: + +#+BEGIN_EXAMPLE + [6/11]* press (n/N) to navigate, (e) to edit, (r) to change range or (R) + for reset +#+END_EXAMPLE + +Where = [x/y]*= is: + - M: the current range mode + - ==: whole buffer range + - ==: current display range + - ==: current function range + - =x=: the index of the current highlighted occurrence + - =y=: the total number of occurrences + - =*=: appears if there is at least one occurrence which is not currently visible. + +*** Visual Star +With [[https://github.com/bling/evil-visualstar][evil-visualstar]] you can search for the next occurrence of the current +selection. + +It is pretty useful combined with the [[Region selection][expand-region]] bindings. + +*Note*: If the current state is not the =visual state= then pressing ~*~ uses +auto-highlight-symbol and its transient state. + +*** Listing symbols by semantic +Use =helm-semantic-or-imenu= command from =Helm= to quickly navigate between the +symbols in a buffer. + +To list all the symbols of a buffer press: ~SPC s j~ + +*** Helm-swoop +This is very similar to =moccur=, it displays a =helm= buffer with all the +occurrences of the word under point. You can then change the search query in +real-time and navigate between them easily. + +You can even edit the occurrences directly in the =helm= buffer and apply the +modifications to the buffer. + +| Key Binding | Description | +|-------------+--------------------------------| +| ~SPC s s~ | execute =helm-swoop= | +| ~SPC s S~ | execute =helm-multi-swoop= | +| ~SPC s C-s~ | execute =helm-multi-swoop-all= | + +** Editing +*** Paste text +**** Paste Transient-state +The paste transient state can be enabled by settings the variable +=dotspacemacs-enable-paste-transient-state= to =t=. By default it is disabled. + +When the transient state is enabled, pressing ~p~ again will replace the pasted text +with the previous yanked (copied) text on the kill ring. + +For example if you copy =foo= and =bar= then press ~p~ the text =bar= will +be pasted, pressing ~p~ again will replace =bar= with =foo=. + +| Key Binding | Description | +|---------------+-------------------------------------------------------------------------------| +| ~p~ or ~P~ | paste the text before or after point and initiate the =paste= transient state | +| ~C-j~ | in transient state: replace paste text with the previously copied one | +| ~C-k~ | in transient state: replace paste text with the next copied one | +| Any other key | leave the transient state | + +**** Auto-indent pasted text +By default any pasted text will be auto-indented. To paste text un-indented use +the universal argument. + +It is possible to disable the auto-indentation for specific major-modes by +adding a major-mode to the variable =spacemacs-indent-sensitive-modes= in your +=dotspacemacs/user-config= function. + +*** Text manipulation commands +Text related commands (start with ~x~): + +| Key Binding | Description | +|-------------+---------------------------------------------------------------| +| ~SPC x a &~ | align region at & | +| ~SPC x a (~ | align region at ( | +| ~SPC x a )~ | align region at ) | +| ~SPC x a ​,​~ | align region at , | +| ~SPC x a .~ | align region at . (for numeric tables) | +| ~SPC x a :~ | align region at : | +| ~SPC x a ;~ | align region at ; | +| ~SPC x a =~ | align region at = | +| ~SPC x a a~ | align region (or guessed section) using default rules | +| ~SPC x a c~ | align current intendation region using default rules | +| ~SPC x a r~ | align region using user-specified regexp | +| ~SPC x a m~ | align region at arithmetic operators (+-*/) | +| ~SPC x a ¦~ | align region at ¦ | +| ~SPC x c~ | count the number of chars/words/lines in the selection region | +| ~SPC x d w~ | delete trailing whitespaces | +| ~SPC x g l~ | set languages used by translate commands | +| ~SPC x g t~ | translate current word using Google Translate | +| ~SPC x g T~ | reverse source and target languages | +| ~SPC x j c~ | set the justification to center | +| ~SPC x j f~ | set the justification to full | +| ~SPC x j l~ | set the justification to left | +| ~SPC x j n~ | set the justification to none | +| ~SPC x j r~ | set the justification to right | +| ~SPC x J~ | move down a line of text (enter transient state) | +| ~SPC x K~ | move up a line of text (enter transient state) | +| ~SPC x l s~ | sort lines | +| ~SPC x l u~ | uniquify lines | +| ~SPC x o~ | use avy to select a link in the frame and open it | +| ~SPC x O~ | use avy to select multiple links in the frame and open them | +| ~SPC x t c~ | swap (transpose) the current character with the previous one | +| ~SPC x t w~ | swap (transpose) the current word with the previous one | +| ~SPC x t l~ | swap (transpose) the current line with the previous one | +| ~SPC x u~ | set the selected text to lower case | +| ~SPC x U~ | set the selected text to upper case | +| ~SPC x w c~ | count the number of occurrences per word in the select region | +| ~SPC x w d~ | show dictionary entry of word from wordnik.com | +| ~SPC x TAB~ | indent or dedent a region rigidly | + +*** Text insertion commands +Text insertion commands (start with ~i~): + +| Key binding | Description | +|-------------+-----------------------------------------------------------------------| +| ~SPC i l l~ | insert lorem-ipsum list | +| ~SPC i l p~ | insert lorem-ipsum paragraph | +| ~SPC i l s~ | insert lorem-ipsum sentence | +| ~SPC i u~ | Search for Unicode characters and insert them into the active buffer. | +| ~SPC i U 1~ | insert UUIDv1 (use universal argument to insert with CID format) | +| ~SPC i U 4~ | insert UUIDv4 (use universal argument to insert with CID format) | +| ~SPC i U U~ | insert UUIDv4 (use universal argument to insert with CID format) | + +*** Smartparens Strict mode +[[https://github.com/Fuco1/smartparens][Smartparens]] comes with a strict mode which prevents deletion of parenthesis if +the result is unbalanced. + +This mode can be frustrating for novices, this is why it is not enabled by +default. + +It is possible to enable it easily for /all programming modes/ with the variable +=dotspacemacs-smartparens-strict-mode= of you =~/.spacemacs=. + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-smartparens-strict-mode t) +#+END_SRC + +*** Zooming +**** Text +The font size of the current buffer can be adjusted with the commands: + +| Key Binding | Description | +|---------------+--------------------------------------------------------------------------------| +| ~SPC z x +~ | scale up the font and initiate the font scaling transient state | +| ~SPC z x =~ | scale up the font and initiate the font scaling transient state | +| ~SPC z x -~ | scale down the font and initiate the font scaling transient state | +| ~SPC z x 0~ | reset the font size (no scaling) and initiate the font scaling transient state | +| ~+~ | increase the font size | +| ~=~ | increase the font size | +| ~-~ | decrease the font size | +| ~0~ | reset the font size | +| Any other key | leave the font scaling transient state | + +Note that /only/ the text of the current buffer is scaled, the other buffers, +the mode-line and the minibuffer are not affected. To zoom the whole content of +a frame use the =zoom frame= bindings (see next section). + +**** Frame +You can zoom in and out the whole content of the frame with the commands: + +| Key Binding | Description | +|---------------+-----------------------------------------------------------------------------| +| ~SPC z f +~ | zoom in the frame content and initiate the frame scaling transient state | +| ~SPC z f =~ | zoom in the frame content and initiate the frame scaling transient state | +| ~SPC z f -~ | zoom out the frame content and initiate the frame scaling transient state | +| ~SPC z f 0~ | reset the frame content size and initiate the frame scaling transient state | +| ~+~ | zoom in | +| ~=~ | zoom in | +| ~-~ | zoom out | +| ~0~ | reset zoom | +| Any other key | leave the zoom frame transient state | + +*** Increase/Decrease numbers +Spacemacs uses [[https://github.com/cofi/evil-numbers][evil-numbers]] to easily increase or decrease numbers. + +| Key Binding | Description | +|-------------+---------------------------------------------------------------------| +| ~SPC n +~ | increase the number under point by one and initiate transient state | +| ~SPC n -~ | decrease the number under point by one and initiate transient state | + +In transient state: + +| Key Binding | Description | +|---------------+----------------------------------------| +| ~+~ | increase the number under point by one | +| ~-~ | decrease the number under point by one | +| Any other key | leave the transient state | + +*Tips:* you can increase or decrease a value by more that once by using a prefix +argument (ie. ~10 SPC n +~ will add 10 to the number under point). + +*** Spell checking +Spell checking is enabled by including the [[../layers/spell-checking][spell +checking]] layer in your dotfile. + +Keybindings are listed in the layer documentation. + +*** Region selection +Vi =Visual= modes are all supported by =evil=. + +**** Expand-region +Spacemacs adds another =Visual= mode via the [[https://github.com/magnars/expand-region.el][expand-region]] mode. + +| Key Binding | Description | +|-------------+------------------------------------------| +| ~SPC v~ | initiate expand-region mode then... | +| ~v~ | expand the region by one semantic unit | +| ~V~ | contract the region by one semantic unit | +| ~r~ | reset the region to initial selection | +| ~ESC~ | leave expand-region mode | + +**** Indent text object +With [[https://github.com/TheBB/evil-indent-plus][evil-indent-plus]] the following text objects are available: + +- ~ii~ - Inner Indentation: the surrounding textblock with the same indentation +- ~iI~ - Above and Indentation: ~ii~ + the line above with a different indentation +- ~iJ~ - Above, Below and Indentation+: ~iI~ + the line below with a different indentation + +There are also ~a~ variants that include whitespace. Example (=|= indicates point): + +#+BEGIN_SRC emacs-lisp + (while (not done) + (messa|ge "All work and no play makes Jack a dull boy.")) + (1+ 41) +#+END_SRC + +- ~vii~ will select the line with message +- ~viI~ will select the whole while loop +- ~viJ~ will select the whole fragment + +*** Region narrowing +The displayed text of a buffer can be narrowed with the commands (start with +~n~): + +| Key Binding | Description | +|-------------+-------------------------------------------| +| ~SPC n f~ | narrow the buffer to the current function | +| ~SPC n p~ | narrow the buffer to the visible page | +| ~SPC n r~ | narrow the buffer to the selected text | +| ~SPC n w~ | widen, i.e show the whole buffer again | + +*** Replacing text with iedit +Spacemacs uses the powerful [[https://github.com/tsdh/iedit][iedit]] mode through [[https://github.com/syl20bnr/evil-iedit-state][evil-iedit-state]] to quickly +edit multiple occurrences of a symbol or selection. + +=evil-iedit-state= defines two new evil states: + - =iedit state= + - =iedit-insert state= + +The color code for these states is =red=. + +=evil-iedit-state= has also a nice integration with [[https://github.com/magnars/expand-region.el][expand-region]] for quick +editing of the currently selected text by pressing ~e~. + +**** iedit states key bindings +***** State transitions + +| Key Binding | From | To | +|-------------+------------------+--------| +| ~SPC s e~ | normal or visual | iedit | +| ~e~ | expand-region | iedit | +| ~ESC~ | iedit | normal | +| ~C-g~ | iedit | normal | +| ~fd~ | iedit | normal | +| ~ESC~ | iedit-insert | iedit | +| ~C-g~ | iedit-insert | normal | +| ~fd~ | iedit-insert | normal | + +To sum-up, in =iedit-insert state= you have to press ESC twice to go back to the +=normal state=. You can also at any time press ~C-g~ or ~fd~ to return to =normal +state=. + +*Note*: evil commands which switch to =insert state= will switch in +=iedit-insert state=. + +***** In iedit state +=iedit state= inherits from =normal state=, the following key bindings are +specific to =iedit state=. + +| Key Binding | Description | +|-------------+-----------------------------------------------------------------------------------------| +| ~ESC~ | go back to =normal state= | +| ~TAB~ | toggle current occurrence | +| ~0~ | go to the beginning of the current occurrence | +| ~$~ | go to the end of the current occurrence | +| ~#~ | prefix all occurrences with an increasing number (SPC u to choose the starting number). | +| ~A~ | go to the end of the current occurrence and switch to =iedit-insert state= | +| ~D~ | delete the occurrences | +| ~F~ | restrict the scope to the function | +| ~gg~ | go to first occurrence | +| ~G~ | go to last occurrence | +| ~I~ | go to the beginning of the current occurrence and switch to =iedit-insert state= | +| ~J~ | increase the editing scope by one line below | +| ~K~ | increase the editing scope by one line above | +| ~L~ | restrict the scope to the current line | +| ~n~ | go to next occurrence | +| ~N~ | go to previous occurrence | +| ~p~ | replace occurrences with last yanked (copied) text | +| ~S~ | (substitute) delete the occurrences and switch to =iedit-insert state= | +| ~V~ | toggle visibility of lines with no occurrence | +| ~U~ | Up-case the occurrences | +| ~C-U~ | down-case the occurrences | + +*Note*: ~0~, ~$~, ~A~ and ~I~ have the default Vim behavior when used outside of +an ~occurrence~. + +***** In iedit-insert state + +| Key Binding | Description | +|-------------+---------------------------| +| ~ESC~ | go back to =iedit state= | +| ~C-g~ | go back to =normal state= | + +**** Examples +- manual selection of several words then replace: ~v w w SPC s e S "toto" ESC ESC~ +- append text to a word on two lines: ~v i w SPC s e J i "toto" ESC ESC~ +- substitute symbol /with expand-region/: ~SPC v v e S "toto" ESC ESC~ +- replace symbol with yanked (copied) text /with expand region/: ~SPC v + e p ESC ESC~ + +*** Replacing text in several files +If you have =ag=, =pt= or =ack= installed, replacing an occurrence of text in +several files can be performed via [[https://github.com/syohex/emacs-helm-ag][helm-ag]]. + +Say you want to replace all =foo= occurrences by =bar= in your current +project: + - initiate a search with ~SPC /~ + - enter in edit mode with ~C-c C-e~ + - go to the occurrence and enter in =iedit state= with ~SPC s e~ + - edit the occurrences then leave the =iedit state= + - press ~C-c C-c~ + +*Note*: In Spacemacs, =helm-ag= despite its name works with =ack= and =pt= as +well (but not with =grep=). + +*** Renaming files in a directory +It is possible to batch rename files in a directory using =wdired= from an +=helm= session: +- browse for a directory using ~SPC f f~ +- enter =wdired= with ~C-c C-e~ +- edit the file names and use ~C-c C-c~ to confirm the changes +- use ~C-c C-k~ to abort any changes + +*** Commenting +Comments are handled by [[https://github.com/redguardtoo/evil-nerd-commenter][evil-nerd-commenter]], it's bound to the following keys. + +| Key Binding | Description | +|-------------+---------------------------| +| ~SPC ;~ | comment operator | +| ~SPC c h~ | hide/show comments | +| ~SPC c l~ | comment lines | +| ~SPC c L~ | invert comment lines | +| ~SPC c p~ | comment paragraphs | +| ~SPC c P~ | invert comment paragraphs | +| ~SPC c t~ | comment to line | +| ~SPC c T~ | invert comment to line | +| ~SPC c y~ | comment and yank | +| ~SPC c Y~ | invert comment and yank | + +*Tips:* To comment efficiently a block of line use the combo ~SPC ; SPC y~ + +*** Regular expressions +Spacemacs uses the packages [[https://github.com/joddie/pcre2el][pcre2el]] to manipulate regular expressions. It is +useful when working with =Emacs Lisp= buffers since it allows to easily converts +=PCRE= (Perl Compatible RegExp) to Emacs RegExp or =rx=. It can also be used to +"explain" a PCRE RegExp around point in =rx= form. + +The key bindings start with ~SPC x r~ and have the following mnemonic structure: + +- ~SPC x r ~ convert from source to target +- ~SPC x r~ do what I mean + +| Key Binding | Function | +|---------------+----------------------------------------------------------------------------------------| +| ~SPC x r /~ | Explain the regexp around point with =rx= | +| ~SPC x r '​~ | Generate strings given by a regexp given this list is finite | +| ~SPC x r t~ | Replace regexp around point by the =rx= form or vice versa | +| ~SPC x r x~ | Convert regexp around point in =rx= form and display the result in the minibuffer | +| ~SPC x r c~ | Convert regexp around point to the other form and display the result in the minibuffer | +| ~SPC x r e /~ | Explain Emacs Lisp regexp | +| ~SPC x r e '​~ | Generate strings from Emacs Lisp regexp | +| ~SPC x r e p~ | Convert Emacs Lisp regexp to PCRE | +| ~SPC x r e t~ | Replace Emacs Lisp regexp by =rx= form or vice versa | +| ~SPC x r e x~ | Convert Emacs Lisp regexp to =rx= form | +| ~SPC x r p /~ | Explain PCRE regexp | +| ~SPC x r p '​~ | Generate strings from PCRE regexp | +| ~SPC x r p e~ | Convert PCRE regexp to Emacs Lisp | +| ~SPC x r p x~ | Convert PCRE to =rx= form | + +*** Deleting files +Deletion is configured to send deleted files to system trash. + +On OS X the =trash= program is required. It can be installed with [[http:www.brew.sh][homebrew]] with +the following command: + +#+BEGIN_SRC sh +$ brew install trash +#+END_SRC + +To disable the trash you can set the variable =delete-by-moving-to-trash= to +=nil= in your =~/.spacemacs=. + +*** Editing Lisp code +Editing of lisp code is provided by [[https://github.com/syl20bnr/evil-lisp-state][evil-lisp-state]]. + +Commands will set the current state to =lisp state= where different commands +combo can be repeated without pressing on ~SPC k~. + +When in =lisp state= the color of the mode-line changes to pink. + +Examples: + - to slurp three times while in normal state: ~SPC k 3 s~ + - to wrap a symbol in parentheses then slurp two times: ~SPC k w 2 s~ + +*Note*: The =lisp state= commands are available in /any/ modes! Try it out. + +**** Lisp Key Bindings +***** Lisp state key bindings +These commands automatically switch to =lisp state=. + +| Key Binding | Function | +|-------------+---------------------------------------------------------------------| +| ~SPC k %~ | evil jump item | +| ~SPC k :~ | ex command | +| ~SPC k (~ | insert expression before (same level as current one) | +| ~SPC k )~ | insert expression after (same level as current one) | +| ~SPC k $~ | go to the end of current sexp | +| ~SPC k ` k~ | hybrid version of push sexp (can be used in non lisp dialects) | +| ~SPC k ` p~ | hybrid version of push sexp (can be used in non lisp dialects) | +| ~SPC k ` s~ | hybrid version of slurp sexp (can be used in non lisp dialects) | +| ~SPC k ` t~ | hybrid version of transpose sexp (can be used in non lisp dialects) | +| ~SPC k 0~ | go to the beginning of current sexp | +| ~SPC k a~ | absorb expression | +| ~SPC k b~ | forward barf expression | +| ~SPC k B~ | backward barf expression | +| ~SPC k c~ | convolute expression | +| ~SPC k ds~ | delete symbol | +| ~SPC k Ds~ | backward delete symbol | +| ~SPC k dw~ | delete word | +| ~SPC k Dw~ | backward delete word | +| ~SPC k dx~ | delete expression | +| ~SPC k Dx~ | backward delete expression | +| ~SPC k e~ | unwrap current expression and kill all symbols after point | +| ~SPC k E~ | unwrap current expression and kill all symbols before point | +| ~SPC k h~ | previous symbol | +| ~SPC k H~ | go to previous sexp | +| ~SPC k i~ | switch to =insert state= | +| ~SPC k I~ | go to beginning of current expression and switch to =insert state= | +| ~SPC k j~ | next closing parenthesis | +| ~SPC k J~ | join expression | +| ~SPC k k~ | previous opening parenthesis | +| ~SPC k l~ | next symbol | +| ~SPC k L~ | go to next sexp | +| ~SPC k p~ | paste after | +| ~SPC k P~ | paste before | +| ~SPC k r~ | raise expression (replace parent expression by current one) | +| ~SPC k s~ | forward slurp expression | +| ~SPC k S~ | backward slurp expression | +| ~SPC k t~ | transpose expression | +| ~SPC k u~ | undo | +| ~SPC k U~ | got to parent sexp backward | +| ~SPC k C-r~ | redo | +| ~SPC k v~ | switch to =visual state= | +| ~SPC k V~ | switch to =visual line state= | +| ~SPC k C-v~ | switch to =visual block state= | +| ~SPC k w~ | wrap expression with parenthesis | +| ~SPC k W~ | unwrap expression | +| ~SPC k y~ | copy expression | + +***** Emacs lisp specific key bindings + +| Key Binding | Function | +|-------------+--------------------------------------------| +| ~SPC m e $~ | go to end of line and evaluate last sexp | +| ~SPC m e b~ | evaluate buffer | +| ~SPC m e c~ | evaluate current form (a =def= or a =set=) | +| ~SPC m e e~ | evaluate last sexp | +| ~SPC m e f~ | evaluate current defun | +| ~SPC m e l~ | go to end of line and evaluate last sexp | +| ~SPC m e r~ | evaluate region | + +| Key Binding | Function | +|-------------+----------------------------------------------------| +| ~SPC m g g~ | go to definition | +| ~SPC m g G~ | go to definition in another window | +| ~SPC m h h~ | describe elisp thing at point (show documentation) | +| ~SPC m t b~ | execute buffer tests | +| ~SPC m t q~ | ask for test function to execute | + +*** Mouse usage +There are some added mouse features set for the line number margin (if shown): + +- single click in line number margin visually selects the entire line +- drag across line number margin visually selects the region +- double click in line number margin visually select the current code block + +** Managing projects +Projects in Spacemacs are managed with [[https://github.com/bbatsov/projectile][projectile]]. In =projectile= projects +are defined implicitly, for instance the root of a project is found when a +=.git= repository or =.projectile= file is encountered in the file tree. + +=Helm= is used whenever it is possible. + +To search in a project see [[Searching in a project][project searching]]. + +=projectile= commands start with p: + +| Key Binding | Description | +|-------------+---------------------------------------------------------| +| ~SPC p '​~ | open a shell in project's root (with the =shell= layer) | +| ~SPC p !~ | run shell command in project's root | +| ~SPC p &~ | run async shell command in project's root | +| ~SPC p %~ | replace a regexp | +| ~SPC p a~ | toggle between implementation and test | +| ~SPC p b~ | switch to project buffer | +| ~SPC p c~ | compile project using =projectile= | +| ~SPC p d~ | find directory | +| ~SPC p D~ | open project root in =dired= | +| ~SPC p f~ | find file | +| ~SPC p F~ | find file based on path around point | +| ~SPC p g~ | find tags | +| ~SPC p C-g~ | regenerate the project's =etags= / =gtags= | +| ~SPC p h~ | find file using =helm= | +| ~SPC p I~ | invalidate the projectile cache | +| ~SPC p k~ | kill all project buffers | +| ~SPC p o~ | run =multi-occur= | +| ~SPC p p~ | switch project | +| ~SPC p r~ | open a recent file | +| ~SPC p R~ | replace a string | +| ~SPC p t~ | open =NeoTree= in =projectile= root | +| ~SPC p T~ | test project | +| ~SPC p v~ | open project root in =vc-dir= or =magit= | +| ~SPC /~ | search in project with the best search tool available | +| ~SPC s p~ | see [[Searching in a project][search in project]] | +| ~SPC s a p~ | run =ag= | +| ~SPC s g p~ | run =grep= | +| ~SPC s k p~ | run =ack= | +| ~SPC s t p~ | run =pt= | + +*Note for Windows Users*: To enable fast indexing the GNU ~find~ or +Cygwin ~find~ must be in your ~PATH~. + +** Registers +Access commands to the various registers start with =r=: + +| Key Binding | Description | +|-------------+------------------------------------| +| ~SPC r e~ | show evil yank and named registers | +| ~SPC r m~ | show marks register | +| ~SPC r r~ | show helm register | +| ~SPC r y~ | show kill ring | + +** Errors handling +Spacemacs uses [[https://github.com/flycheck/flycheck][Flycheck]] to gives error feedback on the fly. The checks are +only performed at save time by default. + +Errors management commands (start with ~e~): + +| Key Binding | Description | +|-------------+-----------------------------------------------------------------------| +| ~SPC t s~ | toggle flycheck | +| ~SPC e c~ | clear all errors | +| ~SPC e h~ | describe a flycheck checker | +| ~SPC e l~ | toggle the display of the =flycheck= list of errors/warnings | +| ~SPC e n~ | go to the next error | +| ~SPC e p~ | go to the previous error | +| ~SPC e v~ | verify flycheck setup (useful to debug 3rd party tools configuration) | +| ~SPC e .~ | error transient state | + +The next/previous error bindings and the error transient state can be used to +browse errors from flycheck as well as errors from compilation buffers, and +indeed anything that supports Emacs’ =next-error= API. This includes for example +search results that have been saved to a separate buffer. + +Custom fringe bitmaps: + +| Symbol | Description | +|--------------------------+-------------| +| [[file:img/dot-error.png]] | Error | +| [[file:img/dot-warning.png]] | warning | +| [[file:img/dot-info.png]] | Info | + +** Compiling +Spacemacs binds a few commands to support compiling a project. + + | Key Binding | Description | + |-------------+--------------------------------| + | ~SPC c c~ | use =helm-make= via projectile | + | ~SPC c C~ | compile | + | ~SPC c d~ | close compilation window | + | ~SPC c k~ | kill compilation | + | ~SPC c m~ | =helm-make= | + | ~SPC c r~ | recompile | + +** Modes +*** Major Mode leader key +Key bindings specific to the current =major mode= start with ~SPC m~. For +convenience a shortcut key called the major mode leader key is set by default on +~​,​~ which saves one precious keystroke. + +It is possible to change the major mode leader key by defining the variable +=dotspacemacs-major-mode-leader-key= in your =~/.spacemacs=. For example to +setup the key on tabulation: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-major-mode-leader-key "") +#+END_SRC + +*** Helm +Spacemacs add =hjkl= navigation to =helm= buffers: + + | Key Binding | Description | + |-------------+------------------------------| + | ~C-h~ | go to next source | + | ~C-H~ | describe key (replace ~C-h~) | + | ~C-j~ | go to previous candidate | + | ~C-k~ | go to next candidate | + | ~C-l~ | same as ~return~ | + +** Emacs Server +Spacemacs starts a server at launch. This server is killed whenever you close +your Emacs windows. + +*** Connecting to the Emacs server +You can open a file in Emacs from the terminal using =emacsclient=. Use +=emacsclient -c= to open the file in Emacs GUI. Use =emacsclient -t= to open the +file in Emacs within the terminal. + +If you want your Linux/OS X system to use Emacs by default for any prompt, you +need to set it in your shell configuration, e.g. =~/.bashrc= or =~/.zshrc=: + +#+BEGIN_SRC sh-mode +export EDITOR="emacsclient -c" +#+END_SRC + +Note that if you're on OS X, you may have to refer to the emacsclient that comes +with your GUI Emacs, e.g.: + +#+BEGIN_SRC sh-mode +export EDITOR="/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -c" +#+END_SRC + +Tip: Remember to use ~:wq~ or ~C-x #~ after you are done editing the file in +Emacs. + +See [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Emacs-Server.html][Emacs as a Server]] in the official Emacs manual for more details. + +** Keeping the server alive +It is possible to keep the server alive when you close Emacs by setting the +variable =dotspacemacs-persistent-server= to =t= in your =~./spacemacs=. + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-persistent-server t) +#+END_SRC + +When this variable is set to =t=, the only way to quit Emacs /and/ kill the +server is to use the following bindings: + +| Keybinding | Description | +|------------+--------------------------------------------------------------------------| +| ~SPC q q~ | Quit Emacs and kill the server, prompt for changed buffers to save | +| ~SPC q Q~ | Quit Emacs and kill the server, lose all unsaved changes. | +| ~SPC q r~ | Restart both Emacs and the server, prompting to save any changed buffers | +| ~SPC q s~ | Save the buffers, quit Emacs and kill the server | +| ~SPC q z~ | Kill the current frame | + +** Troubleshoot +*** Loading fails +If any errors happen during the loading the mode-line will turn red and the +errors should appear inline in the startup buffer. Spacemacs should still be +usable; if it is not then restart Emacs with =emacs --debug-init= and open a +[[https://github.com/syl20bnr/spacemacs/issues][Github issue]] with the backtrace. + +*** Upgrading/Downgrading Emacs version +To ensure that packages are correctly compiled for the new Emacs version you +installed, be sure to run the interactive command =spacemacs/recompile-elpa= +with ~SPC SPC spacemacs/recompile-elpa~. + +* Achievements +** Issues + +| Achievements | Account | +|---------------------------+--------------| +| [[https://github.com/syl20bnr/spacemacs/pull/100][100th issue (PR)]] | [[https://github.com/danielwuz][danielwuz]] | +| [[https://github.com/syl20bnr/spacemacs/issues/200][200th issue (question)]] | [[https://github.com/justrajdeep][justrajdeep]] | +| [[https://github.com/syl20bnr/spacemacs/pull/300][300th issue (PR)]] | [[https://github.com/danielwuz][danielwuz]] | +| [[https://github.com/syl20bnr/spacemacs/pull/400][400th issue (PR)]] | [[https://github.com/CestDiego][CestDiego]] | +| [[https://github.com/syl20bnr/spacemacs/pull/500][500th issue (PR)]] | [[https://github.com/bjarkevad][bjarkevad]] | +| [[https://github.com/syl20bnr/spacemacs/pull/600][600th issue (PR)]] | [[https://github.com/bjarkevad][bjarkevad]] | +| [[https://github.com/syl20bnr/spacemacs/pull/700][700th issue (enhancement)]] | [[https://github.com/jcpetkovich][jcpetkovich]] | +| [[https://github.com/syl20bnr/spacemacs/pull/800][800th issue (PR)]] | [[https://github.com/laat][ryansroberts]] | +| [[https://github.com/syl20bnr/spacemacs/pull/900][900th issue (PR)]] | [[https://github.com/jcpetkovich][jcpetkovich]] | +| [[https://github.com/syl20bnr/spacemacs/pull/1000][1000th issue (PR)]] | [[https://github.com/tuhdo][tuhdo]] | +| [[https://github.com/syl20bnr/spacemacs/pull/2000][2000th issue (PR)]] | [[https://github.com/IvanMalison][IvanMalison]] | +| [[https://github.com/syl20bnr/spacemacs/pull/3000][3000th issue (issue)]] | [[https://github.com/malchmih][malchmih]] | +| [[https://github.com/syl20bnr/spacemacs/pull/4000][4000th issue (issue)]] | [[https://github.com/icymist][icymist]] | +| [[https://github.com/syl20bnr/spacemacs/pull/5000][5000th issue (issue)]] | [[https://github.com/justbur][justbur]] | +| [[https://github.com/syl20bnr/spacemacs/pull/6000][6000th issue (issue)]] | [[https://github.com/d12frosted][d12frosted]] | +| [[https://github.com/syl20bnr/spacemacs/pull/7000][7000th issue (issue)]] | [[https://github.com/deb0ch][deb0ch]] | + +** Merged Pull Requests + +| Achievements | Account | +|---------------------+----------------| +| [[https://github.com/syl20bnr/spacemacs/pull/228][100th pull request]] | [[https://github.com/bru][bru]] | +| [[https://github.com/syl20bnr/spacemacs/pull/418][200th pull request]] | [[https://github.com/smt][smt]] | +| [[https://github.com/syl20bnr/spacemacs/pull/617][300th pull request]] | [[https://github.com/BrianHicks][BrianHicks]] | +| [[https://github.com/syl20bnr/spacemacs/pull/806][400th pull request]] | [[https://github.com/cpaulik][cpaulik]] | +| [[https://github.com/syl20bnr/spacemacs/pull/993][500th pull request]] | [[https://github.com/tuhdo][tuhdo]] | +| [[https://github.com/syl20bnr/spacemacs/pull/1205][600th pull request]] | [[https://github.com/trishume][trishume]] | +| [[https://github.com/syl20bnr/spacemacs/pull/1995][1000th pull request]] | [[https://github.com/justbur][justbur]] | +| [[https://github.com/syl20bnr/spacemacs/pull/4089][2000th pull request]] | [[https://github.com/channingwalton][channingwalton]] | +| [[https://github.com/syl20bnr/spacemacs/pull/6338][3000th pull request]] | [[https://github.com/darkfeline][darkfeline]] | + +** Stars, forks and watchers + +| Achievements | Account | +|----------------------+-----------------| +| 100th watcher | [[https://github.com/adouzzy][adouzzy]] | +| 100th fork | [[https://github.com/balajisivaraman][balajisivaraman]] | +| 200th fork | [[https://github.com/alcol80][alcol80]] | +| 300th fork | [[https://github.com/mlopes][mlopes]] | +| 2000th fork | [[https://github.com/Gameguykiler][Gameguykiler]] | +| 100th star | [[https://github.com/Jackneill][Jackneill]] | +| 200th star | [[https://github.com/jb55][jb55]] | +| 400th star | [[https://github.com/dbohdan][dbohdan]] | +| 600th star | [[https://github.com/laat][laat]] | +| 700th star | [[https://github.com/kendall][kendall]] | +| 800th star | [[https://github.com/urso][urso]] | +| 900th star | [[https://github.com/luisgerhorst][luisgerhorst]] | +| 1000th star! | [[https://github.com/rashly][rashly]] | +| 2000th star!! | [[https://github.com/stshine][stshine]] | +| 3000th star!!! | [[https://github.com/TheBB][TheBB]] | +| 4000th star!!!! | [[https://github.com/nixmaniack][nixmaniack]] | +| 5000th star!!!!! | [[https://github.com/StreakyCobra][StreakyCobra]] | +| 6000th star!!!!!! | [[https://github.com/NJBS][NJBS]] | +| 7000th star!!!!!!! | [[https://github.com/mukhali][mukhali]] | +| 8000th star!!!!!!!! | [[https://github.com/shsteven][shsteven]] | +| 9000th star!!!!!!!!! | [[https://github.com/deb0ch][deb0ch]] | + +** Gitter chat + +| Achievements | Account | +|---------------------------------+-------------| +| First joiner on the Gitter Chat | [[https://github.com/trishume][trishume]] | +| 1000th joiner | [[https://github.com/gabrielpoca][gabrielpoca]] | + +** First times + +| Achievements | Account | +|---------------------------------+--------------| +| [[https://github.com/syl20bnr/spacemacs/pull/19][First contribution]] | [[https://github.com/trishume][trishume]] | +| [[https://github.com/syl20bnr/spacemacs/commit/e802027d75d0c0aed55539b0da2dfa0df94dfd39][First contribution layer]] | [[https://github.com/trishume][trishume]] | +| [[http://oli.me.uk/2014/11/06/spacemacs-emacs-vim/][First blog article on Spacemacs]] | [[https://github.com/Wolfy87][Wolfy87]] | +| [[https://github.com/syl20bnr/spacemacs/commit/7b44a56263049482ed540ed6815a295633ffe9d1][First contributed banner]] | [[https://github.com/chrisbarrett][chrisbarrett]] | + +** Special Mentions + +| Reason | Account | +|---------------------------------------------------------------------+-----------------| +| Autumnal Cleanup 2015 ([[https://github.com/syl20bnr/spacemacs/wiki/Autumnal-Cleanup-2015][wiki]]) | [[https://github.com/StreakyCobra][StreakyCobra]] | +| Test and debug tools | [[https://github.com/justbur][justbur]] | +| Integration of Ivy | [[https://github.com/justbur][justbur]] | +| Transient States | [[https://github.com/justbur][justbur]] | +| Integration of Persp-mode | [[https://github.com/CestDiego][CestDiego]] | +| Cleanest PR ([[https://github.com/syl20bnr/spacemacs/pull/5545][PR #5545]]) | [[https://github.com/JAremko][JAremko]] | +| Documentation tools and GitHub support | [[https://github.com/JAremko][JAremko]] | +| Code navigation improvement (jump handlers, generalized next error) | [[https://github.com/TheBB][TheBB]] | +| Better support for GUI using an Emacs daemon (after-display macro) | [[https://github.com/travisbhartwell][travisbhartwell]] | + +** Special Titles + +| Achievements | Account | +|-------------------------------------------------+--------------| +| The Gunner (18 PRs in a row) | [[https://github.com/ralesi][ralesi]] | +| The Saint (unlocked the holy-mode) | [[https://github.com/trishume][trishume]] | +| The Artist ([[https://github.com/nashamri/spacemacs-logo][logo]] and [[https://github.com/nashamri/spacemacs-theme][theme]]) | [[https://github.com/nashamri][nashamri]] | +| The Meme Master (doge banner) | [[https://github.com/chrisbarrett][chrisbarrett]] | +| The Helm captain ([[http://tuhdo.github.io/helm-intro.html][helm guide]]) | [[https://github.com/tuhdo][tuhdo]] | +| The Master of the Keys ([[https://github.com/justbur/emacs-which-key][which-key]] and [[https://github.com/justbur/emacs-bind-map][bind-map]]) | [[https://github.com/justbur][justbur]] | +| The PR Patrol Officer | [[https://github.com/robbyoconnor][robbyoconnor]] | +| The Expert in Latin Language ([[https://github.com/syl20bnr/spacemacs/pull/4043][PR]]) | [[https://github.com/vijaykiran][vijaykiran]] | +| The Tiler ([[https://github.com/syl20bnr/spacemacs/pull/4068][eyebrowse integration]]) | [[https://github.com/bmag][bmag]] | +| The Geometer ([[https://github.com/TheBB/spaceline][spaceline]]) | [[https://github.com/TheBB][TheBB]] | +| The Librarian (doc-fmt tool and space-doc mode) | [[https://github.com/JAremko][JAremko]] | + +* Thank you +Thank you Richard for this great piece of software. + +Thank you to all the contributors and the whole Emacs community from core +developers to elisp hackers! diff --git a/doc/FAQ.org b/doc/FAQ.org new file mode 100644 index 0000000..1e3d57c --- /dev/null +++ b/doc/FAQ.org @@ -0,0 +1,582 @@ +#+TITLE: Frequently Asked Questions + +* FAQ :TOC_4_gh:noexport: + - [[#common][Common]] + - [[#which-version-of-spacemacs-am-i-running][Which version of Spacemacs am I running?]] + - [[#what-is-the-official-pronunciation-of-spacemacs][What is the official pronunciation of Spacemacs?]] + - [[#why-do-you-call-this-a-distribution-i-dont-see-any-spacemacs-executable][Why do you call this a "distribution", I don't see any "Spacemacs" executable?]] + - [[#why-are-packages-installed-with-package-install-automatically-deleted-by-spacemacs-when-it-boots][Why are packages installed with =package-install= automatically deleted by Spacemacs when it boots?]] + - [[#how-to-fix-package-download-errors-when-installing-spacemacs-][How to fix package download errors when installing Spacemacs ?]] + - [[#how-to-fix-symbols-value-as-variable-is-void-errors-on-startup][How to fix =Symbol's value as variable is void= errors on startup?]] + - [[#how-to-fix-wrong-type-argument-arrayp-nil-errors-on-startup][How to fix =(wrong-type-argument arrayp nil)= errors on startup?]] + - [[#the-spacemacs-banner-is-ugly-what-should-i-do][The Spacemacs banner is ugly, what should I do?]] + - [[#the-powerline-separators-are-ugly-how-can-i-fix-them][The powerline separators are ugly, how can I fix them?]] + - [[#the-powerline-separators-have-no-anti-aliasing-what-can-i-do][The powerline separators have no anti-aliasing, what can I do?]] + - [[#why-is-after-init-hook-not-executed][Why is after-init-hook not executed?]] + - [[#what-is-the-difference-between-spacemacs-base-and-spacemacs-distributions][What is the difference between =spacemacs-base= and =spacemacs= distributions?]] + - [[#should-i-place-my-settings-in-user-init-or-user-config][Should I place my settings in =user-init= or =user-config=?]] + - [[#why-do-some-of-my-org-related-settings-cause-problems][Why do some of my =org=-related settings cause problems?]] + - [[#why-is-spacemacs-hanging-on-startup][Why is Spacemacs hanging on startup?]] + - [[#why-does-helm-m-x-spc-spc-not-accept-the-prefix-argument][Why does =helm-M-x= (~SPC SPC~) not accept the prefix argument?]] + - [[#why-does-my-color-theme-not-render-correctly-in-terminal-mode][Why does my color theme not render correctly in terminal mode?]] + - [[#typing-quickly-fd-takes-me-out-of-insert-state-what-is-going-on][Typing quickly =fd= takes me out of =insert state=. What is going on?]] + - [[#why-do-i-get-files-starting-with-][Why do I get files starting with .#?]] + - [[#why-do-i-get-4m-characters-inside-ansi-term][Why do I get '4m' characters inside ansi-term?]] + - [[#why-are-my-font-settings-not-being-respected][Why are my font settings not being respected?]] + - [[#why-am-i-getting-a-message-about-environment-variables-on-startup][Why am I getting a message about environment variables on startup?]] + - [[#how-do-i][How do I:]] + - [[#install-a-package-not-provided-by-a-layer][Install a package not provided by a layer?]] + - [[#disable-a-package-completely][Disable a package completely?]] + - [[#disable-a-package-only-for-a-specific-major-mode][Disable a package only for a specific major-mode?]] + - [[#disable-company-for-a-specific-major-mode][Disable company for a specific major-mode?]] + - [[#change-special-buffer-rules][Change special buffer rules?]] + - [[#enable-navigation-by-visual-lines][Enable navigation by visual lines?]] + - [[#disable-evilification-of-a-mode][Disable evilification of a mode?]] + - [[#include-underscores-in-word-motions][Include underscores in word motions?]] + - [[#setup-path][Setup =$PATH=?]] + - [[#change-or-define-an-alias-for-a-leader-key][Change or define an alias for a leader key?]] + - [[#restore-the-sentence-delimiter-to-two-spaces][Restore the sentence delimiter to two spaces?]] + - [[#prevent-the-visual-selection-overriding-my-system-clipboard][Prevent the visual selection overriding my system clipboard?]] + - [[#make-spell-checking-support-curly-quotes-or-any-other-character][Make spell-checking support curly quotes (or any other character)?]] + - [[#use-spacemacs-as-the-editor-for-git-commits][Use Spacemacs as the =$EDITOR= for git commits?]] + - [[#try-spacemacs-without-modifying-my-existing-emacs-configuration][Try Spacemacs without modifying my existing Emacs configuration?]] + - [[#make-copypaste-working-with-the-mouse-in-x11-terminals][Make copy/paste working with the mouse in X11 terminals?]] + - [[#use-helm-ag-to-search-only-in-files-of-a-certain-type][Use =helm-ag= to search only in files of a certain type?]] + - [[#modify-spacemacs-documentation-look-space-doc-mode][Modify spacemacs documentation look (space-doc-mode)]] + - [[#remap-paste-key-to-be-able-to-paste-copied-text-multiple-times][Remap paste key to be able to paste copied text multiple times]] + - [[#windows][Windows]] + - [[#why-do-the-fonts-look-crappy-on-windows][Why do the fonts look crappy on Windows?]] + - [[#why-is-there-no-spacemacs-logo-in-the-startup-buffer][Why is there no Spacemacs logo in the startup buffer?]] + - [[#why-are-all-packages-unavailable][Why are all packages unavailable?]] + - [[#the-powerline-isnt-shown-correctly-when-spacemacs-is-used-within-putty][The powerline isn't shown correctly when Spacemacs is used within =PuTTY=]] + +* Common +** Which version of Spacemacs am I running? +The version is displayed on the upper right corner of the loading screen. You +may also just type ~SPC f e v~. + +** What is the official pronunciation of Spacemacs? +As it is written, that is _space_ then _macs_. + +** Why do you call this a "distribution", I don't see any "Spacemacs" executable? +Although we could do it we don't package Emacs with Spacemacs. We allow users to +choose whatever build of Emacs they want that works with their OS, this is more +flexible and it saves use tons of issues. Spacemacs is more than a configuration +of Emacs it comes with advanced feature, concepts and tooling. Roughly, think of +it as a Linux distribution where we would ask people to install the kernel first +and then fetch somehow the actual code to get the distribution. +Note that some Linux distributions may start to create packages for Spacemacs, +they are unofficial packages, we will never package Emacs with Spacemacs. + +** Why are packages installed with =package-install= automatically deleted by Spacemacs when it boots? +By default Spacemacs will keep only the packages that you use (i.e. the packages +belonging to a layer explicitly listed in the variable +=dotspacemacs-configuration-layers=). + +To install packages that does not belong to any Spacemacs layers, you can: + +- use the variable =dotspacemacs-additional-packages=. +- or create a configuration layer configuring the package and add this layer to + =dotspacemacs-configuration-layers= +- or set the variable =dotspacemacs-install-packages= to =used-but-keep-unused= + which will prevent Spacemacs from removing the packages you installed + manually. + +To create a new configuration layer see the [[file:QUICK_START.org][quick start guide]] for more info. + +** How to fix package download errors when installing Spacemacs ? +Since 0.105.0 HTTPS protocol is used by default to download packages. If your +environment does not allow HTTPS to reach ELPA repositories then you can start +Emacs with the =--insecure= argument for force the usage of HTTP non secured +protocol. You can set the variable =dotspacemacs-elpa-https= to =nil= in your +dotfile to remove the need to start Emacs with =--insecure= argument. + +** How to fix =Symbol's value as variable is void= errors on startup? +If Emacs reports an error that the symbol =closed= or =-= is unbound as a +variable, it is probably because you are using HTTPS to download packages, but +you shouldn't be. Try deleting your packages (the =.emacs.d/elpa= folder), and +restart Emacs without HTTPS to download the packages again. There are two ways +to do this: + +- Run Emacs with the =--insecure= command line argument: =emacs --insecure=. You + will have to do this again the next time you update your packages. +- Set the variable =dotspacemacs-elpa-https= to =nil= in your dotfile. This has + the same effect as =--insecure=, but is persistent. + +** How to fix =(wrong-type-argument arrayp nil)= errors on startup? +This is most likely caused by a corrupted package archive. Try deleting your +=~/.emacs.d/elpa/archives/= folder and restart Emacs. + +** The Spacemacs banner is ugly, what should I do? +Install the default font supported by Spacemacs or choose a fixed width font. +More information in the font section of the [[file:DOCUMENTATION.org][documentation]]. + +** The powerline separators are ugly, how can I fix them? +Use the property =:powerline-scale= of the variable =dotspacemacs-default-font=. +See font section of the [[file:DOCUMENTATION.org][documentation]] for more details. + +** The powerline separators have no anti-aliasing, what can I do? +Emacs powerline uses XMP images to draw the separators in a graphical +environment. You can have anti-aliasing if you use the =utf8= separator. Note +that by default the =utf8= separator is used in a terminal. See the powerline +section in the font section of the [[file:DOCUMENTATION.org][documentation]]. + +** Why is after-init-hook not executed? +Don't launch Spacemacs with =emacs -q -l init.el= command. This command will run +the hooked functions in =after-init-hook= before the evaluation of the passed +=-l init.el= file. + +** What is the difference between =spacemacs-base= and =spacemacs= distributions? +The =distribution= concept was introduced in 0.104.x. You can now choose between +two distributions =spacemacs= or =spacemacs-base=. =spacemacs-base= contains +only a minimal set of packages; whereas =spacemacs= is the full Spacemacs +experience. + +Set the distribution with =dotspacemacs-distribution= variable. The default is +=spacemacs=. For more information as to what is included, check out the +=packages.el= file in the respective folders in the =+distributions= folder of +the =layers/= directory. + +** Should I place my settings in =user-init= or =user-config=? +Any variable that layer configuration code will *read* and *act on* must be set +in =user-init=, and any variable that Spacemacs explicitly sets but you wish to +*override* must be set in =user-config=. + +Anything that isn't just setting a variable should 99% be in =user-config=. + +** Why do some of my =org=-related settings cause problems? +Since version 0.104, spacemacs uses the =org= version from the org ELPA +repository instead of the one shipped with emacs. Then, any =org= related code +should not be loaded before =dotspacemacs/user-config=, otherwise both versions +will be loaded and will conflict. + +Because of autoloading, calling to =org= functions will trigger the loading up +of the =org= shipped with emacs wich will induce conflicts. One way to avoid +conflict is to wrap your =org= config code in a =with-eval-after-load= block +like this: + +#+BEGIN_SRC emacs-lisp +(with-eval-after-load 'org + ;; here goes your Org config :) + ;; .... + ) +#+END_SRC + +** Why is Spacemacs hanging on startup? +This is probably related to Helm using Tramp which tries to figure out some +SSH/DNS settings at startup. The root cause is probably your ISP redirecting +non-existing addresses to their own servers. + +Try using these settings in the ~user-init~ function in your ~.spacemacs~ +configuration: + +#+BEGIN_SRC emacs-lisp +(setq tramp-ssh-controlmaster-options + "-o ControlMaster=auto -o ControlPath='tramp.%%C' -o ControlPersist=no") +#+END_SRC + +See [[https://github.com/syl20bnr/spacemacs/issues/3422#issuecomment-148919047][issue #3422]] and [[https://github.com/emacs-helm/helm/issues/1000#issuecomment-119487649][helm issue #1000]] for details. If for any reason this code is +not working, you can try to put these settings directly in =~/.ssh/config=: + +#+BEGIN_SRC ssh +Host * +ControlMaster auto +ControlPath ~/.ssh/master -%r@%h:%p +ControlPersist = no +#+END_SRC + +** Why does =helm-M-x= (~SPC SPC~) not accept the prefix argument? +If you try to run =helm-M-x= with the prefix argument (i.e. ~SPC u SPC SPC~) it +will fail with this message: + +#+BEGIN_VERSE +Error: Specifying a prefix arg before calling helm-M-x +#+END_VERSE + +Instead, call =helm-M-x= first, select the command you want to run, and press +~C-u~ before pressing ~RETURN~. For instance: ~SPC SPC org-reload C-u RET~ + +** Why does my color theme not render correctly in terminal mode? +In the terminal version of Emacs, color themes will not render correctly as +colors are rendered by the terminal and not by emacs. You will probably have to +change your terminal color palette. More explanations can be found on +[[https://github.com/sellout/emacs-color-theme-solarized#important-note-for-terminal-users][emacs-color-theme-solarized webpage]]. + +** Typing quickly =fd= takes me out of =insert state=. What is going on? +This is a feature of Spacemacs, enabling you to easily escape from a lot of +situations, like escaping from =insert state= to =normal state=. + +The sequence of characters used can be customized. See the [[http://spacemacs.org/doc/DOCUMENTATION.html#orgheadline78][documentation]] for +more information. + +If you don't like this feature, you can deactivate it by adding =evil-escape= to +=dotspacemacs-excluded-packages= in your init file. + +** Why do I get files starting with .#? +These are lockfiles, created by Emacs to prevent editing conflicts which occur +when the same file is edited simultaneously by two different programs. To +disable this behaviour: + +#+BEGIN_SRC emacs-lisp +(setq create-lockfiles nil) +#+END_SRC + +** Why do I get '4m' characters inside ansi-term? +Ansi-term only has a subset of capabilities supported by xterm256. Your shell +(e.g. fish shell) might ignore =$TERMINFO= information and require you to set +the =~/.terminfo= yourself. + +#+BEGIN_SRC fish +tic -o ~/.terminfo $TERMINFO/e/eterm-color.ti +#+END_SRC + +Note that =eterm-color.ti= may be at a different location, to find out the exact +location you may try to use =locate=: + +#+BEGIN_SRC fish +locate eterm-color.ti +#+END_SRC + +** Why are my font settings not being respected? +The settings of =dotspacemacs-default-font= (such as size, weight, etc.) will +only be applied if the name of the font exists on your system. Check to make +sure that this is the case. If Spacemacs can't find the font, there should be a +warning to this effect in the =*Messages*= buffer. + +** Why am I getting a message about environment variables on startup? +Spacemacs uses the =exec-path-from-shell= package to set the executable path +when Emacs starts up. This is done by launching a shell and reading the values +of variables such as =PATH= and =MANPATH= from it. If your shell configuration +sets the values of these variables inconsistently, this could be problematic. It +is recommended to set such variables in shell configuration files that are +sourced unconditionally, such as =.profile=, =.bash_profile= or =.zshenv=, as +opposed to files that are sourced only for interactive shells, such as =.bashrc= +or =.zshrc=. If you are willing to neglect this advice, you may disable the +warning, e.g. from =dotspacemacs/user-init=: + +#+BEGIN_SRC emacs-lisp + (setq exec-path-from-shell-check-startup-files nil) +#+END_SRC + +You can also disable this feature entirely by adding =exec-path-from-shell= to +the list =dotspacemacs-excluded-packages= if you prefer setting =exec-path= +yourself. + +* How do I: +** Install a package not provided by a layer? +Spacemacs provides a variable in the =dotspacemacs/layers= function in +=.spacemacs= called =dotspacemacs-additional-packages=. Just add a package name +to the list and it will be installed when you reload your configuration with +~SPC f e R~, or at the next Spacemacs launch. + +** Disable a package completely? +To completely disable a package and effectively uninstalling it even if it is +part of your used layers, look for the variable =dotspacemacs-excluded-packages= +in your dotfile and add the package name to it: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-excluded-packages '(package1 package2 ...)) +#+END_SRC + +** Disable a package only for a specific major-mode? +This is done by removing the hook added by Spacemacs. For example to remove +=flycheck= support in python buffers, look for the function +=dotspacemacs/user-config= in your dotfile and add the following code: + +#+BEGIN_SRC emacs-lisp +(remove-hook 'python-mode-hook 'flycheck-mode) +#+END_SRC + +*Hint* to know the name of the major-mode of the current buffer press: ~SPC h d +v major-mode RET~ + +** Disable company for a specific major-mode? +It may be handy to disable =company= for a given mode if you plan on configuring +=auto-complete= instead. One easy way to do it is to use the macro +=spacemacs|disable-company= in the function =dotspacemacs/user-config= of your +dotfile. The following snippet disables company for =python-mode=: + +#+BEGIN_SRC emacs-lisp +(spacemacs|disable-company python-mode) +#+END_SRC + +** Change special buffer rules? +To change the way spacemacs marks buffers as useless, you can customize +=spacemacs-useless-buffers-regexp= which marks buffers matching the regexp as +useless. The variable =spacemacs-useful-buffers-regexp= marks buffers matching +the regexp as useful buffers. Both can be customized the same way. + +Examples: +#+BEGIN_SRC emacs-lisp +;; Only mark helm buffers as useless +(setq spacemacs-useless-buffers-regexp '("\\*helm\.\+\\*")) + +;; Marking the *Messages* buffer as useful +(push "\\*Messages\\*" spacemacs-useful-buffers-regexp) +#+END_SRC + +** Enable navigation by visual lines? +Add the following snippet to your =dotspacemacs/user-config= function: + +#+BEGIN_SRC emacs-lisp +;; Make evil-mode up/down operate in screen lines instead of logical lines +(define-key evil-motion-state-map "j" 'evil-next-visual-line) +(define-key evil-motion-state-map "k" 'evil-previous-visual-line) +;; Also in visual mode +(define-key evil-visual-state-map "j" 'evil-next-visual-line) +(define-key evil-visual-state-map "k" 'evil-previous-visual-line) +#+END_SRC + +** Disable evilification of a mode? +You can ensure a mode opens in emacs state by using =evil-set-initial-state=. + +#+BEGIN_SRC emacs-lisp +(evil-set-initial-state 'magit-status-mode 'emacs) +#+END_SRC + +You can also do this using buffer name regular expressions. E.g. for magit, +which has a number of different major modes, you can catch them all with + +#+BEGIN_SRC emacs-lisp +(push '("*magit" . emacs) evil-buffer-regexps) +#+END_SRC + +This should make all original magit bindings work in the major modes in +question. To enable the leader key in this case, you may have to define a +binding in the mode's map, e.g. for =magit-status-mode=, + +#+BEGIN_SRC emacs-lisp +(with-eval-after-load 'magit + (define-key magit-status-mode-map + (kbd dotspacemacs-leader-key) spacemacs-default-map)) +#+END_SRC + +** Include underscores in word motions? +You can modify the syntax table of the mode in question. To do so you can +include this on your =dotspacemacs/user-config=. + +#+BEGIN_SRC emacs-lisp +;; For python +(add-hook 'python-mode-hook #'(lambda () (modify-syntax-entry ?_ "w"))) +;; For ruby +(add-hook 'ruby-mode-hook #'(lambda () (modify-syntax-entry ?_ "w"))) +;; For Javascript +(add-hook 'js2-mode-hook #'(lambda () (modify-syntax-entry ?_ "w"))) +#+END_SRC + +** Setup =$PATH=? +Some layers require certain tools to be available on your =$PATH=. This means +that your =$PATH= must contain the installation paths for those tools. For +example, if you have installed some tools to =~/.local/bin= and want them to be +available in Spacemacs, you need to add =~/.local/bin= to your =$PATH=. + +Users of =bash=, =zsh=, =sh= and other similar shells should add following line +to their =.bashrc= (=.zshrc=, =.profile= or your shell's equivalent). Note that +the =export= part is very important. + +#+BEGIN_SRC sh +export PATH=~/.local/bin:$PATH +#+END_SRC + +Users of =fish= should add following line to their =config.fish= file (should be +in =$XDG_CONFIG_HOME= or its default value - =~/.config/fish=). Note that =-x= +part is very important. + +#+BEGIN_SRC fish +set -x PATH ~/.local/bin $PATH +#+END_SRC + +Users of other shells should consult its documentation on how to setup =$PATH= +variable (with export to environment). + +So now, =~/.local/bin= should be available in your =$PATH=. You can verify this +by calling =echo $PATH=. But you also should verify that =$PATH= is set properly +in your environment. To do so call following command in your terminal. + +#+BEGIN_SRC sh +env | grep "PATH" +#+END_SRC + +This is the value that will be used by Emacs. So it must contain =~/.local/bin=. + +After that you can run Spacemacs and check that it properly gets the value of +=$PATH= by running =M-: (getenv "PATH")=. + +Note that having =~/.local/bin= in your =$PATH= also means that it's possible to +run terminal and call tools from =~/.local/bin= without specifying their full +path. Under certain conditions you might want to avoid modifying your =$PATH=. +In that case you have the option of updating the value of =exec-path= in the +=dotspacemacs/user-config= function of your =.spacemacs= file. + +#+BEGIN_SRC emacs-lisp +(add-to-list 'exec-path "~/.local/bin/") +#+END_SRC + +** Change or define an alias for a leader key? +It is possible to change a leader key by binding its keymap to another sequence. +For instance, if you want to switch ~SPC S~ (spelling) with ~SPC d~ (used by +dash) to make the former easier to reach, you can use: + +#+BEGIN_SRC emacs-lisp +(defun dear-leader/swap-keys (key1 key2) + (let ((map1 (lookup-key spacemacs-default-map key1)) + (map2 (lookup-key spacemacs-default-map key2))) + (spacemacs/set-leader-keys key1 map2 key2 map1))) +(dear-leader/swap-keys "S" "d") +#+END_SRC + +If you want to define your own alias, like using ~SPC é~ (because it's a not +used key on your keyboard-layout for instance) for accessing ~SPC w~ (windows +management), you can use this: + +#+BEGIN_SRC emacs-lisp +(defun dear-leader/alias-of (key1 key2) + (let ((map (lookup-key spacemacs-default-map key2))) + (spacemacs/set-leader-keys key1 map))) +(dear-leader/alias-of "é" "w") +#+END_SRC + +** Restore the sentence delimiter to two spaces? +To restore the sentence delimiter to two spaces, add the following code to the +=dotspacemacs/user-init= function of your =.spacemacs=: + +#+BEGIN_SRC emacs-lisp +(setq sentence-end-double-space t) +#+END_SRC + +** Prevent the visual selection overriding my system clipboard? +On some operating systems, there is only one clipboard for both *copied* and +*selected* texts. This has the consequence that visual *selection* – which +should normally be saved to the /PRIMARY/ clipboard – overrides the /SYSTEM/ +clipboard, where normally goes the *copied* text. This can be corrected by +adding the following code to the =dotspacemacs/user-config= of your +=.spacemacs=: + +#+BEGIN_SRC emacs-lisp +(fset 'evil-visual-update-x-selection 'ignore) +#+END_SRC + +** Make spell-checking support curly quotes (or any other character)? +To have spell-checking support curly quotes (or any other character), you need +to add a new entry to =ispell-local-dictionary-alist=, by adding for example the +following code in the =dotspacemacs/user-config= of your =.spacemacs=: + +#+BEGIN_SRC emacs-lisp +(add-to-list 'ispell-local-dictionary-alist + (quote ("my_english" "[[:alpha:]]" "[^[:alpha:]]" "['’]" t ("-d" "en_US") nil utf-8))) +#+END_SRC + +You can then add any regular expression you want in the fourth argument (i.e. +add a symbol within =['’]=) to make it supported. Consult the help of +=ispell-dictionary-alist= for more details about the possibilities. + +You finally have to set =my_english= as your =ispell-local-dictionary= in order +to use the dictionary supporting your newly added characters. + +** Use Spacemacs as the =$EDITOR= for git commits? +Spacemacs can be used as the =$EDITOR= (or =$GIT_EDITOR=) for editing git +commits messages. To enable this you have to add the following line to your +=dotspacemacs/user-config=: + +#+BEGIN_SRC emacs-lisp +(global-git-commit-mode t) +#+END_SRC + +** Try Spacemacs without modifying my existing Emacs configuration? +Emacs' ability to use any directory as the home for launching it allows us to +try out Spacemacs (or any other Emacs configuration we desire) without having to +go through the trouble of backing up our =~/.emacs.d= directory and then cloning +the new configuration. This can be achieved easily using the following steps: + +#+BEGIN_SRC sh +mkdir ~/spacemacs +git clone git@github.com:syl20bnr/spacemacs.git ~/spacemacs/.emacs.d +HOME=~/spacemacs emacs +#+END_SRC + +If you're on Fish shell, you will need to modify the last command to: +=env HOME=$HOME/spacemacs emacs= + +** Make copy/paste working with the mouse in X11 terminals? +It is possible to disable the mouse support in X11 terminals in order to +enable copying/pasting with the mouse. You need to add this line to your +=dotspacemacs/user-config=: + +#+begin_src emacs-lisp +(xterm-mouse-mode -1) +#+end_src + +** Use =helm-ag= to search only in files of a certain type? +It is possible to restrict the scope of =helm-ag= to search only expressions in +some specified file types. There are two ways of doing this, both by appending +some expressions to the search input: + +- By using a regexp with =-G=, for instance =-G\.el$= will look for all files + ending with =.el= which are emacs-lisp files. + +- By using a flag like =--python= which should be self-explaining. The list of + available flags colud be accessed from terminal with: + + #+begin_src shell + ag --list-file-types + #+end_src + +This is possible because =helm-ag= is treating the search input as command-line +arguments of the =ag= program. + +** Modify spacemacs documentation look (space-doc-mode) +You can modify the list of visual enhancements applied by the =space-doc-mode=: +#+BEGIN_SRC emacs-lisp +(setq spacemacs-space-doc-modificators + '(center-buffer-mode + org-indent-mode + view-mode + hide-line-numbers + alternative-emphasis + alternative-tags-look + link-protocol + org-block-line-face-remap + org-kbd-face-remap + resize-inline-images)) +#+END_SRC +By default only =center-buffer-mode= is disabled. +Both =space-doc-mode= and =center-buffer-mode= can be customized +with "Easy Customization Interface". + +** Remap paste key to be able to paste copied text multiple times +In vim and evil, pasting over a text would cause it to be copied, hence making it impossible to paste +the same text multiple times. + +To fix this, add the following snippet to your ~user-config~: +#+BEGIN_SRC emacs-lisp +(defun evil-paste-after-from-0 () + (interactive) + (let ((evil-this-register ?0)) + (call-interactively 'evil-paste-after))) + +(define-key evil-visual-state-map "p" 'evil-paste-after-from-0) +#+END_SRC + +* Windows +** Why do the fonts look crappy on Windows? +You can install [[https://code.google.com/archive/p/gdipp/][GDIPP]] (simplest) or [[https://code.google.com/p/mactype/][MacType]] (more complete) on Windows to get +very nice looking fonts. It is also recommended to disable smooth scrolling on +Windows. + +** Why is there no Spacemacs logo in the startup buffer? +A GUI build of emacs supporting image display is required. You can follow the +instructions [[http://stackoverflow.com/questions/2650041/emacs-under-windows-and-png-files][here]]. Alternatively you can download binaries of emacs with image +support included such as [[http://emacsbinw64.sourceforge.net/][this one]]. + +** Why are all packages unavailable? +Check if your Emacs has HTTPS capabilities by doing =M-:= and then: + +#+BEGIN_SRC emacs-lisp + (gnutls-available-p) +#+END_SRC + +If this returns =nil=, you need to install the GnuTLS DLL file in the same +directory as Emacs. See [[https://www.gnu.org/software/emacs/manual/html_mono/emacs-gnutls.html#Help-For-Users][here]] for instructions. + +** The powerline isn't shown correctly when Spacemacs is used within =PuTTY= +You can follow [[http://mschulte.nl/posts/using-powerline-in-PuTTY.html][this explanation]] explaining how to correct this. diff --git a/doc/LAYERS.org b/doc/LAYERS.org new file mode 100644 index 0000000..9b58f27 --- /dev/null +++ b/doc/LAYERS.org @@ -0,0 +1,623 @@ +#+TITLE: Configuration layers + +* Configuration Layers :TOC_4_gh:noexport: + - [[#introduction][Introduction]] + - [[#nomenclature][Nomenclature]] + - [[#the-emacs-loading-process][The Emacs loading process]] + - [[#emacs-lisp-files][Emacs Lisp files]] + - [[#loading-a-file][Loading a file]] + - [[#features][Features]] + - [[#the-load-path][The load path]] + - [[#auto-loading][Auto-loading]] + - [[#eval-after-load][Eval after load]] + - [[#use-package][Use-package]] + - [[#anatomy-of-a-layer][Anatomy of a layer]] + - [[#layersel][layers.el]] + - [[#packagesel][packages.el]] + - [[#funcsel][funcs.el]] + - [[#configel][config.el]] + - [[#keybindingsel][keybindings.el]] + - [[#the-spacemacs-loading-process][The Spacemacs loading process]] + - [[#case-study-auto-completion][Case study: auto-completion]] + - [[#layer-tips-and-tricks][Layer tips and tricks]] + - [[#cross-dependencies][Cross-dependencies]] + - [[#use-package-1][Use-package]] + - [[#use-package-hooks][Use-package hooks]] + - [[#best-practices][Best practices]] + - [[#package-ownership][Package ownership]] + - [[#localize-your-configuration][Localize your configuration]] + - [[#load-ordering][Load ordering]] + - [[#no-require][No require]] + - [[#auto-load-everything][Auto-load everything]] + - [[#how-do-i--idiomatically][How do I ... idiomatically?]] + - [[#setup-auto-completion-for-a-major-mode][Setup auto-completion for a major mode]] + +* Introduction +This document is intended as a tutorial for users who are interested in writing +their first configuration layer, whether for private use or for contributing +upstream. It should help clear up some confusion regarding how layers work and +how Spacemacs (and Emacs) loads packages. + +* Nomenclature +Layers and packages. What gives? + +- Package :: A set of Emacs Lisp files that, taken together, provide some + feature. Packages may be available on a package repository, such as ELPA or + MELPA or on a third-party service provider (such as github) or even + locally on the disk. +- Layer :: A collected unit of configuration that can be enabled (or disabled) + in Spacemacs. A layer typically brings together one or more packages, as + well as the glue configuration code required to make them play well with + each other and Spacemacs in general. + +Before writing a layer, it is helpful to consider what you are trying to +achieve. Is there a package that provides the functionality you are after, and +you want to integrate it in Spacemacs? If yes, you should write a layer. Are you +trying to implement a new feature that would be useful for the Emacs community +at large? In that case, consider whether it wouldn't be more appropriate to +write a package first, and then a layer that uses your package. + +* The Emacs loading process +To understand how to best implement a layer, we have to investigate how Emacs +loads code. + +** Emacs Lisp files +Emacs Lisp files contains code that can be evaluated. When evaluated, the +functions, macros and modes defined in that file become available to the current +Emacs session. Henceforth, this will be termed as /loading/ a file. + +One major problem is to ensure that all the correct files are loaded, and in the +proper order. Another issue is to ensure that not too many files are loaded +immediately. This causes startup to take too long. Instead, we want to make sure +that files are loaded only as needed, and not all at once. + +How is this done in Emacs, and how is it done in Spacemacs? + +*** Loading a file +The simplest way to load a file is to call =load-file=. + +#+begin_src emacs-lisp +(load-file "~/elisp/foo.el") +#+end_src + +This is as primitive as it comes. The path must be exact, and it does not have +to be in the Emacs load path (we'll get to that later). It will not look for a +byte-compiled =.elc= file. It will simply load exactly what you tell it to. + +** Features +A better way to load what you need is to use /features/. A feature is a symbol +that typically has the same name as the file it resides in. Let us say you have +the following contents in a file called =my-feature.el=. + +#+begin_src emacs-lisp +;; Your code goes here ... + +(provide 'my-feature) +#+end_src + +To have Emacs load this file, call =require=, as such: + +#+begin_src emacs-lisp +(require 'my-feature) +#+end_src + +This checks whether the feature =my-feature= has already been loaded. If not, it +looks for a file called =my-feature.el=, =my-feature.elc= or some such. If it +finds such a file, it will load it. When the call to =provide= is evaluated, the +feature is added to the list of loaded features, so that subsequent calls to +=require= will do nothing. + +This will cause an error if no such file can be found. + +The file =my-feature.el= may very well contain other calls to =require=, and in +fact this is quite a common way to ensure that dependencies are loaded before +your code runs. + +Package authors should use this technique to make sure that dependencies are +loaded before their code runs. + +*** The load path +When loaded using =require=, Emacs looks for files in its /load path/. This is +nothing more than a list of paths where elisp files can be found, and you can +inspect it through ~SPC h d v load-path~ in Spacemacs. To add to the load path, +simply push to this list, e.g. + +#+begin_src emacs-lisp +(push "/some/path/" load-path) +#+end_src + +** Auto-loading +Calling =require= is nothing more than a glorified way of calling =load-file=. +It solves the problem of ensuring that files are loaded in the correct order, +and to some degree it solved the problem of where to find the files on disk but +a long list of calls to =require= at startup would still cause Emacs to take for +ever to load. + +Emacs uses auto-loading to solve this problem. When a function is registered as +auto-loading, an "empty" definition is provided. When that function is called, +the file that provides the function is immediately loaded (along with all its +required features). Finally, the "empty" function is substituted with the real +one and called normally. The end user will see only a slight delay when first +calling the function, while subsequent calls to that function (or any other +function loaded as part of the same procedure) will be as quick as normal. + +To register a function as auto-loadable, we call =autoload=: + +#+begin_src emacs-lisp +(autoload 'some-function "some-file") +#+end_src + +This instructs Emacs that whenever =some-function= is called, load +=some-file.el= first, and then proceed. + +After evaluating the above code, you can try to inspect =some-function= by doing +~SPC h d f some-function~. It will say it's an auto-loaded function, and that +nothing else is known about it until it is loaded. The call to =autoload= can +optionally include more information, such as a doc-string, whether the function +can be called interactively, and so on. This provides more information to the +end-user without her having to actually load the file first. + +Open your =elpa= directory, go to =helm= and look at the file +=helm-autoloads.el=. This provides all the auto-loads for all the files in Helm. +However, this file is not written by hand. Instead, it is automatically +generated from "magic" comments in the source code of Helm. They look like this: + +#+begin_src emacs-lisp +;;;###autoload +(defun my-function () + ;; Source code... + ) +#+end_src + +The magic comment =;;;###autoload= instructs Emacs that the following definition +should be auto-loaded. This automatically generates an appropriate call to +=autoload=. + +Things that can be auto-loaded generally involve anything "definable", such as +functions, macros, major or minor modes, groups, classes, and so on. + +Magic comments also work on other things, such as variable definitions +(=defvar=), but in that case, the definition is just copied verbatim into the +auto-loading file. For example, this code will load Helm on startup, long before +your file is actually evaluated, probably not what was intended: + +#+begin_src emacs-lisp +;;;###autoload +(require 'helm) +#+end_src + +It is the responsibility of the package authors to ensure that their package can +be appropriately auto-loaded, and most packages do this quite well. + +Spacemacs makes thorough use of auto-loading. Almost everything in Spacemacs is +loaded when needed instead of right away. + +** Eval after load +Often, we will want to configure packages after loading them. We may want to set +some variables or call some functions. This is trivial with =require=, because +it loads immediately, but it can be tricky with autoloading, because the +configuration code must also be deferred. + +Emacs offers =with-eval-after-load= for this purpose. It can be used like this: + +#+begin_src emacs-lisp +(with-eval-after-load 'helm + ;; Code + ) +#+end_src + +This arranges for the relevant code to be executed after Helm is loaded (using +either =require= or an autoload), or if Helm is already loaded, the code is +executed immediately. + +Since =with-eval-after-load= is a macro and not a function, its argument does +not have to be quoted. + +** Use-package +For /end users/ who are trying to put together an efficient Emacs configuration, +there is a very useful /package/ called =use-package= that provides a macro +which is /also/ called =use-package= which does a very good job of streamlining +the whole process of loading packages. + +The aspiring layer author is recommended to have a look at the =use-package= +[[https://github.com/jwiegley/use-package][documentation]]. Some examples follow. + +#+begin_src emacs-lisp +(use-package helm) +#+end_src + +This simply loads Helm. It is essentially equivalent to =(require 'helm)=. + +#+begin_src emacs-lisp +(use-package helm + :defer t) +#+end_src + +This defers the loading of Helm using the auto-load facility and the auto-load +commands provided by the Helm source code. It is, in fact, a no-op. + +#+begin_src emacs-lisp +(use-package helm + :defer t + :init + ;; Code to execute before Helm is loaded + :config + ;; Code to execute after Helm is loaded + ) +#+end_src + +This form includes code to execute before and after Helm is loaded. The =:init= +section can be executed immediately, but since Helm is deferred, the =:config= +section is not executed until after loading, if ever. It is essentially +equivalent to simply running the =:init= block, and then adding the =:config= +block in an =with-eval-after-load=. + +#+begin_src emacs-lisp +(use-package helm + :commands (helm-find-files helm-M-x)) +#+end_src + +This creates auto-load references for additional commands, if you find that the +package author has been slacking. + +#+begin_src emacs-lisp +(use-package ruby-mode + :mode "\\.rb\\'") +#+end_src + +For packages that provide major modes, you can associate file extensions to that +mode by using the =:mode= keyword. This adds an entry to =auto-mode-alist= and +an auto-load for =ruby-mode=. Typically this is not required, as =ruby-mode= +should already be auto-loadable, and the package should associate Ruby files +with itself already. + +Use-package supports heaps of useful keywords. Look at the [[https://github.com/jwiegley/use-package][documentation]] for +more. + +* Anatomy of a layer +A layer is simply a folder somewhere in Spacemacs' layer search path that +usually contains these files (listed in loading order). + +- =layers.el= :: declare additional layers +- =packages.el= :: the packages list and configuration +- =funcs.el= :: all functions used in the layer should be declared here +- =config.el= :: layer specific configuration +- =keybindings.el= :: general key bindings + +Additionally, for each local package (see the next section), there should be a +folder =/local//= containing the source code for that package. +Before initializing that package, Spacemacs will add this folder to the load +path for you. + +** layers.el +This file is the first file to be loaded and this is the place where addtional +layers can be declared. + +For instance is layer A depends on some functionality of layer B then in the +file =layers.el= of layer A we can add: + +#+begin_src emacs-lisp +(configuration-layer/declare-layer 'B) +#+end_src + +The effect is that B is considered a used layer and will be loaded as if it +was added to =dotspacemacs-configuration-layers= variables. + +** packages.el +It contains this list of packages of the layer and the actual configuration for +the packages included in the layer. + +This file is loaded after =layers.el=. + +It must define a variable called =-packages=, which should be a list of +all the packages that this layer needs. Some valid package specifications are +as follows: + +#+begin_src emacs-lisp +(defconst mylayer-packages + '( + ;; Get the package from MELPA, ELPA, etc. + some-package + (some-package :location elpa) + + ;; A local package + (some-package :location local) + + ;; A package recipe + (some-package :location (recipe + :fetcher github + :repo "some/repo")) + + ;; An excluded package + (some-package :excluded t) + )) +#+end_src + +The =:location= attribute specifies where the package may be found. Spacemacs +currently supports packages on ELPA compliant repositories, local packages and +MELPA recipes (through the Quelpa package). Local packages should reside at =/local//=. For information about recipes see the [[https://github.com/milkypostman/melpa#recipe-format][MELPA documentation]]. + +Packages may be /excluded/ by setting the =:excluded= property to true. This +will prevent the package from being installed even if it is used by another +layer. + +For each included package, you may define one or more of the following +functions, which are called in order by Spacemacs to initialize the package. + +1. =/pre-init-= +2. =/init-= +3. =/post-init-= + +It is the responsibility of these functions to load and configure the package in +question. Spacemacs will do nothing other than download the package and place it +in the load path for you. + +*Note:* A package will not be installed unless at least one layer defines an +=init= function for it. That is to say, in a certain sense, the =init= function +does mandatory setup while the =pre-init= and =post-init= functions do optional +setup. This can be used for managing cross-layer dependencies, which we will +discuss later. + +** funcs.el +It contains all the defined functions used in the layer. + +This file is loaded after =packages.el= and before =config.el=. + +It is good practice to guard the definition of functions to make sure a package +is actually used. For instance: + +#+begin_src emacs-lisp +(when (configuration-layer/package-usedp 'my-package) + (defun spacemacs/my-package-enable () ...) + (defun spacemacs/my-package-disable () ...)) +#+end_src + +By guarding these functions we avoid to define them in case the package +`my-package` is not used. + +** config.el +This file configure the layer like declaring layer variables default values +and setup some other variables related to the layer. + +This file is loaded after =funcs.el=. + +** keybindings.el +It contains general key bindings. + +This is the last file loaded. + +The word /general/ here means /independent of any package/. Since the end user +can exclude an arbitrary set of packages, you cannot be sure that, just because +your layer includes a package, that package will necessarily be loaded. For this +reason, code in these files must be generally safe, regardless of which packages +are installed. + +More on this in the next section. + +* The Spacemacs loading process +The Spacemacs loading process can be summarized as follows: + +1. Spacemacs goes through all the enabled layers and evaluates their files. The + changes introduced by =config.el= are thus applied, then =funcs.el= and + =packages.el= are loaded, but nothing happens from =packages.el=, since these + files only define functions and variables. +2. Spacemacs checks which packages should be downloaded and installed. To be + installed, a package must be + - included by a layer that the user has enabled, + - not be excluded by any other layer that the user has enabled, + - not be excluded by the user herself, and + - there must be at least one =/init-= function defined for + it. + Alternatively, if a package is part of the end user's + =dotspacemacs-additional-packages=, it will also be installed. +3. All packages which should be installed are installed in alphabetical order, + =package.el= built-in Emacs library is in charge of implicit dependencies. + Installed packages not following the rules of 2. are removed as well as + their dependencies if possible. (This last behavior is optional but default.) +4. The =pre-init=, =init= and =post-init= functions for each installed package + are executed in turn. + +It is step four that interests us. It is very important that a package is not +installed if no =init= function is defined for it. + +We say that a layer *owns* a package if it defines an =init= function for it. A +layer does *not* own a package if it only defines =pre-init= or =post-init= +functions. + +Only one layer may own a package. Since layers are processed in order of +specification in the user's dotfile, it is possible for layers to "seize" +ownership of a package that was owned by a previously enabled layer. + +* Case study: auto-completion +Spacemacs provides a layer called =auto-completion= which provides +auto-completion features in many modes. It does this using the package +=company=. This layer owns the =company= package, so it defines a function +called =auto-completion/init-company=. + +When a user enables the =auto-completion= layer, Spacemacs locates it and finds +=company= in the list of packages. Provided that =company= is not excluded, +either by the user or another layer, Spacemacs then locates and runs the =init= +function for =company=. This function includes a call to =use-package= that sets +up the basic configuration. + +However, auto-completion is a two-horse game. By its very nature, it is specific +to the major mode in question. It is pointless to expect the =auto-completion= +layer to include configuration for each conceivable major mode, and equally +futile to expect each programming language layer (python, ruby, etc.) to fully +configure =company= on their own. + +This is solved using the =post-init= functions. The Python layer, for example, +includes the =company= package and defines a function called +=python/post-init-company=. This function is called after +=auto-completion/init-company=, but it is not called if + +- the =auto-completion= layer is not enabled, in which case no =init= function + for =company= will be found, or +- the =company= package is excluded either by the user or another layer + +As such, =python/post-init-company= is the /only/ safe place to put +configuration related to =company= in Python mode. + +If the Python layer had defined an =init= function for =company=, that package +would have been installed even if the =auto-completion= layer had been disabled, +which is not what we want. + +* Layer tips and tricks + +** Cross-dependencies +Spacemacs provides a couple of additional useful functions you can use to check +whether other layers or packages are included. + +- =configuration-layer/layer-usedp= :: check if a layer is enabled +- =configuration-layer/package-usedp= :: check if a package is or will be installed + +These are useful in some cases, but usually you can get the desired result just +by using =post-init= functions. + +For layers that require another layers to be enabled, use the functions +=configuration-layer/declare-layer= and =configuration-layer/declare-layers= to +ensure that layers are enabled even if the user has not enabled them explicitly. +Calls to these functions must go in the =config.el= file. + +** Use-package +In the vast majority of cases, a package =init= function should do nothing but +call to =use-package=. Again, in the vast majority of cases, all the +configuration you need to do should be doable within the =:init= or =:config= +blocks of such a call. + +What goes where? Since =:init= is executed before load and =:config= after, +these rules of thumb apply. + +In =:config= should be +- Anything that requires the package to be already loaded. +- Anything that takes a long time to run, which would ruin startup performance. + +The =:init= block should contain setup for the entry points to the package. This +includes keybindings, if the package should be loaded manually by the user, or +hooks, if the package should be loaded upon some event. It is not unusual to +have both! + +** Use-package hooks +Spacemacs includes a macro for adding more code to the =:init= or =:config= +blocks of a call to =use-package=, after the fact. This is useful for =pre-init= +or =post-init= functions to "inject" code into the =use-package= call of the +=init= function. + +#+begin_src emacs-lisp +(spacemacs|use-package-add-hook helm + :pre-init + ;; Code + :post-init + ;; Code + :pre-config + ;; Code + :post-config + ;; Code + ) +#+end_src + +Since a call to =use-package= may evaluate the =:init= block immediately, any +function that wants to inject code into this block must run =before= the call to +=use-package=. Further, since this call to =use-package= typically takes place +in the =init-= function, calls to =spacemacs|use-package-add-hook= +typically happen in the =pre-init-= functions, and not in +=post-init-=. It is quite safe to do this in =pre-init=, so that should +be the default choice. + +** Best practices +If you break any of these rules, you should know what you are doing and have a +good reason for doing it. + +*** Package ownership +Each package should be owned by one layer only. The layer that owns the +package should define its =init= function. Other layers should rely on +=pre-init= or =post-init= functions. + +*** Localize your configuration +*Each function can only assume the existence of one package.* With some +exceptions, the =pre-init=, =init= and =post-init= functions can /only/ +configure exactly the package they are defined for. Since the user can exclude +an arbitrary set of packages, there is no /a priori/ safe way to assume that +another package is included. Use =configuration-layer/package-usedp= if you +must. + +This can be very challenging, so please take this as a guideline and not +something that is absolute. It is quite possible for the user to break her +Spacemacs installation by excluding the wrong packages, and it is not our +intention to prevent this at all costs. + +*** Load ordering +In Spacemacs, layers are loaded in order of inclusion in the dotfile, and +packages are loaded in alphabetical order. In the rare cases where you make use +of this property, you should make sure to document it well. Many will assume +that layers can be included in arbitrary order (which is true in most cases), +and that packages can be renamed without problems (which is also in most cases). + +Preferably, write your layer so that it is independent of load ordering. The +=pre=- and =post-init= functions are helpful, together with +=configuration-layer/package-usedp=. + +*** No require +Do not use require. If you find yourself using =require=, you are almost +certainly doing something wrong. Packages in Spacemacs should be loaded through +auto-loading, and not explicitly by you. Calls to =require= in package init +functions will cause a package to be loaded upon startup. Code in an =:init= +block of =use-package= should not cause anything to be loaded, either. If you +need a =require= in a =:config= block, that is a sign that some other package is +missing appropriate auto-loads. + +*** Auto-load everything +Defer everything. You should have a very good reason not to defer the loading +of a package. + +* How do I ... idiomatically? + +** Setup auto-completion for a major mode +In your layer's =config.el=, call =spacemacs|defvar-company-backends=. + +#+begin_src emacs-lisp +(spacemacs|defvar-company-backends yoyo-mode) +#+end_src + +This creates a variable called =company-backends-yoyo-mode=. In the package +=init= functions, you should push backends to this variable. But of course, only +if the =auto-completion= layer is enabled. + +#+begin_src emacs-lisp +(defconst yoyo-packages '( + ;; ... + some-weird-package + ;; ... + ) + + (when (configuration-layer/package-usedp 'company) + (defun yoyo/init-some-weird-package () + (use-package some-weird-package + :defer t + ;; This has to be in init because it's a package entry point + :init + (push 'some-weird-backend company-backends-yoyo-mode)))) +#+end_src + +Finally, we must make sure company is started when we enter =yoyo-mode=, but +again only if the =auto-completion= layer is enabled. + +#+begin_src emacs-lisp +(defconst yoyo-packages '( + ;; ... + yoyo-mode + ;; ... + )) + +(defun yoyo/init-yoyo-mode () + (use-package yoyo-mode + ;; Some configuration goes here, however nothing relating to company + ;; since this function may be called even if company is not installed! + )) + +(when (configuration-layer/package-usedp 'company) + (defun yoyo/post-init-yoyo-mode () + ;; This makes no reference to `some-weird-package', which may have + ;; been excluded by the user + (spacemacs|add-company-hook yoyo-mode))) +#+end_src diff --git a/doc/QUICK_START.org b/doc/QUICK_START.org new file mode 100644 index 0000000..dd35ba6 --- /dev/null +++ b/doc/QUICK_START.org @@ -0,0 +1,177 @@ +#+TITLE: Quick start + +* Configuration :TOC_4_gh:noexport: + - [[#configuration-layers][Configuration layers]] + - [[#dotfile-spacemacs][Dotfile (.spacemacs)]] + - [[#dotdirectory-spacemacsd][Dotdirectory (~/.spacemacs.d)]] + - [[#learning-spacemacs][Learning Spacemacs]] + - [[#editing-styles][Editing Styles]] + - [[#the-leader-keys][The leader keys]] + - [[#evil-tutor][Evil-tutor]] + - [[#universal-argument][Universal argument]] + - [[#configuration-layers-and-package-discovery][Configuration layers and Package discovery]] + - [[#key-bindings-discovery][Key bindings discovery]] + - [[#describe-functions][Describe functions]] + - [[#how-tos][How-To's]] + +* Configuration layers +Spacemacs divides its configuration into self-contained units called +=configuration layers=. These layers are stacked on top of each other +to achieve a custom configuration. + +By default Spacemacs uses a dotfile called =~/.spacemacs= to control which +layers to load. Within this file you can also configure certain features. + +A configuration layer is a directory containing at least a =packages.el= +file which defines and configures packages to be downloaded from Emacs +package repositories using the =package.el= built-in feature of Emacs. + +If you already have your own =Emacs= configuration you can move it to your +own layer. + +The following command creates a layer in the =private= directory: + +#+BEGIN_EXAMPLE + SPC SPC configuration-layer/create-layer RET +#+END_EXAMPLE + +Any configuration layers you create must be explicitly loaded in =~/.spacemacs=. + +Note: For your privacy, the contents of the =private= directory are not +under source control. See the section on private configuration management in +the [[file:DOCUMENTATION.org][documentation]]. + +* Dotfile (.spacemacs) +As mentioned =.spacemacs= controls which configuration layers to load and +is also a means to customizing Spacemacs. + +The following command will create a =.spacemacs= file in your home directory: + +#+BEGIN_EXAMPLE + SPC SPC dotspacemacs/install RET +#+END_EXAMPLE + +To open the installed dotfile: + +#+BEGIN_EXAMPLE + SPC f e d +#+END_EXAMPLE + +To load some configuration layers using the variable +=dotspacemacs-configuration-layers=: + +#+BEGIN_SRC elisp +;; List of configuration layers to load. +dotspacemacs-configuration-layers '(auto-completion smex) +#+END_SRC + +Some configuration layers support configuration variables to expose granular +control over layer-specific features, [[file:../layers/+source-control/git/README.org][git layer]] being one such example. +Variables can be directly set within =dotspacemacs-configuration-layers= like so: + +#+BEGIN_SRC elisp +;; List of configuration layers to load. +dotspacemacs-configuration-layers '(auto-completion + (git :variables + git-magit-status-fullscreen t) + smex) +#+END_SRC + +At anytime you can apply the changes made to the dotfile or layers +_without restarting_ Spacemacs by pressing ~SPC f e R~. + +The [[file:../core/templates/.spacemacs.template][dotfile template]] contain further information about how to customize +Spacemacs. See the dotfile configuration section of the [[file:DOCUMENTATION.org][documentation]] for +more details. + +* Dotdirectory (~/.spacemacs.d) +Like =Emacs=, Spacemacs initialization can also be contained in an =init.el= file +in a special directory =~/.spacemacs.d=. The contents of the dotfile should be +then copied in the =init.el= file. + +The Emacs dotfile or dotdirectory is not replaced but rather +complemented by the Spacemacs dotfile or dotdirectory. During startup, +Emacs still uses =~/.emacs.d/init.el= (or =~/.emacs=) for its +initialization, and variable =user-emacs-directory= will still point +to =~/.emacs.d/=, even if =~/.spacemacs.d= or =~/.spacemacs= are +present. Only now =~/.emacs.d/init.el= is provided by Spacemacs +(e.g. after cloning the Spacemacs git repo into an empty +=~/.emacs.d/=), and your own personnal configurations go into +=~/.spacemacs.d/init.el= (or =~/.spacemacs=). + +Have a look into the FAQ for an easy workaround to maintain (your +former) vanilla Emacs and (your new) Spacemacs configurations +side-by-side without the need to rename and backup =~/.emacs.d/=. + +* Learning Spacemacs +** Editing Styles +Spacemacs can be used by Vim users or Emacs users by setting the +=dotspacemacs-editing-style= variable to =vim=, =emacs= or even =hybrid= +in the dotfile =~/.spacemacs=. + +** The leader keys +Spacemacs key bindings use a leader key which is by default bound to +~SPC~ (space bar) in =vim= or =hybrid= editing styles and ~M-m~ in =emacs= +style. + +You can change it by setting the variable =dotspacemacs-leader-key= if +you use the =vim= style or =dotspacemacs-emacs-leader-key= if you use +the =emacs= style (these variables must be set in the file =~/.spacemacs=). + +For simplicity the documentation always refers to the leader key as +~SPC~. + +There is secondary leader key called the major-mode leader key which is +set to ~​,​~ by default. This key is a shortcut for ~SPC m~ +where all the major-mode specific commands are bound. + +** Evil-tutor +If you are willing to learn the Vim key bindings (highly recommended since +you can benefit from them even in =emacs= style), press ~SPC h T~ +to begin an Evil-adapted Vimtutor. + +** Universal argument +In =vim= editing style the universal argument defaults to ~SPC u~ +instead of ~C-u~ because the latter is used to scroll up as in Vim. + +** Configuration layers and Package discovery +By using =helm-spacemacs-help= with ~SPC h SPC~ you can quickly search +for a package and get the name of the layers using it. + +You can also easily go to the =README.org= of a layer or go to the initialization +function of a package. + +** Key bindings discovery +Thanks to [[https://github.com/justbur/emacs-which-key][which-key]], whenever a prefix command is pressed (like ~SPC~) +a buffer appears after one second listing the possible keys for this prefix. + +It is also possible to search for specific key bindings by pressing: + +#+BEGIN_EXAMPLE + SPC ? +#+END_EXAMPLE + +To narrow the bindings list to those prefixed with =SPC=, +type a pattern like this regular expression: + +#+BEGIN_EXAMPLE + SPC\ b +#+END_EXAMPLE + +which would list all =buffer= related bindings. *Note:* You are at the +/HELM-Descbind/ prompt, the pattern consists of 6 letters: uppercase ~SPC~, a +backslash, an actual space and a lowercase ~b~. + +** Describe functions +=Describe functions= are powerful Emacs introspection commands to get information +about functions, variables, modes etc. These commands are bound thusly: + +| Key Binding | Description | +|-------------+-------------------| +| ~SPC h d f~ | describe-function | +| ~SPC h d k~ | describe-key | +| ~SPC h d m~ | describe-mode | +| ~SPC h d v~ | describe-variable | + +* How-To's +Some quick =how-to's= are compiled in the [[file:FAQ.org::How%20do%20I...][FAQ.org]] file. diff --git a/doc/VIMUSERS.org b/doc/VIMUSERS.org new file mode 100644 index 0000000..39820ec --- /dev/null +++ b/doc/VIMUSERS.org @@ -0,0 +1,484 @@ +#+TITLE: Migrating from Vim + +* Migrating from vim :TOC_4_gh:noexport: + - [[#purpose-of-this-document][Purpose of this document]] + - [[#philosophy][Philosophy]] + - [[#basic-orientation][Basic orientation]] + - [[#terms][Terms]] + - [[#modes-vs-states][Modes vs. States]] + - [[#layers][Layers]] + - [[#transient-states][Transient-states]] + - [[#keybinding-conventions][Keybinding conventions]] + - [[#running-commands][Running commands]] + - [[#buffer-and-window-management][Buffer and window management]] + - [[#buffers][Buffers]] + - [[#special-buffers][Special buffers]] + - [[#windows][Windows]] + - [[#files][Files]] + - [[#the-help-system][The Help System]] + - [[#exploring][Exploring]] + - [[#customization][Customization]] + - [[#the-spacemacs-file][The .spacemacs file]] + - [[#emacs-lisp][Emacs Lisp]] + - [[#variables][Variables]] + - [[#keybindings][Keybindings]] + - [[#functions][Functions]] + - [[#activating-a-layer][Activating a Layer]] + - [[#creating-a-layer][Creating a Layer]] + - [[#installing-a-single-package][Installing a single package]] + - [[#loading-packages][Loading packages]] + - [[#uninstalling-a-package][Uninstalling a package]] + - [[#common-tweaks][Common tweaks]] + - [[#changing-the-escape-key][Changing the escape key]] + - [[#changing-the-colorscheme][Changing the colorscheme]] + - [[#nohlsearch][Nohlsearch]] + - [[#sessions][Sessions]] + - [[#navigating-using-visual-lines][Navigating using visual lines]] + - [[#other-useful-links][Other useful links]] + +* Purpose of this document +This document is intended to supplement the Spacemacs documentation by bridging +the gap between vim and Spacemacs. While some information may be duplicated, +this does not replace the Spacemacs documentation. It is recommended that you +read both files to fully understand Spacemacs. + +[[file:DOCUMENTATION.org][Spacemacs Documentation]] + +* Philosophy + One misconception many vim users have is that Spacemacs is an Emacs /clone/ of + vim. Spacemacs does not seek to completely mimic the behavior of vim + everywhere, only when editing. You should not expect every vim command to be + available, although many are. You cannot use Vimscript to configure Spacemacs, + but who likes Vimscript anyway? It is important to understand that Spacemacs is + an attempt to improve on both vim and Emacs using the superior modal editing of + vim and the nicer configuration language of Emacs. + +* Basic orientation +** Terms +Spacemacs uses some different terminology than vim, which can cause confusion +for new users. This section attempts to clear up any confusion. + +*** Modes vs. States +In vim you have various editing modes like =insert mode= and =visual mode= to +manipulate text. In Emacs, we have [[./DOCUMENTATION.org#states][states]]. These are equivalent to vim modes. +For example, =evil-insert-state= is the same as =insert-mode= in vim. + +A =minor-mode= in Emacs is like a feature that is activated. For example, +=aggressive-indent-mode= is a =minor-mode= that automatically indents code as you +type. It is important to know that there can be many =minor-modes= activated in a +buffer. Many Emacs packages work by providing a =minor-mode=. A =major-mode= +determines the editing behavior of Emacs in the current buffer. There is +generally a corresponding =major-mode= per filetype. An example of a =major-mode= is +=python-mode=, which provides python specific settings in python files. There is +only one =major-mode= per buffer. + +*** Layers +Spacemacs has the concept of layers. Layers are similar to vim plugins. They +provide new features to use in Spacemacs. However, layers are often comprised of +several packages that integrate well with each other. For example, the =python= +layer includes support for auto-completion, documentation look-up, tests, and +much more by using several different packages. This keeps you from thinking +about what packages to install, and instead worry about what features you want. +More information on layers can be found in the [[./VIMUSERS.org#customization][customization]] section and in the +[[./DOCUMENTATION.org#configuration-layers][documentation]]. There is also a more in-depth guide on writing layers [[file:LAYERS.org][here]]. + +*** Transient-states +Spacemacs provides a special functionality called transient-states. Transient-states +allow similar commands to be run in succession without repeatedly pressing the +~~ key. Transient-states are usually triggered by using a keybinding with the +following pattern: ~ .~ where group is the category the +transient-state falls under. When in a transient-state you will see documentation at the +bottom of your window. To exit a transient-state press ~q~. + +#+CAPTION: Transient-state documentation window + +[[file:img/spacemacs-scale-transient-state.png]] + +** Keybinding conventions +Spacemacs uses ~SPC~ as its ~~ key. This document will use ~SPC~ to refer to +the ~~ key. All keybindings are mnemonic and are organized under the +~~ key. For example, the keybindings for language-specific commands are +always under the ~SPC m~ prefix. A full list of conventions used in Spacemacs is +[[./CONVENTIONS.org][here]]. Note that all keybindings can be changed. + +Spacemacs uses [[https://github.com/justbur/emacs-which-key][which-key]] to show available keybindings after a delay: + +#+CAPTION: Which-key window + +[[file:img/which-key.png]] + +** Running commands +Emacs commands can be run using ~SPC SPC~. This will pop up a buffer using [[https://github.com/emacs-helm/helm][Helm]] +which can be used to run any Emacs command. You can also run many ex commands +using ~:~, just like in vim. + +Note: You can run Emacs interactive commands using ~:~, but you cannot run ex +commands using ~SPC SPC~. + +** Buffer and window management +*** Buffers +Buffers in Emacs and vim are essentially the same. The keybindings for buffers +are located under the ~SPC b~ prefix. + +| Keybinding | Function | +|---------------------------+------------------------------------------------------| +| ~SPC b b ~ | Create a buffer named ==. | +| ~SPC b b~ | Search through open buffers and recent files. | +| ~SPC b n~ or ~:bnext~ | Switch to the next buffer. (See [[*Special%20buffers][Special buffers]]) | +| ~SPC b p~ or ~:bprevious~ | Switch to the previous buffer. (See [[*Special%20buffers][Special buffers]]) | +| ~SPC b d~ or ~:bdelete~ | Kill current buffer. | +| ~SPC b C-d~ | Kill buffers using a regular expression. | +| ~SPC b m~ | Kill all buffers except the current buffer. | +| ~SPC b .~ | Buffer transient-state. | + +**** Special buffers +By default Emacs creates a lot of buffers that most people will never need, like +=*Messages*=. Spacemacs automatically ignores these when using these +key bindings. More information can be found [[./DOCUMENTATION.org#special-buffers][here]]. + +*** Windows +Windows are like splits in vim. They are useful for editing multiple files at +once. All window keybindings are under the ~SPC w~ prefix. + +| Keybinding | Function | +|------------------------+--------------------------------------| +| ~SPC w v~ or ~:vsplit~ | Opens a vertical split on the right. | +| ~SPC w s~ or ~:split~ | Opens a horizontal split below. | +| ~SPC w h/j/k/l~ | Navigate among windows. | +| ~SPC w H/J/K/L~ | Move the current window. | +| ~SPC w .~ | Window transient-state. | + +** Files +All file commands in Spacemacs are available under the ~SPC f~ prefix. + +| Keybinding | Function | +|-------------------+--------------------------------------------------------------| +| ~SPC f f~ | Opens a buffer to search for files in the current directory. | +| ~SPC f r~ | Opens a buffer to search through recently opened files. | +| ~SPC f s~ or ~:w~ | Save the current file. | +| ~:x~ | Save the current file and quit. | +| ~:e ~ | Open == | + +** The Help System +Emacs has an extensive help system. All keybindings under the ~SPC h d~ prefix +allow convenient access to the help system. The most important of these +keybindings are ~SPC h d f~ , ~SPC h d k~ , and ~SPC h d v~. There is also the +~SPC ~ keybinding which allows you to search for documentation. + +| Keybinding | Function | +|-------------+----------------------------------------------------------------------------------| +| ~SPC h d f~ | Prompts for a function and shows its documentation. | +| ~SPC h d k~ | Prompts for a keybinding and shows what it is bound to. | +| ~SPC h d v~ | Prompts for a variable and shows its documentation and current value. | +| ~SPC ~ | Searches for a command, function, variable, or face and shows its documentation. | + +Whenever, you see weird behavior or want to know what something does, these +functions are the first thing you should refer to. + +** Exploring +There are a few ways to explore the functionality of Spacemacs. One is to read +the [[https://github.com/syl20bnr/spacemacs][source code]] on Github. You can begin to feel your way around Emacs Lisp and +how Spacemacs works this way. You can also use the following keybindings to +explore: + +| Keybinding | Function | +|-------------+---------------------------------------------------------------| +| ~SPC h SPC~ | Lists all layers and allows you to view files from the layer. | +| ~SPC ?~ | Lists all keybindings. | + +* Customization +** The .spacemacs file +When you first start spacemacs, you will be prompted to choose an editing style. +If you are reading this, you likely want to choose the vim style. A =.spacemacs= +file will be created with the appropriate style selected. Most trivial +configuration will go in this file. + +There are four top-level functions in the file: =dotspacemacs/layers=, +=dotspacemacs/init=, =dotspacemacs/user-init= and =dotspacemacs/user-config=. +The =dotspacemacs/layers= function exist only to enable and disable layers and +packages. The =dotspacemacs/init= function is run before anything else during +startup and contains Spacemacs settings. You will never need to touch this +function except to change default Spacemacs settings. +The =dotspacemacs/user-init= function is also run before anything else and +contains user specific configuration. The =dotspacemacs/user-config= function +is the one you will use the most. This is where you define any user configuration. + +| Keybinding | Function | +|-------------+--------------------------------------------------------------------------| +| ~SPC f e d~ | Open your =.spacemacs= | +| ~SPC f e D~ | Update your =.spacemacs= manually using a diff with the default template | + +** Emacs Lisp +This section introduces a few emacs lisp functions that are needed to configure +Spacemacs. For a more detailed look at the language, see [[http://learnxinyminutes.com/docs/elisp/][this]] link. If you +really want to learn everything there is about emacs lisp, use the info page +found at ~SPC h i elisp RET~ . + +*** Variables +Setting variables is the most common way to customize the behavior of Spacemacs. +The syntax is simple: + +#+begin_src emacs-lisp + (setq variable value) ; Syntax + ;; Setting variables example + (setq variable1 t ; True + variable2 nil ; False + variable3 '("A" "list" "of" "things")) +#+end_src + +*** Keybindings +Defining keybindings is something that almost everyone will want to do. The +built-in =define-key= function is the best way to do that. + +#+begin_src emacs-lisp + (define-key map new-keybinding function) ; Syntax + ;; Map H to go to the previous buffer in normal mode + (define-key evil-normal-state-map (kbd "H") 'previous-buffer) + ;; Mapping keybinding to another keybinding + (define-key evil-normal-state-map (kbd "H") (kbd "^")) ; H goes to beginning of the line +#+end_src + +The map is the keymap you want to bind the key in. Most of the time you will use +=evil--state-map=. These correspond to different =evil-mode= states. +For example, using =evil-insert-state-map= maps the keybinding in insert mode. + +To map ~~ keybindings, use the =spacemacs/set-leader-keys= function. + +#+begin_src emacs-lisp + (spacemacs/set-leader-keys key function) ; Syntax + ;; Map killing a buffer to b c + (spacemacs/set-leader-keys "bc" 'spacemacs/kill-this-buffer) + ;; Map opening a link to o l only in org-mode (works for any major-mode) + (spacemacs/set-leader-keys-for-major-mode 'org-mode + "ol" 'org-open-at-point) +#+end_src + +*** Functions +You may occasionally want to define a function to do a more complex +customization. The syntax is simple: + +#+begin_src emacs-lisp + (defun func-name (arg1 arg2) + "docstring" + ;; Body + ) + + ;; Calling a function + (func-name arg1 arg1) +#+end_src + +Here is an example of a function that is useful in real life: + +#+begin_src emacs-lisp + ;; This snippet allows you to run clang-format before saving + ;; given the current file as the correct filetype. + ;; This relies on the c-c++ layer being enabled. + (defun clang-format-for-filetype () + "Run clang-format if the current file has a file extensions + in the filetypes list." + (let ((filetypes '("c" "cpp"))) + (when (member (file-name-extension (buffer-file-name)) filetypes) + (clang-format-buffer)))) + + ;; See http://www.gnu.org/software/emacs/manual/html_node/emacs/Hooks.html for + ;; what this line means + (add-hook 'before-save-hook 'clang-format-for-filetype) +#+end_src + +** Activating a Layer +As said in the terms section, layers provide an easy way to add features. +Activating a layer is done in the =.spacemacs= file. In the file search for the +=dotspacemacs-configuration-layers= variable. By default, it should look like +this: + +#+begin_src emacs-lisp + (defun dotspacemacs/layers () + (setq-default + ;; ... + dotspacemacs-configuration-layers '(;; auto-completion + ;; better-defaults + emacs-lisp + ;; (git :variables + ;; git-gutter-use-fringe t) + ;; markdown + ;; org + ;; syntax-checking + ))) +#+end_src + +You can uncomment these suggested layers by deleting the semi-colons for a nice +out-of-the-box experience. To add a layer, add its name to the list and restart +Emacs or press ~SPC f e R~ . To view all layers and their documentation use ~SPC +h SPC~. + +** Creating a Layer +To group configuration or when configuration doesn't fit well in your +=.spacemacs= file, you can create a configuration layer. Spacemacs provides a +builtin command to generate the layer boilerplate: ~SPC SPC +configuration-layer/create-layer~. This generates a folder that looks like this: + +#+BEGIN_EXAMPLE + [layer-name] + |__ [local]* + | |__ [example-mode-1] + | | ... + | |__ [example-mode-n] + |__ config.el* + |__ funcs.el* + |__ keybindings.el* + |__ packages.el + + [] = directory + * = not created by the command +#+END_EXAMPLE + +The =packages.el= file contains a list of packages that you can install in the +variable =-packages=. Any package that is available on the [[http:melpa.org][MELPA]] +repository can be added to the list. A list can also exclude packages using the +=:excluded t= property. +Each package requires a function to initialize it. The function /must/ be named +with this pattern: =/init-=. This function contains +configuration for the package. There are also =pre/post-init= functions to +execute code before or after a package loads. It would look like this: + +#+begin_src emacs-lisp + (setq layer-name-packages '(example-package + ;; This layer uninstalls example-package-2 + ;; by setting the :excluded property to true (t) + (example-package-2 :excluded t))) + + (defun layer-name/post-init-package () + ;; Add configuration to a package in another layer here + ) + + (defun layer-name/init-example-package () + ;; Configuration for example-package goes here + ) +#+end_src + +**Note**: Only one layer can have a =init= function for a package. If you want +to override the configuration of a package in another layer, use a +=/pre-init= function in addition to [[file:LAYERS.org#use-package-hooks][use-package hooks]]. + +If a package is not available on MELPA, you must use a local package or a +package recipe. For more details see [[file:LAYERS.org#anatomy-of-a-layer][anatomy of a layer]]. + +Make sure you [[Activating a Layer][add]] your layer to your =.spacemacs= file and restart to +activate it. + +A detailed description of the loading process and how layers work can be found in +[[file:LAYERS.org][LAYERS.org]]. + +** Installing a single package +Sometimes creating a layer is a bit overkill. Maybe you just want one package +and don't want to maintain a whole layer. Spacemacs provides a variable in the +=dotspacemacs/layers= function in =.spacemacs= called +=dotspacemacs-additional-packages=. Just add a package name to the list and it +will be installed when you restart. Loading the package is covered in the next +[[Loading packages][section]]. + +** Loading packages +Ever wonder how Spacemacs can load over a 100 packages in just a few seconds? +Such low loading times must require some kind of unreadable black magic that no +one can understand. Thanks to [[https://github.com/jwiegley/use-package][use-package]], this is not true. It is a package +that allows easy lazy-loading and configuration of packages. Here are the basics +to using it: + +#+begin_src emacs-lisp + ;; Basic form of use-package declaration. The :defer t tells use-package to + ;; try to lazy load the package. + (use-package package-name + :defer t) + ;; The :init section is run before the package loads The :config section is + ;; run after the package loads + (use-package package-name + :defer t + :init + (progn + ;; Change some variables + (setq variable1 t variable2 nil) + ;; Define a function + (defun foo () + (message "%s" "Hello, World!"))) + :config + (progn + ;; Calling a function that is defined when the package loads + (function-defined-when-package-loads))) +#+end_src + +This is just a very basic overview of =use-package=. There are many other ways +to control how a package loads using it that aren't covered here. + +** Uninstalling a package +Spacemacs provides a variable in the =dotspacemacs/init= function in +=.spacemacs= called =dotspacemacs-excluded-packages=. Just add a package name to +the list and it will be uninstalled when you restart. + +** Common tweaks +This section is for things many will want to change. All of these settings go in +the =dotspacemacs/user-config= function in your =.spacemacs= unless otherwise noted. + +*** Changing the escape key +Spacemacs uses [[https://github.com/syl20bnr/evil-escape][evil-escape]] to +allow escaping from many =major-modes= with one keybinding. You can customize +the variable in your =dotspacemacs/user-config= like this: + +#+begin_src emacs-lisp + (defun dotspacemacs/user-config () + ;; ... + ;; Set escape keybinding to "jk" + (setq-default evil-escape-key-sequence "jk")) +#+end_src + +More documentation is found in the =evil-escape= [[https://github.com/syl20bnr/evil-escape/blob/master/README.md][README]]. + +*** Changing the colorscheme +The =.spacemacs= file contains the =dotspacemacs-themes= variable in the +=dotspacemacs/init= function. This is a list of themes that can be cycled +through with the ~SPC T n~ keybinding. The first theme in the list is the one +that is loaded at startup. Here is an example: + +#+begin_src emacs-lisp + (defun dotspacemacs/init + ;; Darktooth theme is the default theme + ;; Each theme is automatically installed. + ;; Note that we drop the -theme from the package name. + ;; Ex. darktooth-theme -> darktooth + (setq-default dotspacemacs-themes '(darktooth + soothe + gotham))) +#+end_src + +All installed themes can be listed and chosen using the ~SPC T h~ keybinding. + +*** Nohlsearch +Spacemacs emulates the default vim behavior which highlights search results even +when you are not navigating between them. You can use ~SPC s c~ or ~:nohlsearch~ +to disable search result highlighting. + +To disable the result highlighting when it is not needed anymore automatically, +you can [[Uninstalling a package][uninstall]] the =evil-search-highlight-persist= package. + +*** Sessions +Spacemacs does not automatically restore your windows and buffers when you +reopen it. If you use vim sessions regularly you may want to set +=dotspacemacs-auto-resume-layouts= to =t= in your =.spacemacs=. + +*** Navigating using visual lines +Spacemacs uses the vim default of navigating by actual lines, even if they are +wrapped. If you want ~j~ and ~k~ to behave like ~g j~ and ~g k~, add this to +your =.spacemacs=: + +#+begin_src emacs-lisp + (define-key evil-normal-state-map (kbd "j") 'evil-next-visual-line) + (define-key evil-normal-state-map (kbd "k") 'evil-previous-visual-line) +#+end_src + +* Other useful links +- [[https://www.gnu.org/software/emacs/manual/emacs.html][Emacs Manual]] +- [[file:DOCUMENTATION.org][Spacemacs Documentation]] +- [[http://ian.mccowan.space/2015/04/07/Spacemacs/][Spacemacs: A Vimmer's Emacs Prerequisites]] + - Note: The article refers to ~SPC b s~ as the keybinding to switch buffers. + It is ~SPC b b~ +- [[http://thume.ca/howto/2015/03/07/configuring-spacemacs-a-tutorial/][Configuring Spacemacs: A Tutorial]] +- [[http://juanjoalvarez.net/es/detail/2014/sep/19/vim-emacsevil-chaotic-migration-guide/][From Vim to Emacs+Evil chaotic migration guide]] diff --git a/doc/img/crappy-powerline-separators.png b/doc/img/crappy-powerline-separators.png new file mode 100644 index 0000000..0d813b8 Binary files /dev/null and b/doc/img/crappy-powerline-separators.png differ diff --git a/doc/img/dot-error.png b/doc/img/dot-error.png new file mode 100644 index 0000000..9e1d366 Binary files /dev/null and b/doc/img/dot-error.png differ diff --git a/doc/img/dot-info.png b/doc/img/dot-info.png new file mode 100644 index 0000000..7583bbe Binary files /dev/null and b/doc/img/dot-info.png differ diff --git a/doc/img/dot-warning.png b/doc/img/dot-warning.png new file mode 100644 index 0000000..2e8a36c Binary files /dev/null and b/doc/img/dot-warning.png differ diff --git a/doc/img/flycheck-error.png b/doc/img/flycheck-error.png new file mode 100644 index 0000000..3405cdf Binary files /dev/null and b/doc/img/flycheck-error.png differ diff --git a/doc/img/flycheck-info.png b/doc/img/flycheck-info.png new file mode 100644 index 0000000..c3428f1 Binary files /dev/null and b/doc/img/flycheck-info.png differ diff --git a/doc/img/flycheck-mode-line.png b/doc/img/flycheck-mode-line.png new file mode 100644 index 0000000..f23e315 Binary files /dev/null and b/doc/img/flycheck-mode-line.png differ diff --git a/doc/img/flycheck-warning.png b/doc/img/flycheck-warning.png new file mode 100644 index 0000000..b32026f Binary files /dev/null and b/doc/img/flycheck-warning.png differ diff --git a/doc/img/powerline-alternate.png b/doc/img/powerline-alternate.png new file mode 100644 index 0000000..4979224 Binary files /dev/null and b/doc/img/powerline-alternate.png differ diff --git a/doc/img/powerline-anzu.png b/doc/img/powerline-anzu.png new file mode 100644 index 0000000..b5a2f9c Binary files /dev/null and b/doc/img/powerline-anzu.png differ diff --git a/doc/img/powerline-arrow-fade.png b/doc/img/powerline-arrow-fade.png new file mode 100644 index 0000000..0facdec Binary files /dev/null and b/doc/img/powerline-arrow-fade.png differ diff --git a/doc/img/powerline-arrow.png b/doc/img/powerline-arrow.png new file mode 100644 index 0000000..e887a36 Binary files /dev/null and b/doc/img/powerline-arrow.png differ diff --git a/doc/img/powerline-bar.png b/doc/img/powerline-bar.png new file mode 100644 index 0000000..4c810f1 Binary files /dev/null and b/doc/img/powerline-bar.png differ diff --git a/doc/img/powerline-box.png b/doc/img/powerline-box.png new file mode 100644 index 0000000..7ec53ca Binary files /dev/null and b/doc/img/powerline-box.png differ diff --git a/doc/img/powerline-brace.png b/doc/img/powerline-brace.png new file mode 100644 index 0000000..e667039 Binary files /dev/null and b/doc/img/powerline-brace.png differ diff --git a/doc/img/powerline-butt.png b/doc/img/powerline-butt.png new file mode 100644 index 0000000..981263c Binary files /dev/null and b/doc/img/powerline-butt.png differ diff --git a/doc/img/powerline-chamfer.png b/doc/img/powerline-chamfer.png new file mode 100644 index 0000000..9fb4f4b Binary files /dev/null and b/doc/img/powerline-chamfer.png differ diff --git a/doc/img/powerline-contour.png b/doc/img/powerline-contour.png new file mode 100644 index 0000000..b4112eb Binary files /dev/null and b/doc/img/powerline-contour.png differ diff --git a/doc/img/powerline-curve.png b/doc/img/powerline-curve.png new file mode 100644 index 0000000..6d31e5e Binary files /dev/null and b/doc/img/powerline-curve.png differ diff --git a/doc/img/powerline-fix-windows.png b/doc/img/powerline-fix-windows.png new file mode 100644 index 0000000..fa87e7f Binary files /dev/null and b/doc/img/powerline-fix-windows.png differ diff --git a/doc/img/powerline-nil.png b/doc/img/powerline-nil.png new file mode 100644 index 0000000..9da702e Binary files /dev/null and b/doc/img/powerline-nil.png differ diff --git a/doc/img/powerline-rounded.png b/doc/img/powerline-rounded.png new file mode 100644 index 0000000..9666167 Binary files /dev/null and b/doc/img/powerline-rounded.png differ diff --git a/doc/img/powerline-roundstub.png b/doc/img/powerline-roundstub.png new file mode 100644 index 0000000..90402c6 Binary files /dev/null and b/doc/img/powerline-roundstub.png differ diff --git a/doc/img/powerline-slant.png b/doc/img/powerline-slant.png new file mode 100644 index 0000000..f02078d Binary files /dev/null and b/doc/img/powerline-slant.png differ diff --git a/doc/img/powerline-update.png b/doc/img/powerline-update.png new file mode 100644 index 0000000..9bd6523 Binary files /dev/null and b/doc/img/powerline-update.png differ diff --git a/doc/img/powerline-wave.png b/doc/img/powerline-wave.png new file mode 100644 index 0000000..d6090f5 Binary files /dev/null and b/doc/img/powerline-wave.png differ diff --git a/doc/img/powerline-zigzag.png b/doc/img/powerline-zigzag.png new file mode 100644 index 0000000..7fb3cf2 Binary files /dev/null and b/doc/img/powerline-zigzag.png differ diff --git a/doc/img/spacemacs-ahs-transient-state.png b/doc/img/spacemacs-ahs-transient-state.png new file mode 100644 index 0000000..cef0dac Binary files /dev/null and b/doc/img/spacemacs-ahs-transient-state.png differ diff --git a/doc/img/spacemacs-lisp-transient-state.png b/doc/img/spacemacs-lisp-transient-state.png new file mode 100644 index 0000000..f3eb236 Binary files /dev/null and b/doc/img/spacemacs-lisp-transient-state.png differ diff --git a/doc/img/spacemacs-python.png b/doc/img/spacemacs-python.png new file mode 100644 index 0000000..497075b Binary files /dev/null and b/doc/img/spacemacs-python.png differ diff --git a/doc/img/spacemacs-scale-transient-state.png b/doc/img/spacemacs-scale-transient-state.png new file mode 100644 index 0000000..1b2726a Binary files /dev/null and b/doc/img/spacemacs-scale-transient-state.png differ diff --git a/doc/img/spacemacs-startup.png b/doc/img/spacemacs-startup.png new file mode 100644 index 0000000..4118b01 Binary files /dev/null and b/doc/img/spacemacs-startup.png differ diff --git a/doc/img/spacemacs-urxvt.png b/doc/img/spacemacs-urxvt.png new file mode 100644 index 0000000..a837e64 Binary files /dev/null and b/doc/img/spacemacs-urxvt.png differ diff --git a/doc/img/title.png b/doc/img/title.png new file mode 100644 index 0000000..331537e Binary files /dev/null and b/doc/img/title.png differ diff --git a/doc/img/title2.png b/doc/img/title2.png new file mode 100644 index 0000000..3c3e62d Binary files /dev/null and b/doc/img/title2.png differ diff --git a/doc/img/update-green.png b/doc/img/update-green.png new file mode 100644 index 0000000..e2f7166 Binary files /dev/null and b/doc/img/update-green.png differ diff --git a/doc/img/update-orange.png b/doc/img/update-orange.png new file mode 100644 index 0000000..253df50 Binary files /dev/null and b/doc/img/update-orange.png differ diff --git a/doc/img/update-red.png b/doc/img/update-red.png new file mode 100644 index 0000000..9601734 Binary files /dev/null and b/doc/img/update-red.png differ diff --git a/doc/img/which-key.png b/doc/img/which-key.png new file mode 100644 index 0000000..4a1409d Binary files /dev/null and b/doc/img/which-key.png differ diff --git a/init.el b/init.el new file mode 100644 index 0000000..d0cd280 --- /dev/null +++ b/init.el @@ -0,0 +1,35 @@ +;;; init.el --- Spacemacs Initialization File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Without this comment emacs25 adds (package-initialize) here +;; (package-initialize) + +;; Increase gc-cons-threshold, depending on your system you may set it back to a +;; lower value in your dotfile (function `dotspacemacs/user-config') +(setq gc-cons-threshold 100000000) + +(defconst spacemacs-version "0.200.5" "Spacemacs version.") +(defconst spacemacs-emacs-min-version "24.4" "Minimal version of Emacs.") + +(if (not (version<= spacemacs-emacs-min-version emacs-version)) + (message (concat "Your version of Emacs (%s) is too old. " + "Spacemacs requires Emacs version %s or above.") + emacs-version spacemacs-emacs-min-version) + (load-file (concat (file-name-directory load-file-name) + "core/core-load-paths.el")) + (require 'core-spacemacs) + (spacemacs/init) + (spacemacs/maybe-install-dotfile) + (configuration-layer/sync) + (spacemacs-buffer/display-info-box) + (spacemacs/setup-startup-hook) + (require 'server) + (unless (server-running-p) (server-start))) diff --git a/layers/+chat/erc/README.org b/layers/+chat/erc/README.org new file mode 100644 index 0000000..98ca526 --- /dev/null +++ b/layers/+chat/erc/README.org @@ -0,0 +1,103 @@ +#+TITLE: ERC layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#os-x][OS X]] + - [[#social-graph][Social graph]] + - [[#default-servers][Default servers]] + - [[#security-note][Security Note]] + - [[#key-bindings][Key bindings]] + - [[#spacemacs-layout-support][Spacemacs Layout Support]] + +* Description +Layer for [[http://www.emacswiki.org/emacs/ERC][ERC IRC chat]]. + +* Features +- Highlight nicks (using [[https://github.com/leathekd/erc-hl-nicks][erc-hl-nicks]]) +- Image inline support (using [[https://github.com/kidd/erc-image.el][erc-image]]) +- Logging to ~/.emacs.d/.cache/erc-logs and ViewLogMode for viewing logs + (using [[https://github.com/Niluge-KiWi/erc-view-log][erc-view-log]]) +- YouTube videos Thumbnails inline (using [[https://github.com/yhvh/erc-yt][erc-yt]]) +- Social Graph for ERC messages (using [[https://github.com/vibhavp/erc-social-graph][erc-social-graph]]) +- Optional SASL authentication via the variable =erc-enable-sasl-auth= + (using [[http://emacswiki.org/emacs/ErcSASL][erc-sasl]]) +- Completion of Emojis using [[https://github.com/dunn/company-emoji][company-emoji]] (still needs a way of showing, either + using the =emoji= layer or having a proper font) :clap: + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =erc= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** OS X +It's recommended to install the [[https://github.com/alloy/terminal-notifier][terminal-notifier gem]] so that you get +notifications via the OS X Notification Center. + +** Social graph +[[https://github.com/vibhavp/erc-social-graph][erc-social-graph]] needs graphviz to be installed on your system. + +** Default servers +You can define the default servers in the ERC custom layout by setting the +variable =erc-server-list=. Setting =:ssl= non nil will connect with =erc-tls=. +You can also use =aiD= to connect to your default servers outside the +custom layout. + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers + '((erc :variables + erc-server-list + '(("irc.freenode.net" + :port "6697" + :ssl t + :nick "some-user" + :password "secret") + ("irc.myworkirc.net" + :port "1234" + :nick "some-suit" + :password "hunter2"))))) +#+END_SRC + +*** Security Note +You should not store your passwords in the clear in your =.spacemacs=, and that +goes double if you version your config file. ERC allows for a number of ways of +protecting this information. + +First, ERC will check your =~/.authinfo.gpg=, looking for lines like + +#+BEGIN_SRC shell + machine login password port +#+END_SRC + +You can omit =:password= in this case. + +You could also set an environment variable (or otherwise secret variable) and +read that in =:password=. + +* Key bindings + +| Key Binding | Description | +|-------------+-------------------------------------------------------| +| ~SPC a i e~ | Starts ERC | +| ~SPC a i E~ | Starts ERC via TLS/SSL | +| ~SPC a i i~ | Switch to next active ERC buffer | +| ~SPC a i D~ | Start ERC with default servers | +| ~SPC m b~ | Switch between ERC buffers | +| ~SPC m d~ | Interactively input a user action and send it to IRC. | +| ~SPC m D~ | Draw Social Graph using [[https://github.com/vibhavp/erc-social-graph][erc-social-graph]] | +| ~SPC m j~ | Join a channel, executes the /join command | +| ~SPC m n~ | Run "/names #channel" in the current channel. | +| ~SPC m l~ | Run the /list command | +| ~SPC m p~ | Part from the channel | +| ~SPC m q~ | Quit server | + +*Note:* If you want to connect securely to an IRC server, you must run =erc-tls= + command on ~SPC a i E~ instead of the =erc= command. + +* Spacemacs Layout Support +ERC buffers are added automatically to the default layout for ERC controlled by +the variable ~erc-spacemacs-layout-name~ (defaults to "@ERC") and the default +binding ("E") is controlled by ~erc-spacemacs-layout-binding~ diff --git a/layers/+chat/erc/config.el b/layers/+chat/erc/config.el new file mode 100644 index 0000000..7567fb1 --- /dev/null +++ b/layers/+chat/erc/config.el @@ -0,0 +1,24 @@ +;;; config.el --- erc Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar erc-enable-sasl-auth nil + "If non nil then use SASL authenthication with ERC.") + +(defvar erc-spacemacs-layout-name "@ERC" + "Name used in the setup for `spacemacs-layouts' micro-state") + +(defvar erc-spacemacs-layout-binding "E" + "Binding used in the setup for `spacemacs-layouts' micro-state") + +(defvar erc-server-list nil + "If non nil, connect automatically to the specified servers with the given credentials.") + +(spacemacs|defvar-company-backends erc-mode) diff --git a/layers/+chat/erc/funcs.el b/layers/+chat/erc/funcs.el new file mode 100644 index 0000000..34699e1 --- /dev/null +++ b/layers/+chat/erc/funcs.el @@ -0,0 +1,27 @@ +;;; funcs.el --- Spacemacs ERC Layer functions File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun erc//servers (server-list) + (dolist (s server-list) + (setq s (copy-list s)) + (apply (if + (plist-get (cdr s) :ssl) + (progn + (remf (cdr s) :ssl) + 'erc-tls) + 'erc) + :server s))) + +(defun erc/default-servers () + (interactive) + (if erc-server-list + (erc//servers erc-server-list) + (message "You must define erc-server-list"))) diff --git a/layers/+chat/erc/local/erc-sasl/erc-sasl.el b/layers/+chat/erc/local/erc-sasl/erc-sasl.el new file mode 100644 index 0000000..0736b38 --- /dev/null +++ b/layers/+chat/erc/local/erc-sasl/erc-sasl.el @@ -0,0 +1,95 @@ +;; erc-sasl.el -- handle SASL PLAIN authentication + +;; Copyright (C) 2012 Joseph Gay + +;; Author: Joseph Gay +;; Keywords: comm + +;; This file is NOT part of GNU Emacs. + +;; GNU Emacs 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. + +;; GNU Emacs 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 . + +;;; Commentary: + +;; This file implements SASL PLAIN authentication +;; To activate: +;; +;; (require 'erc-sasl) +;; +;; (add-to-list 'erc-sasl-server-regexp-list "host\\.server\\.com") +;; e.g. irc\\.freenode\\.net, or .* for any host +;; +;; To disable: +;; (setq erc-sasl-use-sasl nil) +;; +;; NOTE: requires passing a password initially to (erc) and variants + +;;; Code: + +(eval-when-compile (require 'cl)) + +(defvar erc-sasl-use-sasl t + "Set to nil to disable SASL auth") + +(defvar erc-sasl-server-regexp-list '() + "List of regexps matching server host names for which sasl + should be used") + +(defun erc-sasl-use-sasl-p () + "Used internally to decide whether SASL should be used in the +current session" + (and erc-sasl-use-sasl + (boundp 'erc-session-server) + (cl-loop for re in erc-sasl-server-regexp-list + thereis (integerp (string-match re erc-session-server))))) + +(define-erc-response-handler (CAP) + "Client capability framework is used to request SASL auth, need + to wait for ACK to begin" nil + (let ((msg (erc-response.contents parsed))) + (when (string-match " *sasl" msg) + (erc-server-send "AUTHENTICATE PLAIN") + ;; now wait for AUTHENTICATE + + ))) + +(define-erc-response-handler (AUTHENTICATE) + "Handling empty server response indicating ready to receive + authentication." nil + (if erc-session-password + (let ((msg (erc-response.contents parsed))) + (when (string= "+" msg) + ;; plain auth + (erc-server-send + (format "AUTHENTICATE %s" + (base64-encode-string + (concat "\0" (erc-current-nick) + "\0" erc-session-password) t))))) + (progn + (erc-display-message + parsed 'error + (if erc-server-connected 'active proc) + "You must set a password in order to use SASL authentication.") + ;; aborting SASL auth + (erc-server-send (erc-server-send "AUTHENTICATE *"))))) + +(define-erc-response-handler (903) + "Handling a successful SASL authentication." nil + (erc-server-send "CAP END")) + +(provide 'erc-sasl) + +;;; erc-sasl.el ends here +;; Local Variables: +;; indent-tabs-mode: nil +;; End: diff --git a/layers/+chat/erc/local/erc-tex/erc-tex.el b/layers/+chat/erc/local/erc-tex/erc-tex.el new file mode 100644 index 0000000..5b316b1 --- /dev/null +++ b/layers/+chat/erc/local/erc-tex/erc-tex.el @@ -0,0 +1,176 @@ +;;; erc-tex.el --- LaTeX mathematical expressions rendering for ERC + +;; Copyright (C) 2009 David Vazquez + +;; Last-modified: <2009-09-14 02:11:53 david> + +;; Authors: David Vazquez +;; Created: 12 Sep 2009 +;; Keywords: comm, tex + +;; This file 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, or (at your option) +;; any later version. + +;; This file 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., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; erc-tex is a tiny ERC module which render LaTeX mathematical expressions +;; in your ERC chats. You will need both latex and dvipng in order to use this +;; module. +;; +;; Once erc-tex is avalaible for your Emacs, you can use `erc-tex-mode' to +;; toggle the module. This will render the text between $...$ as a LaTeX +;; expression. Indeed, you can use `erc-tex-image-edit', bound to `RET' on TeX +;; formulas to edit the TeX code in the prompt and resend the image. + +;;; TODO: +;; - Highlight the formulas according to ERC faces as erc-track. + +;;; Code: + +(eval-when-compile (require 'cl)) +(require 'erc) + + +(defvar erc-tex-latex-program "latex" + "Program name for invoking LaTeX.") + +(defvar erc-tex-dvipng-program "dvipng" + "Program name for invoking dvipng.") + +(defvar erc-tex-image-size 1.2 + "Ratio of magnification.") + + +;; Error condition signaled when it cannot render a LaTeX expression. +(put 'erc-tex-bad-expression-error + 'error-conditions '(error erc-tex-bad-expression-error)) + + +(defsubst erc-tex-run-latex (&rest arguments) + "Launch LaTeX program with some arguments." + (unless (zerop (apply #'call-process erc-tex-latex-program nil nil nil arguments)) + (signal 'erc-tex-bad-expression-error nil))) + +(defsubst erc-tex-run-dvipng (&rest arguments) + "Launch dvipng program with some arguments." + (unless (zerop (apply #'call-process erc-tex-dvipng-program nil nil nil arguments)) + (signal 'erc-tex-bad-expression-error nil))) + +;; Call to latex and dvipng in order to build a PNG image from the LaTeX +;; expression MATH-STRING. Return the image descriptor if it was sucessful, +;; NIL otherwise. +(defun erc-tex-make-image (math-expression fg bg) + (condition-case nil + (let* ((prefix (concat temporary-file-directory (make-temp-name "erc-tex-"))) + (tex-file (concat prefix ".tex")) + (dvi-file (concat prefix ".dvi")) + (png-file (concat prefix ".png"))) + + (with-temp-file tex-file + (insert "\\documentclass{article}\n" + "\\pagestyle{empty}\n" + "\\usepackage{amsmath, amssymb, amsthm}\n" + "\\begin{document}\n" + "\\par\n" + "$" math-expression "$" + "\\end{document}\n")) + + (erc-tex-run-latex (concat "-output-directory=" temporary-file-directory) tex-file) + + (cl-flet ((colorize (color) + ;; Return a string which stand for COLOR in the format that + ;; dvipng understands. + (let ((max (car (color-values "#ffffff")))) + (destructuring-bind (r g b) + (color-values color) + (format "rgb %.02f %.02f %.02f" + (/ (float r) max) + (/ (float g) max) + (/ (float b) max)))))) + + (erc-tex-run-dvipng "-x" (number-to-string (floor (* 1000 erc-tex-image-size))) + "-T" "tight" + "-fg" (colorize fg) + "-bg" (colorize bg) + "-o" png-file + dvi-file)) + (delete-file tex-file) + (delete-file dvi-file) + (create-image png-file 'png nil :margin '(0 . 5) :ascent 'center)) + + ((erc-tex-bad-expression-error) + ;; We do not delete auxiliary files if any error ocurred. + ))) + + + +(defvar erc-tex-image-keymap + (let ((keymap (make-sparse-keymap))) + (define-key keymap (kbd "RET") 'erc-tex-image-edit) + keymap)) + +(defun erc-tex-image-edit () + (interactive) + (let* ((start (point)) + (i start) + (prop (get-char-property i 'display))) + (while (eq prop (get-char-property i 'display)) + (setq i (1+ i))) + (goto-char (point-max)) + (insert (buffer-substring-no-properties start i)))) + +(defun erc-tex-render (&optional fg bg) + (let ((fg (or fg (face-foreground 'default))) + (bg (or bg (face-background 'default)))) + (goto-char (point-min)) + (while (re-search-forward "\\$[^$]*\\$" nil t) + (let* ((match (match-string-no-properties 0)) + (descp (erc-tex-make-image match fg bg))) + (when descp + (let (start end) + (delete-region (match-beginning 0) (match-end 0)) + (setq start (point)) + (insert-image descp match) + (setq end (point)) + (put-text-property start end 'keymap erc-tex-image-keymap))))))) + + +;;; Minor mode + +(defun erc-tex-render-insert () + (erc-tex-render)) + +(defun erc-tex-render-send () + (erc-tex-render + (face-foreground 'erc-input-face) + (face-background 'erc-input-face))) + +(define-erc-module tex latex + "Display LaTeX mathematical expressions as images in ERC." + ((add-hook 'erc-insert-modify-hook 'erc-tex-render-insert t) + (add-hook 'erc-send-modify-hook 'erc-tex-render-send t)) + ((remove-hook 'erc-insert-modify-hook 'erc-tex-render-insert) + (remove-hook 'erc-send-modify-hook 'erc-tex-render-send))) + + +(provide 'erc-tex) + +;; Local variables: +;; fill-column: 78 +;; indent-tabs-mode: nil +;; time-stamp-pattern: "10/^;; Last-modified: <%%>$" +;; End: + +;;; erc-tex.el ends here diff --git a/layers/+chat/erc/local/erc-yank/README.md b/layers/+chat/erc/local/erc-yank/README.md new file mode 100644 index 0000000..29e2410 --- /dev/null +++ b/layers/+chat/erc/local/erc-yank/README.md @@ -0,0 +1,19 @@ +# erc-yank + +Automagically create a Gist if pasting more than 5 lines + +Hook in as follows: + + (add-hook 'erc-mode-hook + (lambda () (define-key erc-mode-map [(control ?y)] 'erc-yank))) + +Or, if you want to use my `use-package' macro: + + (use-package erc + :commands erc + :config + (use-package erc-yank + :init + (bind-key "C-y" 'erc-yank erc-mode-map))) + +This module requires gist.el, from: https://github.com/defunkt/gist.el diff --git a/layers/+chat/erc/local/erc-yank/erc-yank.el b/layers/+chat/erc/local/erc-yank/erc-yank.el new file mode 100644 index 0000000..62a49bf --- /dev/null +++ b/layers/+chat/erc/local/erc-yank/erc-yank.el @@ -0,0 +1,106 @@ +;;; erc-yank --- Automagically create a Gist if pasting more than 5 lines + +;; Copyright (C) 2012 John Wiegley + +;; Author: John Wiegley +;; Created: 17 Jun 2012 +;; Version: 1.0 +;; Keywords: erc yank gist +;; X-URL: https://github.com/jwiegley/erc-yank + +;; 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: + +;; Automagically create a Gist if pasting more than 5 lines. +;; +;; Hook in as follows: +;; +;; (add-hook 'erc-mode-hook +;; (lambda () (define-key erc-mode-map [(control ?y)] 'erc-yank))) +;; +;; Or, if you want to use my `use-package' macro: +;; +;; (use-package erc +;; :commands erc +;; :config +;; (use-package erc-yank +;; :init +;; (bind-key "C-y" 'erc-yank erc-mode-map))) +;; +;; This module requires gist.el, from: https://github.com/defunkt/gist.el + +;;; Code: + +(require 'gist) + +(defgroup erc-yank nil + "Automagically create a Gist if pasting more than 5 lines" + :group 'erc) + +(defcustom erc-yank-flood-limit 5 + "Maximum number of lines allowed to yank to an erc buffer." + :type 'integer + :group 'erc-yank) + +(defcustom erc-yank-query-before-gisting t + "If non-nil, ask the user before creating a new Gist." + :type 'boolean + :group 'erc-yank) + +(defcustom erc-yank-display-text-on-prompt t + "If non-nil, show the text to yank in another buffer when prompting." + :type 'boolean + :group 'erc-yank) + +(defun erc-yank (&optional arg) + "Yank or make a gist depending on the size of the yanked text." + (interactive "*P") + (let* ((kill-text (current-kill (cond + ((listp arg) 0) + ((eq arg '-) -2) + (t (1- arg))))) + (lines (length (split-string kill-text "\n")))) + (if (and (> lines erc-yank-flood-limit) + (or (not erc-yank-query-before-gisting) + (let ((query + (format (concat "Text to yank is %d lines;" + " create a Gist instead? ") lines))) + (if erc-yank-display-text-on-prompt + (save-window-excursion + (with-current-buffer (get-buffer-create "*Yank*") + (delete-region (point-min) (point-max)) + (insert kill-text) + (goto-char (point-min)) + (display-buffer (current-buffer)) + (fit-window-to-buffer + (get-buffer-window (current-buffer))) + (unwind-protect + (y-or-n-p query) + (kill-buffer (current-buffer))))) + (y-or-n-p query))))) + (let ((buf (current-buffer))) + (with-temp-buffer + (insert kill-text) + (gist-region (point-min) (point-max) nil + `(lambda (gist) + (with-current-buffer ,buf + (insert (oref gist :html-url))))))) + (yank arg)))) + +(provide 'erc-yank) + +;;; erc-yank.el ends here diff --git a/layers/+chat/erc/packages.el b/layers/+chat/erc/packages.el new file mode 100644 index 0000000..c539b0d --- /dev/null +++ b/layers/+chat/erc/packages.el @@ -0,0 +1,247 @@ +;;; packages.el --- erc Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq erc-packages + '( + company + company-emoji + emoji-cheat-sheet-plus + erc + (erc-gitter :location (recipe + :fetcher github + :repo "jleechpe/erc-gitter") + :excluded t) + erc-hl-nicks + erc-image + (erc-sasl :location local) + erc-social-graph + (erc-tex :location local) + erc-view-log + (erc-yank :location local :excluded t) + erc-yt + linum + persp-mode + )) + +(when (spacemacs/system-is-mac) + (push 'erc-terminal-notifier erc-packages)) + +(defun erc/post-init-company () + (spacemacs|add-company-hook erc-mode) + (push 'company-capf company-backends-erc-mode)) + +(defun erc/post-init-company-emoji () + (push 'company-emoji company-backends-erc-mode)) + +(defun erc/post-init-emoji-cheat-sheet-plus () + (add-hook 'erc-mode-hook 'emoji-cheat-sheet-plus-display-mode)) + +(defun erc/init-erc () + "Initialize ERC" + (use-package erc + :defer t + :init + (progn + (spacemacs/set-leader-keys + "aie" 'erc + "aiE" 'erc-tls + "aii" 'erc-track-switch-buffer + "aiD" 'erc/default-servers) + ;; utf-8 always and forever + (setq erc-server-coding-system '(utf-8 . utf-8))) + :config + (progn + (use-package erc-autoaway + :defer t + :init + (setq erc-auto-discard-away t + erc-autoaway-idle-seconds 600 + erc-autoaway-use-emacs-idle t)) + (erc-services-mode 1) + (defun erc-list-command () + "execute the list command" + (interactive) + (insert "/list") + (erc-send-current-line)) + (setq erc-kill-buffer-on-part t + erc-kill-queries-on-quit t + erc-kill-server-buffer-on-quit t) + (add-hook 'erc-connect-pre-hook (lambda (x) (erc-update-modules))) + (erc-track-mode t) + (setq erc-track-exclude-types '("JOIN" "NICK" "PART" "QUIT" "MODE") + erc-server-coding-system '(utf-8 . utf-8)) + (setq erc-prompt (lambda () (concat "[" (buffer-name) "]"))) + + (require 'notifications) + (defun erc-global-notify (match-type nick message) + "Notify when a message is recieved." + (notifications-notify + :title nick + :body message + :app-icon (concat spacemacs-assets-directory "spacemacs.svg") + :urgency 'low)) + + ;; osx doesn't have dbus support + (when (boundp 'dbus-compiled-version) + (add-hook 'erc-text-matched-hook 'erc-global-notify)) + + ;; keybindings + (spacemacs/set-leader-keys-for-major-mode 'erc-mode + "d" 'erc-input-action + "j" 'erc-join-channel + "n" 'erc-channel-names + "l" 'erc-list-command + "p" 'erc-part-from-channel + "q" 'erc-quit-server)))) + +(defun erc/init-erc-gitter () + (use-package erc-gitter + :config + (add-to-list 'erc-modules 'gitter))) + + +(defun erc/init-erc-hl-nicks () + (spacemacs|use-package-add-hook erc + :post-config + (use-package erc-hl-nicks))) + +(defun erc/init-erc-sasl () + (spacemacs|use-package-add-hook erc + :post-config + (use-package erc-sasl + :defer t + :if erc-enable-sasl-auth + ;; Following http://www.emacswiki.org/emacs/ErcSASL + ;; Maybe an advice would be better? + :config + (progn + ;; Add any server like this + ;; (add-to-list 'erc-sasl-server-regexp-list "host\\.server\\.com") + (add-to-list 'erc-sasl-server-regexp-list "irc\\.freenode\\.net") + (defun erc-login () + "Perform user authentication at the IRC server." + (erc-log (format "login: nick: %s, user: %s %s %s :%s" + (erc-current-nick) + (user-login-name) + (or erc-system-name (system-name)) + erc-session-server + erc-session-user-full-name)) + (if erc-session-password + (erc-server-send (format "PASS %s" erc-session-password)) + (message "Logging in without password")) + (when (and (featurep 'erc-sasl) (erc-sasl-use-sasl-p)) + (erc-server-send "CAP REQ :sasl")) + (erc-server-send (format "NICK %s" (erc-current-nick))) + (erc-server-send + (format "USER %s %s %s :%s" + ;; hacked - S.B. + (if erc-anonymous-login erc-email-userid (user-login-name)) + "0" "*" + erc-session-user-full-name)) + (erc-update-mode-line)))))) + +(defun erc/init-erc-social-graph () + (spacemacs|use-package-add-hook erc + :post-config + (use-package erc-social-graph + :init + (progn + ;; does not exist ? + ;; (erc-social-graph-enable) + (setq erc-social-graph-dynamic-graph t) + (spacemacs/set-leader-keys-for-major-mode 'erc-mode + "D" 'erc-social-graph-draw))))) + +(defun erc/init-erc-tex () + (spacemacs|use-package-add-hook erc + :post-config + (require 'erc-tex))) + +(defun erc/init-erc-yt () + (spacemacs|use-package-add-hook erc + :post-config + (use-package erc-yt + :init (with-eval-after-load 'erc + (add-to-list 'erc-modules 'youtube))))) + +(defun erc/init-erc-yank () + (spacemacs|use-package-add-hook erc + :post-config + (use-package erc-yank + :if (configuration-layer/package-usedp 'gist) + :init (evil-define-key 'normal erc-mode-map "p" 'erc-yank)))) + +(defun erc/init-erc-view-log () + (use-package erc-view-log + :defer t + :init + (progn + (setq erc-log-channels-directory + (expand-file-name + (concat spacemacs-cache-directory + "erc-logs"))) + (unless (file-exists-p erc-log-channels-directory) + (make-directory erc-log-channels-directory)) + (add-to-list 'auto-mode-alist + `(,(format "%s/.*\\.[log|txt]" + (regexp-quote + (expand-file-name + erc-log-channels-directory))) . erc-view-log-mode)) + (with-eval-after-load 'erc (add-to-list 'erc-modules 'log))) + :config + ;; ERC Logging + (progn + ;; Following https://raw.githubusercontent.com/Niluge-KiWi/erc-view-log/master/erc-view-log.el + ;; installation instructions + (add-hook 'erc-view-log-mode-hook 'turn-on-auto-revert-tail-mode) + + (spacemacs|define-transient-state erc-log + :title "ERC Log Transient State" + :doc "\n[_r_] reload the log file [_>_/_<_] go to the next/prev mention" + :evil-leader-for-mode (erc-mode . ".") + :bindings + ("r" erc-view-log-reload-file) + (">" erc-view-log-next-mention) + ("<" erc-view-log-previous-mention))))) + +(defun erc/init-erc-image () + (use-package erc-image + :defer t + :init (with-eval-after-load 'erc + (require 'erc-image) + (add-to-list 'erc-modules 'image)))) + +(defun erc/init-erc-terminal-notifier () + (use-package erc-terminal-notifier + :if (executable-find "terminal-notifier"))) + +(defun erc/post-init-linum () + (spacemacs/add-to-hooks 'spacemacs/no-linum '(erc-mode-hook + erc-insert-pre-hook))) + +(defun erc/post-init-persp-mode () + ;; do not save erc buffers + (with-eval-after-load 'persp-mode + (push (lambda (b) (with-current-buffer b (eq major-mode 'erc-mode))) + persp-filter-save-buffers-functions)) + + (spacemacs|define-custom-layout erc-spacemacs-layout-name + :binding erc-spacemacs-layout-binding + :body + (progn + (defun spacemacs-layouts/add-erc-buffer-to-persp () + (persp-add-buffer (current-buffer) + (persp-get-by-name + erc-spacemacs-layout-name))) + (add-hook 'erc-mode-hook #'spacemacs-layouts/add-erc-buffer-to-persp) + (if erc-server-list + (erc/default-servers) + (call-interactively 'erc))))) diff --git a/layers/+chat/jabber/README.org b/layers/+chat/jabber/README.org new file mode 100644 index 0000000..6c11922 --- /dev/null +++ b/layers/+chat/jabber/README.org @@ -0,0 +1,78 @@ +#+TITLE: Jabber contribution layer for Spacemacs + +[[file:img/jabber-logo.gif]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + - [[#jabber-roster][Jabber Roster]] + - [[#hipchat][HipChat]] + - [[#authentication][Authentication]] + - [[#joining-rooms][Joining rooms]] + +* Description +This layer adds keybindings for jabber.el. jabber.el is a Jabber (XMPP) client for Emacs + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =jabber= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key bindings + +| Key Binding | Description | +| ~SPC a j~ | Connect all accounts | + +** Jabber Roster +| Key Binding | Description | +| ~SPC m a~ | Jabber send presence | +| ~SPC m b~ | Jabber get browse | +| ~SPC m d~ | Jabber disconnect | +| ~SPC m e~ | Jabber roster edit action at point | +| ~SPC m g~ | Jabber display roster | +| ~SPC m i~ | Jabber get disco items | +| ~SPC m j~ | Jabber muc join | +| ~SPC m q~ | bury buffer | +| ~SPC m r~ | Jabber roster toggle offline display | +| ~SPC m s~ | Jabber send subscription request | +| ~SPC m v~ | Jabber get version | +| ~SPC m RET~ | Jabber roster ret action at point | + +* HipChat +** Authentication +To find YOUR_JABBER_ID visit "XMPP/Jabber info" section on your profile page at hipchat.com + #+begin_src emacs-lisp + + (setq ssl-program-name "gnutls-cli" + ssl-program-arguments '("--insecure" "-p" service host) + ssl-certificate-verification-policy 1) + + (setq jabber-account-list '(("YOUR_JABBER_ID@chat.hipchat.com" + (:port . 5223) + (:password . "YOUR_PASS") + (:connection-type . ssl)))) + #+end_src + +** Joining rooms +To simplify joining rooms, you can use something like this: + + #+begin_src emacs-lisp + (defvar hipchat-room-list '( + ("HIPCHAT NAME" . "XMPP/JABBER NAME") + )) + + (defvar hipchat-number "") + (defvar hipchat-nickname "YOU_NICKNAME") + (defun hipchat-join () + (interactive) + (let* ((room-list (sort (mapcar 'car hipchat-room-list) 'string-lessp)) + (selected-room (completing-read "Room name: " room-list)) + (hipchat-mapping (cdr (assoc selected-room hipchat-room-list)))) + (jabber-groupchat-join + (jabber-read-account) + (concat hipchat-number "" hipchat-mapping "@conf.hipchat.com") + hipchat-nickname + t))) + + #+end_src diff --git a/layers/+chat/jabber/funcs.el b/layers/+chat/jabber/funcs.el new file mode 100644 index 0000000..9511581 --- /dev/null +++ b/layers/+chat/jabber/funcs.el @@ -0,0 +1,20 @@ +;;; funcs.el --- Jabber layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spacemacs/jabber-connect-hook (jc) + (jabber-send-presence "" "Online" 10) + (jabber-whitespace-ping-start) + ;; Disable the minibuffer getting jabber messages when active + ;; See http://www.emacswiki.org/JabberEl + (define-jabber-alert echo "Show a message in the echo area" + (lambda (msg) + (unless (minibuffer-prompt) + (message "%s" msg))))) diff --git a/layers/+chat/jabber/img/attribution.md b/layers/+chat/jabber/img/attribution.md new file mode 100644 index 0000000..a10bad9 --- /dev/null +++ b/layers/+chat/jabber/img/attribution.md @@ -0,0 +1,5 @@ +This image (jabber-logo.gif) is a derivative of an image owned and +copyrighted by the Jabber Software Foundation and released under the +[CC-BY 2.5 license](http://creativecommons.org/licenses/by/2.5/), +which is available at +[at Wikimedia Commons](http://commons.wikimedia.org/wiki/File:Jabber_logo.png). diff --git a/layers/+chat/jabber/img/jabber-logo.gif b/layers/+chat/jabber/img/jabber-logo.gif new file mode 100644 index 0000000..5077a98 Binary files /dev/null and b/layers/+chat/jabber/img/jabber-logo.gif differ diff --git a/layers/+chat/jabber/packages.el b/layers/+chat/jabber/packages.el new file mode 100644 index 0000000..60092ae --- /dev/null +++ b/layers/+chat/jabber/packages.el @@ -0,0 +1,39 @@ +;;; packages.el --- jabber Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Tosh Lyons +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq jabber-packages '(jabber)) + +(defun jabber/init-jabber () + (use-package jabber + :defer t + :init + (progn + (add-hook 'jabber-post-connect-hooks 'spacemacs/jabber-connect-hook) + (spacemacs/set-leader-keys "aj" 'jabber-connect-all)) + :config + (progn + (spacemacs/set-leader-keys-for-major-mode 'jabber-roster-mode + "a" 'jabber-send-presence + "b" 'jabber-get-browse + "d" 'jabber-disconnect + "e" 'jabber-roster-edit-action-at-point + "g" 'jabber-display-roster + "i" 'jabber-get-disco-items + "j" 'jabber-muc-join + "q" 'bury-buffer + "r" 'jabber-roster-toggle-offline-display + "s" 'jabber-send-subscription-request + "v" 'jabber-get-version + "RET" 'jabber-roster-ret-action-at-point) + (evilified-state-evilify jabber-roster-mode jabber-roster-mode-map + "j" 'jabber-go-to-next-roster-item + "k" 'jabber-go-to-previous-roster-item)))) + diff --git a/layers/+chat/rcirc/README.org b/layers/+chat/rcirc/README.org new file mode 100644 index 0000000..45f5982 --- /dev/null +++ b/layers/+chat/rcirc/README.org @@ -0,0 +1,193 @@ +#+TITLE: RCIRC layer + +[[file:img/irc.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#configuration][Configuration]] + - [[#storing-the-credentials-in-your-dotfile][Storing the credentials in your dotfile]] + - [[#example][Example:]] + - [[#storing-the-credentials-in-your-dropbox][Storing the credentials in your Dropbox]] + - [[#example][Example:]] + - [[#storing-the-credentials-in-authinfo][Storing the credentials in authinfo]] + - [[#connecting-behind-a-znc-bouncer-and-storing-the-credentials-in-authinfo][Connecting behind a ZNC bouncer and storing the credentials in authinfo]] + - [[#disclaimer][Disclaimer]] + - [[#note][Note]] + - [[#key-bindings][Key Bindings]] + - [[#rcirc-documentation][Rcirc documentation]] + - [[#spacemacs-layout-support][Spacemacs Layout Support]] + +* Description +This layer provide support for [[http://www.gnu.org/software/emacs/manual/html_mono/rcirc.html][rcirc]] with optional support for authinfo +and ZNC. + +* Features +- Store channel logs into =~/.emacs.d/.cache/rcirc-logs/= +- Support for credentials stored in =~/.authinfo.gpg= (need to have gnutls) +- Support ZNC support (with optional =~/.authinfo.gpg=) +- Colored nicknames +- WIP: Real time change when people use =/s/foo/bar= in the chats +- Completion of Emojis using [[https://github.com/dunn/company-emoji][company-emoji]] (still needs a way of showing, either + using the =emoji= layer or having a proper font) :clap: + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =rcirc= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Configuration +There are several ways to configure rcirc supported by the layer: +- By storing your credentials in =rcirc-server-alist= in your dotfile (not + secured) +- By storing your credentials in =rcirc-server-alist= in your Dropbox (better + but still not secured) +- By storing your credentials in authinfo (secured) +- By using a ZNC bouncer _and_ storing your credentials (secured) + +*** Storing the credentials in your dotfile +You can store your servers configuration along with your credentials in the +=dotspacemacs/user-config= of your dotfile. + +*Important:* This method is the less secured and it is not recommended since +your dotfile is often stored in a public repository and is not crypted. This +is convenient but not recommended. + +**** Example: +#+BEGIN_SRC emacs-lisp +(setq rcirc-server-alist + '(("irc.freenode.net" + :user "spacemacs_user" + :port "1337" + :password "le_passwd" + :channels ("#emacs")))) +#+END_SRC + +*** Storing the credentials in your Dropbox +You can store your servers configuration along with your credentials in +your dropbox in the file =~/Dropbox/emacs/pinit-rcirc.el=. + +*Important:* This method is more secured since your file is stored in +a private location but it is still not crypted on your drive. Moreover +since Dropbox automatically sync your files you may have a lot of copies +of the file containing your credentials. This is convenient but not +recommended. + +**** Example: +#+BEGIN_SRC emacs-lisp +(setq rcirc-server-alist + '(("irc.freenode.net" + :user "spacemacs_user" + :port "1337" + :password "le_passwd" + :channels ("#emacs")))) +#+END_SRC + +*** Storing the credentials in authinfo +This method is considered secured and is the recommended way to configure +rcirc. + +1) If you want to use =authinfo.gpg= you have to enable the support for it by + setting =rcirc-enable-authinfo-support= to =t= in your dotfile: + + #+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '( + (rcirc :variables rcirc-enable-authinfo-support t))) + #+END_SRC + +2) In your =~/.authinfo.gpg= file store your credentials like this: + + #+BEGIN_EXAMPLE + machine irc.freenode.net port nickserv user password + #+END_EXAMPLE + +3) At last you need to provide your servers configuration in the + =dotspacemacs/user-config= function of your dotfile: + + #+BEGIN_SRC emacs-lisp + (setq rcirc-server-alist + '(("irc.freenode.net" + :user "spacemacs_user" + :port "1337" + :channels ("#emacs")))) + #+END_SRC + +*** Connecting behind a ZNC bouncer and storing the credentials in authinfo +This methods is also secured since it uses authinfo _but_ you must secure your +ZNC server configuration as well! + +ZNC is a popular bouncer which is easy to setup. A bouncer is a proxy that +connects to your IRC channels on your behalf, instead of connecting to the IRC +server you connect to your ZNC server. The ZNC server can store the discussions +in a buffer while you are not connected. + +**** Disclaimer +This assumes that you are familiar with ZNC and you have a ZNC server properly +setup. If it is not the case then it is recommended to read about ZNC +[[http://wiki.znc.in/ZNC][here]]. There is also an installation guide for Ubuntu [[https://www.digitalocean.com/community/tutorials/how-to-install-znc-an-irc-bouncer-on-an-ubuntu-vps][here]]. + +**** Note +For now authinfo is mandatory to use the ZNC configuration. + +1) To enable ZNC support set the variable =rcirc-enable-znc-support= to =t= in + your dotfile: + + #+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '( + (rcirc :variables rcirc-enable-znc-support t))) + #+END_SRC + +2) In your =~/.authinfo.gpg= file store your credentials like this: + + #+BEGIN_EXAMPLE + machine freenode.spacemacsserver.me port irc user spacemacs_user/freenode password ZNC_PASSWORD + machine geekshed.spacemacsserver.me port irc user spacemacs_user/geekshed password ZNC_PASSWORD + #+END_EXAMPLE + + *Important* =port= must be set to =irc=. This is a convention of the layer to + retrieve the credentials for the ZNC configuration. + +3) Then setup your servers configuration using subdomains in the + =dotspacemacs/user-config= function of your dotfile. The =:auth= keyword arguments + will be replaced by the credentials stored in your =~/.authinfo.gpg=. + + #+BEGIN_SRC emacs-lisp + (setq rcirc-server-alist + ;; This will replace :auth with the correct thing, see the doc for that function + '(("freenode" + :host "freenode.spacemacsserver.me" + :port "1337" + :auth "spacemacs_user/freenode" + :channels ("#emacs")) + ("geekshed" + :host "geekshed.spacemacsserver.me" + :port "1337" + :auth "spacemacs_user/geekshed" + :channels ("#jupiterbroadcasting")))) + #+END_SRC + +* Key Bindings + +| Key Binding | Description | +|-------------+-------------------------------------------------------------------------------| +| ~SPC a i r~ | Open rcirc | +| ~SPC l o i~ | Open rcirc in a custom perspective "@RICRC" (need perspectives layer enabled) | + +In normal state: + +| Key Binding | Description | +|-------------+--------------------------| +| ~C-j~ | next item in history | +| ~C-k~ | previous item in history | + +* Rcirc documentation +The rcirc documentation can be found [[http://www.gnu.org/software/emacs/manual/html_mono/rcirc.html][here]]. + +* Spacemacs Layout Support + +RCIRC buffers are added automatically to the default layout for RCIRC controlled by +the variable ~rcirc-spacemacs-layout-name~ (defaults to "@RCIRC") and the default +binding ("i") is controlled by ~rcirc-spacemacs-layout-binding~ diff --git a/layers/+chat/rcirc/config.el b/layers/+chat/rcirc/config.el new file mode 100644 index 0000000..d8549e1 --- /dev/null +++ b/layers/+chat/rcirc/config.el @@ -0,0 +1,26 @@ +;;; config.el --- rcirc Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(defvar rcirc-enable-authinfo-support nil + "if non nil then authentication uses authinfo.") + +(defvar rcirc-enable-znc-support nil + "if non nil then znc is enabled.") + +(defvar rcirc-spacemacs-layout-name "@RCIRC" + "Name used in the setup for `spacemacs-layouts' micro-state") + +(defvar rcirc-spacemacs-layout-binding "i" + "Binding used in the setup for `spacemacs-layouts' micro-state") + +(spacemacs|defvar-company-backends rcirc-mode) diff --git a/layers/+chat/rcirc/funcs.el b/layers/+chat/rcirc/funcs.el new file mode 100644 index 0000000..58502c5 --- /dev/null +++ b/layers/+chat/rcirc/funcs.el @@ -0,0 +1,83 @@ +;;; funcs.el --- rcirc Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + +;; authinfo ------------------------------------------------------------------ + +(defun spacemacs//rcirc-authinfo-config () + "Initialize authinfo. +Allow rcirc to read authinfo from ~/.authinfo.gpg via the auth-source API. +This doesn't support the chanserv auth method. " + (require 'auth-source) + (dolist (p (auth-source-search :port '("nickserv" "bitlbee" "quakenet") + :require '(:port :user :secret))) + (let ((secret (plist-get p :secret)) + (method (intern (plist-get p :port)))) + (add-to-list + 'rcirc-authinfo + (list (plist-get p :host) method (plist-get p :user) + (if (functionp secret) (funcall secret) secret)))))) + + +;; ZNC with authinfo --------------------------------------------------------- + +(defun spacemacs//znc-auth-source-fetch-password (server) + "Given a server with at least :host :port :login, return the :password" + (destructuring-bind (&key host auth &allow-other-keys) + (cdr server) + (destructuring-bind (&key secret &allow-other-keys) + (car (auth-source-search :host host + :port "irc" + :user auth + :require '(:user :secret))) + (if (functionp secret) (funcall secret) secret)))) + +;; (setq auth (auth-source--aput :host "")) +;; build rcirc-authinfo from rcirc-server-alist and authinfo +(defun spacemacs//znc-rcirc-server-alist-get-authinfo (server-alist) + "replace :auth in rcirc-server-alist with :password \"user:password\" + from .authinfo.gpg" + (dolist (server server-alist server-alist) + (let* ((host (car server)) + (plist (cdr server)) + (auth (plist-get plist :auth)) + (pass (spacemacs//znc-auth-source-fetch-password server))) + (when auth + (plist-put plist :password (format "%s:%s" auth pass)))))) + +;; rcirc does not know how to connect to the same server more than once, so +;; we build our own connection routine from our own rcirc-server-alist, +;; using :host rather than the server name for connecting. +(defun spacemacs//znc-rcirc-connect () + "Connect to rcirc-server-alist servers." + (loop + for s in rcirc-server-alist + collect + (destructuring-bind (&key host + (port rcirc-default-port) + (nick rcirc-default-nick) + (user-name rcirc-default-user-name) + (full-name rcirc-default-full-name) + channels + password + encryption + &allow-other-keys + &aux contact (server (car s))) + (cdr s) + (let ((host (or host server)) ; catter with server without :host + (connected + (loop for p in (rcirc-process-list) + thereis (string= server (process-get p :rcirc-server))))) + (unless connected + (let ((process + (rcirc-connect host port nick user-name + full-name channels password encryption))) + (process-put process :rcirc-server server))))))) diff --git a/layers/+chat/rcirc/img/irc.png b/layers/+chat/rcirc/img/irc.png new file mode 100644 index 0000000..6132b89 Binary files /dev/null and b/layers/+chat/rcirc/img/irc.png differ diff --git a/layers/+chat/rcirc/local/helm-rcirc/README.md b/layers/+chat/rcirc/local/helm-rcirc/README.md new file mode 100644 index 0000000..1ecebe5 --- /dev/null +++ b/layers/+chat/rcirc/local/helm-rcirc/README.md @@ -0,0 +1,4 @@ +helm-rcirc +========== + +An Helm interface for rcirc diff --git a/layers/+chat/rcirc/local/helm-rcirc/helm-rcirc.el b/layers/+chat/rcirc/local/helm-rcirc/helm-rcirc.el new file mode 100644 index 0000000..8a567ff --- /dev/null +++ b/layers/+chat/rcirc/local/helm-rcirc/helm-rcirc.el @@ -0,0 +1,39 @@ +(require 'rcirc) + +(defun helm-rcirc-auto-join-channels-alist () + "Return an alist where key is a server and value is a list of defined +channels to auto join." + (mapcar (lambda (server) + (cons (car server) (plist-get (cdr server) :channels))) + rcirc-server-alist) +) + +(defun helm-rcirc-auto-join-channels-source (entry) + "Construct the Helm source given an ENTRY. + +ENTRY is a key value pair where key is the server and value is a list of +channels." + (let ((server (car entry)) + (chans (cdr entry))) + (list (cons 'name (format "Server: %s" (car entry))) + (cons 'candidates (mapcar (lambda (chan) + (cons chan (cons server chan))) chans)) + (cons 'action 'helm-rcirc-open-channel-buffer)))) + +(defun helm-rcirc-open-channel-buffer (selected-value) + "Open the buffer corresponding to SELECTED-VALUE if any. + +SELECTED-VALUE is a key value pair where key is the server and value is the +channel name." + (let ((buf (format "%s@%s" (cdr selected-value) (car selected-value)))) + (if (bufferp (get-buffer buf)) + (switch-to-buffer buf) + (message (format "Cannot find buffer %s" buf))))) + +;;;###autoload +(defun helm-rcirc-auto-join-channels () + "rcirc auto join channels selection with helm interface." + (interactive) + (helm :buffer "*helm: Auto Join Channels (rcirc)*" + :sources (mapcar 'helm-rcirc-auto-join-channels-source + (helm-rcirc-auto-join-channels-alist)))) diff --git a/layers/+chat/rcirc/local/rcirc-late-fix/rcirc-late-fix.el b/layers/+chat/rcirc/local/rcirc-late-fix/rcirc-late-fix.el new file mode 100644 index 0000000..eb79375 --- /dev/null +++ b/layers/+chat/rcirc/local/rcirc-late-fix/rcirc-late-fix.el @@ -0,0 +1,90 @@ +;;; rcirc-late-fix.el -- Replace s/wrong/right strings on rcirc buffers +;; Copyright 2007 Hugo Schmitt + +;; 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, write to the Free +;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, +;; MA 02111-1307 USA + +;;; Commentary: + +;; The idea is to detect messages like 's/tset/test' and overwrite the +;; wrong word with the correction, on the original phrase, using +;; overlays. + +;; Please mail me (hugows@gmail.com) about any improvements or bug +;; reports you have regarding this file. + +;;; Changes (11/12/2007) (Tks tsdh for the suggestions) + +;; [x] Exclude the nicknames from correction. +;; [x] Strip the / from the replacement text. +;; [x] With s/foo/bar the last occurence of foo is replaced with bar, not the first. +;; [x] Support s/foo/bar/g to replace all occurences of foo with bar. +;; [ ] Use rcirc-response-formats for building the name string +;; [ ] A variable could control whether only whole words are changed (then +;; just concat "<" word ">") +;; [ ] Support s/word// and s/word//g for removing matching text + +;;; Bugs : + +;; This fails, probably caused by some missed detail about overlapping overlays: +;; Having the line aaaaaaaa and the replacement s/a/b/g results in a +;; _single_ b. + +;;; Code: + +(require 'rcirc) + +(add-hook 'rcirc-print-hooks 'rcirc-late-fix-hook) + +(defface rcirc-late-fix-face '((t (:underline t :foreground "Blue"))) + "Face for showing fixed words on the channel buffer.") + +(defun rcirc-late-fix-apply (beg end string) + (save-excursion + (let ((overlay (make-overlay beg end (current-buffer) nil t))) + (overlay-put overlay 'face 'rcirc-late-fix-face) + (overlay-put overlay 'display string)))) + +(defun rcirc-late-fix-hook (process sender response target text) + (save-excursion + (when (string-equal response "PRIVMSG") + (let (from to global matches) + (when (or (and (string-match "^s/\\(.+\\)/\\(.+\\)/g" text) + (setq from (match-string 1 text) + to (match-string 2 text) + global t)) + (and (string-match "^s/\\(.+\\)/\\([^/]+\\)" text) + (setq from (match-string 1 text) + to (match-string 2 text)))) + (set-buffer (rcirc-late-fix-matching-buffer target)) + (goto-char (point-max)) + (when (search-backward (concat "<" sender ">") nil t 2) + (goto-char (match-end 0)) ;; skip nickname + (while (search-forward from (point-at-eol) t) ;; make a list of the points from each match + (setf matches (cons (list (match-beginning 0) (match-end 0)) matches))) + (when (not (null matches)) ;; there was at least one match + (if global ;; global = replace all matches + (mapc '(lambda (x) (rcirc-late-fix-apply (car x) (cadr x) to)) matches) + (rcirc-late-fix-apply (caar matches) (cadar matches) to))))))))) + +(defun rcirc-late-fix-matching-buffer (name) + "Find buffer (channel) that starts with NAME." + (find-if '(lambda (x) (string-match (concat "^" name) x)) + (mapcar 'buffer-name (buffer-list)))) + + + +;;; rcirc-late-fix.el ends here +(provide 'rcirc-late-fix) diff --git a/layers/+chat/rcirc/local/rcirc-reconnect/rcirc-reconnect.el b/layers/+chat/rcirc/local/rcirc-reconnect/rcirc-reconnect.el new file mode 100644 index 0000000..0bc1d84 --- /dev/null +++ b/layers/+chat/rcirc/local/rcirc-reconnect/rcirc-reconnect.el @@ -0,0 +1,113 @@ +;;;; Auto reconnect +;;;; Taken from http://www.emacswiki.org/emacs/rcircReconnect +(defun-rcirc-command reconnect (arg) + "Reconnect the server process." + (interactive "i") + (if (buffer-live-p rcirc-server-buffer) + (with-current-buffer rcirc-server-buffer + (let ((reconnect-buffer (current-buffer)) + (server (or rcirc-server rcirc-default-server)) + (port (if (boundp 'rcirc-port) rcirc-port rcirc-default-port)) + (nick (or rcirc-nick rcirc-default-nick)) + channels) + (dolist (buf (buffer-list)) + (with-current-buffer buf + (when (equal reconnect-buffer rcirc-server-buffer) + (remove-hook 'change-major-mode-hook + 'rcirc-change-major-mode-hook) + (let ((server-plist (cdr (assoc-string server rcirc-server-alist)))) + (when server-plist + (setq channels (plist-get server-plist :channels)))) + ))) + (if process (delete-process process)) + (rcirc-connect server port nick + nil + nil + channels))))) + +;; the following minor mode does not work + +;; ;;; Attempt reconnection at increasing intervals when a connection is +;; ;;; lost. + +;; (defvar rcirc-reconnect-attempts 0) + +;; ;;;###autoload +;; (define-minor-mode rcirc-reconnect-mode +;; nil +;; nil +;; " Auto-Reconnect" +;; nil +;; (if rcirc-reconnect-mode +;; (progn +;; (make-local-variable 'rcirc-reconnect-attempts) +;; (add-hook 'rcirc-sentinel-functions +;; 'rcirc-reconnect-schedule nil t)) +;; (remove-hook 'rcirc-sentinel-functions +;; 'rcirc-reconnect-schedule t))) +;; ;; (if rcirc-reconnect-mode +;; ;; (add-hook 'rcirc-sentinel-functions 'sds-rcirc-sentinel) +;; ;; (remove-hook 'rcirc-sentinel-functions 'sds-rcirc-sentinel))) + +;; (defun rcirc-reconnect-schedule (process &optional sentinel seconds) +;; (condition-case err +;; (when (and (eq 'closed (process-status process)) +;; (buffer-live-p (process-buffer process))) +;; (with-rcirc-process-buffer process +;; (unless seconds +;; (setq seconds (exp (1+ rcirc-reconnect-attempts)))) +;; (rcirc-print +;; process "my-rcirc.el" "ERROR" rcirc-target +;; (format "scheduling reconnection attempt in %s second(s)." seconds) t) +;; (run-with-timer +;; seconds +;; nil +;; 'rcirc-reconnect-perform-reconnect +;; process))) +;; (error +;; (rcirc-print process "RCIRC" "ERROR" nil +;; (format "%S" err) t)))) + +;; (defun rcirc-reconnect-perform-reconnect (process) +;; (when (and (eq 'closed (process-status process)) +;; (buffer-live-p (process-buffer process)) +;; ) +;; (with-rcirc-process-buffer process +;; (when rcirc-reconnect-mode +;; (if (get-buffer-process (process-buffer process)) +;; ;; user reconnected manually +;; (setq rcirc-reconnect-attempts 0) +;; (let ((msg (format "attempting reconnect to %s..." +;; (process-name process) +;; ))) +;; (rcirc-print process "my-rcirc.el" "ERROR" rcirc-target +;; msg t)) +;; ;; remove the prompt from buffers +;; (condition-case err +;; (progn +;; (save-window-excursion +;; (save-excursion +;; (rcirc-cmd-reconnect nil))) +;; (setq rcirc-reconnect-attempts 0)) +;; ((quit error) +;; (incf rcirc-reconnect-attempts) +;; (rcirc-print process "my-rcirc.el" "ERROR" rcirc-target +;; (format "reconnection attempt failed: %s" err) t) +;; (rcirc-reconnect-schedule process)))))))) + +;; (defvar sds-rcirc-sentinel-last (current-time) "last reconnect attempt time") +;; (defun sds-rcirc-sentinel (process sentinel) +;; (let* ((now (current-time)) +;; (delay (float-time (time-subtract (current-time) +;; sds-rcirc-sentinel-last)))) +;; (message "%s sds-rcirc-sentinel: %s %s %s (last: %s, %s ago)" +;; (format-time-string "%F %R") process +;; (process-status process) sentinel +;; (format-time-string "%F %R" sds-rcirc-sentinel-last) +;; (sds-difftime-to-string delay)) +;; (when (and (string= sentinel "deleted") +;; (< 60 delay)) ; do not try to reconnect more than once a minute +;; (setq sds-rcirc-sentinel-last now) +;; (rcirc-cmd-reconnect nil)))) + +(provide 'rcirc-reconnect) diff --git a/layers/+chat/rcirc/packages.el b/layers/+chat/rcirc/packages.el new file mode 100644 index 0000000..3cb8b2d --- /dev/null +++ b/layers/+chat/rcirc/packages.el @@ -0,0 +1,171 @@ +(setq rcirc-packages + '( + company + company-emoji + emoji-cheat-sheet-plus + flyspell + (helm-rcirc :location local + :toggle (configuration-layer/package-usedp 'helm)) + persp-mode + rcirc + rcirc-color + rcirc-notify + )) + +(defun rcirc/post-init-company () + (spacemacs|add-company-hook rcirc-mode) + (push 'company-capf company-backends-rcirc-mode)) + +(defun rcirc/post-init-company-emoji () + (push 'company-emoji company-backends-rcirc-mode)) + +(defun rcirc/post-init-emoji-cheat-sheet-plus () + (add-hook 'rcirc-mode-hook 'emoji-cheat-sheet-plus-display-mode)) + +(defun rcirc/post-init-flyspell () + (spell-checking/add-flyspell-hook 'rcirc-mode-hook)) + +(defun rcirc/init-helm-rcirc () + (use-package helm-rcirc + :commands helm-rcirc-auto-join-channels + :init + (spacemacs/set-leader-keys "irc" 'helm-rcirc-auto-join-channels))) + +(defun rcirc/post-init-persp-mode () + ;; do not save rcirc buffers + (with-eval-after-load 'persp-mode + (push (lambda (b) (with-current-buffer b (eq major-mode 'rcirc-mode))) + persp-filter-save-buffers-functions)) + + (spacemacs|define-custom-layout rcirc-spacemacs-layout-name + :binding rcirc-spacemacs-layout-binding + :body + (progn + (defun spacemacs-layouts/add-rcirc-buffer-to-persp () + (persp-add-buffer (current-buffer) + (persp-get-by-name + rcirc-spacemacs-layout-name))) + (add-hook 'rcirc-mode-hook #'spacemacs-layouts/add-rcirc-buffer-to-persp) + (call-interactively 'spacemacs/rcirc)))) + +(defun rcirc/init-rcirc () + (use-package rcirc + :defer t + :init + (progn + (spacemacs/add-to-hook 'rcirc-mode-hook '(rcirc-omit-mode + rcirc-track-minor-mode)) + + (defun spacemacs//rcirc-with-authinfo (arg) + "Fire rcirc with support for authinfo." + (unless arg + (if (file-exists-p "~/.authinfo.gpg") + (spacemacs//rcirc-authinfo-config) + (message "Cannot find file ~/.authinfo.gpg"))) + (rcirc arg)) + + (defun spacemacs//rcirc-with-znc (arg) + "Fire rcirc with support for znc." + (if arg + (rcirc arg) + (setq rcirc-server-alist + ;; This will replace :auth with the correct thing, see the + ;; doc for that function + (spacemacs//znc-rcirc-server-alist-get-authinfo + rcirc-server-alist)) + (spacemacs//znc-rcirc-connect))) + + (spacemacs/set-leader-keys "air" 'spacemacs/rcirc) + (defun spacemacs/rcirc (arg) + "Launch rcirc." + (interactive "P") + (require 'rcirc) + ;; dispatch to rcirc launcher with appropriate support + (cond + (rcirc-enable-authinfo-support (spacemacs//rcirc-with-authinfo arg)) + (rcirc-enable-znc-support (spacemacs//rcirc-with-znc arg)) + (t (rcirc arg)))) + (evil-set-initial-state 'rcirc-mode 'insert)) + :config + (progn + ;; (set-input-method "latin-1-prefix") + (set (make-local-variable 'scroll-conservatively) 8192) + + (setq rcirc-fill-column 80 + rcirc-buffer-maximum-lines 2048 + rcirc-omit-responses '("JOIN" "PART" "QUIT" "NICK" "AWAY" "MODE") + rcirc-time-format "%Y-%m-%d %H:%M " + rcirc-omit-threshold 20) + + ;; Exclude rcirc properties when yanking, in order to be able to send mails + ;; for example. + (add-to-list 'yank-excluded-properties 'rcirc-text) + + ;; rcirc-reconnect + (let ((dir (configuration-layer/get-layer-local-dir 'rcirc))) + (require 'rcirc-reconnect + (concat dir "rcirc-reconnect/rcirc-reconnect.el"))) + + ;; load this file from the dropbox location load-path + ;; this is where you can store personal information + (require 'pinit-rcirc nil 'noerror) + + (evil-define-key 'normal rcirc-mode-map + (kbd "C-j") 'rcirc-insert-prev-input + (kbd "C-k") 'rcirc-insert-next-input) + + ;; add a key for EMMS integration + (when (boundp 'emms-track-description) + (defun rcirc/insert-current-emms-track () + (interactive) + (insert (emms-track-description (emms-playlist-current-selected-track)))) + (define-key rcirc-mode-map (kbd "C-c C-e") 'rcirc/insert-current-emms-track)) + + ;; Minimal logging to `~/.emacs.d/.cache/rcirc-logs/' + ;; by courtesy of Trent Buck. + (setq rcirc-log-directory (concat spacemacs-cache-directory "/rcirc-logs/")) + (setq rcirc-log-flag t) + (defun rcirc-write-log (process sender response target text) + (when rcirc-log-directory + (when (not (file-directory-p rcirc-log-directory)) + (make-directory rcirc-log-directory)) + (with-temp-buffer + ;; Sometimes TARGET is a buffer :-( + (when (bufferp target) + (setq target (with-current-buffer buffer rcirc-target))) + ;; Sometimes buffer is not anything at all! + (unless (or (null target) (string= target "")) + ;; Print the line into the temp buffer. + (insert (format-time-string "%Y-%m-%d %H:%M ")) + (insert (format "%-16s " (rcirc-user-nick sender))) + (unless (string= response "PRIVMSG") + (insert "/" (downcase response) " ")) + (insert text "\n") + ;; Append the line to the appropriate logfile. + (let ((coding-system-for-write 'no-conversion)) + (write-region (point-min) (point-max) + (concat rcirc-log-directory (downcase target)) + t 'quietly)))))) + (add-hook 'rcirc-print-hooks 'rcirc-write-log) + + ;; dependencies + ;; will autoload rcirc-notify + (rcirc-notify-add-hooks) + (require 'rcirc-color)))) + +(defun rcirc/init-rcirc-color () + (use-package rcirc-color :defer t)) + +(defun rcirc/init-rcirc-notify () + (use-package rcirc-notify + :defer t + :config + (progn + (defun spacemacs/rcirc-notify-beep (msg) + "Beep when notifying." + (let ((player "mplayer") + (sound (concat spacemacs-start-directory "site-misc/startup.ogg"))) + (when (and (executable-find player) + (file-exists-p sound))) + (start-process "beep-process" nil player sound))) + (add-hook 'rcirc-notify-page-me-hooks 'spacemacs/rcirc-notify-beep)))) diff --git a/layers/+chat/slack/README.org b/layers/+chat/slack/README.org new file mode 100644 index 0000000..f41a7d7 --- /dev/null +++ b/layers/+chat/slack/README.org @@ -0,0 +1,69 @@ +#+TITLE: Slack layer + +[[file:img/slack.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#configuration][Configuration]] + - [[#key-bindings][Key bindings]] + +* Description +This layer provides an interface to the Slack chat service via the emacs-slack +package. Where possible, this layer aims to reuse keybindings from the IRC +packages in Spacemacs. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =slack= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Configuration + +Follow the instructions in the [[https://github.com/yuya373/emacs-slack/blob/master/README.md][emacs-slack]] package for obtaining your client ID, +client secret, and token. + +To test that eveyrthing is alright put the following snippet in your +=dotspacemacs/user-config()= replacing =client-id=, =client-secret= and =token= +with your info. + +*Important* Do not keep private data in your dotfile. You can put your private +stuff elsewhere (like Dropbox for instance) and load the file in your dotfile. + +#+begin_src emacs-lisp +(slack-register-team + :name "emacs-slack" + :default t + :client-id "my@email.address" + :client-secret "mypassword" + :token "token" + :subscribed-channels '(general slackbot)) +#+end_src + +* Key bindings + +| Key Binding | Description | +|-------------+--------------------------| +| ~SPC a C s~ | (Re)connects to Slack | +| ~SPC a C j~ | Join a channel | +| ~SPC a C d~ | Direct message someone | +| ~SPC a C q~ | Close connection | +| ~SPC m j~ | Join a channel | +| ~SPC m d~ | Direct message someone | +| ~SPC m p~ | Load previous messages | +| ~SPC m e~ | Edit message at point | +| ~SPC m q~ | Quit Slack | +| ~SPC m m~ | Embed mention of user | +| ~SPC m c~ | Embed mention of channel | + +The following bindings are provided to mimic bindings in the official Slack +client. + +| Key Binding | Description | +|-------------+--------------------------| +| ~ m k~ | Join a channel | +| ~ m @~ | Embed mention of user | +| ~ m #~ | Embed mention of channel | + +In insert state, one can also use ~@~ and ~#~ directly without the leader key +prefix. diff --git a/layers/+chat/slack/img/slack.png b/layers/+chat/slack/img/slack.png new file mode 100644 index 0000000..fb4de28 Binary files /dev/null and b/layers/+chat/slack/img/slack.png differ diff --git a/layers/+chat/slack/packages.el b/layers/+chat/slack/packages.el new file mode 100644 index 0000000..6a18c67 --- /dev/null +++ b/layers/+chat/slack/packages.el @@ -0,0 +1,88 @@ +;;; packages.el --- slack layer packages file for Spacemacs. +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Kosta Harlan +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;;; Commentary: + +;;; Code: + +;; TODO: Integrate company-emoji. + +(defconst slack-packages + '( + alert + emoji-cheat-sheet-plus + flyspell + linum + persp-mode + slack + )) + +(defun slack/init-alert () + (use-package alert + :defer t + :init (setq alert-default-style 'notifier))) + +(defun slack/post-init-emoji-cheat-sheet-plus () + (add-hook 'slack-mode-hook 'emoji-cheat-sheet-plus-display-mode)) + +(defun slack/post-init-flyspell () + (add-hook 'lui-mode-hook 'flyspell-mode)) + +(defun slack/post-init-linum () + (add-hook 'slack-mode-hook 'spacemacs/no-linum)) + +(defun slack/post-init-persp-mode () + (spacemacs|define-custom-layout "@Slack" + :binding "s" + :body + (progn + (add-hook 'slack-mode #'(lambda () + (persp-add-buffer (current-buffer)))) + ;; TODO: We don't want to slack-start every time someone types ` l o s` + (call-interactively 'slack-start) + (call-interactively 'slack-channel-select))) + ;; Do not save slack buffers + (spacemacs|use-package-add-hook persp-mode + :post-config + (push (lambda (b) (with-current-buffer b (eq major-mode 'slack-mode))) + persp-filter-save-buffers-functions))) + +(defun slack/init-slack () + "Initialize Slack" + (use-package slack + :commands (slack-start) + :defer t + :init + (progn + (spacemacs/set-leader-keys + "aCs" 'slack-start + "aCj" 'slack-channel-select + "aCd" 'slack-im-select + "aCq" 'slack-ws-close) + (setq slack-enable-emoji t)) + :config + (progn + (spacemacs/set-leader-keys-for-major-mode 'slack-mode + "j" 'slack-channel-select + "d" 'slack-im-select + "p" 'slack-room-load-prev-messages + "e" 'slack-message-edit + "q" 'slack-ws-close + "mm" 'slack-message-embed-mention + "mc" 'slack-message-embed-channel + "k" 'slack-channel-select + "@" 'slack-message-embed-mention + "#" 'slack-message-embed-channel) + (evil-define-key 'insert slack-mode-map + (kbd "@") 'slack-message-embed-mention + (kbd "#") 'slack-message-embed-channel)))) + +;;; packages.el ends here diff --git a/layers/+checkers/spell-checking/README.org b/layers/+checkers/spell-checking/README.org new file mode 100644 index 0000000..96b5560 --- /dev/null +++ b/layers/+checkers/spell-checking/README.org @@ -0,0 +1,99 @@ +#+TITLE: Spell Checking layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#spell-checker-configuration][Spell Checker Configuration]] + - [[#disabling-by-default][Disabling by default]] + - [[#enabling-auto-dictionary-mode][Enabling auto-dictionary-mode]] + - [[#enable-auto-completion-popup][Enable auto-completion popup]] + - [[#key-bindings][Key Bindings]] + +* Description +This layer provides spell checking using [[http://www-sop.inria.fr/members/Manuel.Serrano/flyspell/flyspell.html][Flyspell]] and [[https://github.com/nschum/auto-dictionary-mode][auto-dictionary-mode]]. + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =spell-checking= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Spell Checker Configuration +The built-in Emacs variable that controls which external spell-checking program +is used is =ispell-program-name=, which can be set in your +=dotspacemacs/user-init= function if you do not like the default. It will give +priority to =aspell= if it is installed on your system. Another important +variable to be aware of is =ispell-dictionary= which will control the default +dictionary used by =ispell-program-name= (instead of using this variable you can +also use the key binding ~SPC S d~). + +** Disabling by default +By default, =spell-checking= is enabled in all available major modes and may be +toggled off with ~SPC t S~. You can default this to off by setting the variable +=spell-checking-enable-by-default= to =nil=: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers + '((spell-checking :variables spell-checking-enable-by-default nil))) +#+END_SRC + +** Enabling auto-dictionary-mode +=auto-dictionary-mode= tries to detect the current language from the buffer +content, and activate the corresponding dictionary. You can enable it by setting +the variable =spell-checking-enable-auto-dictionary= to something other than +=nil=: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers + '((spell-checking :variables spell-checking-enable-auto-dictionary t))) +#+END_SRC + +Some people encountered bugs with =auto-dictionary-mode=, especially in *daemon +mode* where new =emacsclient= open directly freezed. If so, no other workaround +have been found yet than disabling =auto-dictionary-mode= completely. + +Not all languages are supported by =auto-dictionary-list=. The supported +languages are listed in the =adict-language-list= variable, that can be checked +with =spacemacs/describe-variable=. For convenience, here is the list of +currently supported language: + +| Language | +|-------------------| +| catalan | +| classical greek | +| danish | +| english | +| esperanto | +| french | +| german | +| hindi | +| hungarian | +| modern greek | +| norwegian bokmål | +| norwegian nynorsk | +| portuguese | +| romanian | +| slovak | +| slovene | +| spanish | +| swedish | + +** Enable auto-completion popup +To enable auto-completion popup when the point is idle on a misspelled word +set the layer variable =enable-flyspell-auto-completion= to t: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers + '((spell-checking :variables =enable-flyspell-auto-completion= t))) +#+END_SRC + +* Key Bindings + +| Key Binding | Description | +|-------------+--------------------------| +| ~SPC S b~ | flyspell whole buffer | +| ~SPC S c~ | flyspell correct | +| ~SPC S d~ | change dictionary | +| ~SPC S n~ | flyspell goto next error | +| ~SPC t S~ | toggle flyspell | diff --git a/layers/+checkers/spell-checking/config.el b/layers/+checkers/spell-checking/config.el new file mode 100644 index 0000000..96664d2 --- /dev/null +++ b/layers/+checkers/spell-checking/config.el @@ -0,0 +1,19 @@ +;;; config.el --- Spell Checking Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar spell-checking-enable-by-default t + "Enable spell checking by default.") + +(defvar spell-checking-enable-auto-dictionary nil + "Specify if auto-dictionary should be enabled or not.") + +(defvar enable-flyspell-auto-completion nil + "If not nil, show speeling suggestions in popups.") diff --git a/layers/+checkers/spell-checking/funcs.el b/layers/+checkers/spell-checking/funcs.el new file mode 100644 index 0000000..cf8a36c --- /dev/null +++ b/layers/+checkers/spell-checking/funcs.el @@ -0,0 +1,24 @@ +;;; funcs.el --- Spell Checking Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spell-checking/add-flyspell-hook (hook) + "Add `flyspell-mode' to the given HOOK, if +`spell-checking-enable-by-default' is true." + (when spell-checking-enable-by-default + (add-hook hook 'flyspell-mode))) + +(defun spell-checking/change-dictionary () + "Change the dictionary. Use the ispell version if +auto-dictionary is not used, use the adict version otherwise." + (interactive) + (if (fboundp 'adict-change-dictionary) + (adict-change-dictionary) + (call-interactively 'ispell-change-dictionary))) diff --git a/layers/+checkers/spell-checking/packages.el b/layers/+checkers/spell-checking/packages.el new file mode 100644 index 0000000..f103430 --- /dev/null +++ b/layers/+checkers/spell-checking/packages.el @@ -0,0 +1,92 @@ +;;; packages.el --- Spell Checking Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq spell-checking-packages + '( + auto-dictionary + flyspell + flyspell-correct + (flyspell-correct-ivy :toggle (configuration-layer/layer-usedp 'ivy)) + (flyspell-correct-helm :toggle (configuration-layer/layer-usedp 'helm)) + (flyspell-correct-popup :toggle (and (not (configuration-layer/layer-usedp 'ivy)) + (not (configuration-layer/layer-usedp 'helm)))) + (flyspell-popup :toggle enable-flyspell-auto-completion))) + +(defun spell-checking/init-auto-dictionary () + (use-package auto-dictionary + :defer t + :if spell-checking-enable-auto-dictionary + :init + (progn + (add-hook 'flyspell-mode-hook 'auto-dictionary-mode) + ;; Select the buffer local dictionary if it was set, otherwise + ;; auto-dictionary will replace it with a guessed one at each activation. + ;; https://github.com/nschum/auto-dictionary-mode/issues/5 + (defun spacemacs//adict-set-local-dictionary () + "Set the local dictionary if not nil." + (when (and (fboundp 'adict-change-dictionary) + ispell-local-dictionary) + (adict-change-dictionary ispell-local-dictionary))) + (add-hook 'auto-dictionary-mode-hook + 'spacemacs//adict-set-local-dictionary 'append)))) + +(defun spell-checking/init-flyspell () + (use-package flyspell + :defer t + :commands (spell-checking/change-dictionary) + :init + (progn + (spell-checking/add-flyspell-hook 'text-mode-hook) + (when spell-checking-enable-by-default + (add-hook 'prog-mode-hook 'flyspell-prog-mode)) + + (spacemacs|add-toggle spelling-checking + :status flyspell-mode + :on (if (derived-mode-p 'prog-mode) + (flyspell-prog-mode) + (flyspell-mode)) + :off (progn + (flyspell-mode-off) + ;; Also disable auto-dictionary when disabling spell-checking. + (when (fboundp 'auto-dictionary-mode) (auto-dictionary-mode -1))) + :documentation "Enable automatic spell checking." + :evil-leader "tS") + + (spacemacs/declare-prefix "S" "spelling") + (spacemacs/set-leader-keys + "Sb" 'flyspell-buffer + "Sd" 'spell-checking/change-dictionary + "Sn" 'flyspell-goto-next-error)) + :config (spacemacs|diminish flyspell-mode " Ⓢ" " S"))) + +(defun spell-checking/init-flyspell-correct () + (use-package flyspell-correct + :commands (flyspell-correct-word-generic + flyspell-correct-previous-word-generic) + :init + (spacemacs/set-leader-keys "Sc" 'flyspell-correct-previous-word-generic))) + +(defun spell-checking/init-flyspell-correct-ivy () + (use-package flyspell-correct-ivy)) + +(defun spell-checking/init-flyspell-correct-helm () + (use-package flyspell-correct-helm)) + +(defun spell-checking/init-flyspell-correct-popup () + (use-package flyspell-correct-popup)) + +(defun spell-checking/init-flyspell-popup () + (use-package flyspell-popup + :defer t + :init + (progn + (setq flyspell-popup-correct-delay 0.8) + (add-hook 'flyspell-mode-hook 'flyspell-popup-auto-correct-mode)))) diff --git a/layers/+checkers/syntax-checking/README.org b/layers/+checkers/syntax-checking/README.org new file mode 100644 index 0000000..a4c9aa6 --- /dev/null +++ b/layers/+checkers/syntax-checking/README.org @@ -0,0 +1,68 @@ +#+TITLE: Syntax Checking layer + +[[file:img/flycheck.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#enablingdisabling-tooltips][Enabling/Disabling tooltips]] + - [[#disabling-by-default][Disabling by default]] + - [[#bitmaps][Bitmaps]] + - [[#key-bindings][Key Bindings]] + +* Description +This layer provides on the fly syntax checking using [[http://www.flycheck.org/][Flycheck]]. + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =syntax-checking= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Enabling/Disabling tooltips +By default tooltips are enabled and used whenever it is possible. +You can disable them by setting the variable =syntax-checking-enable-tooltips= +to =nil=: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers + '((syntax-checking :variables syntax-checking-enable-tooltips nil))) +#+END_SRC + +** Disabling by default +By default, syntax-checking is enabled in all available major modes and may be +toggled off with ~SPC t s~. You can default this to off by setting the variable +=syntax-checking-enable-by-default= to =nil=: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers + '((syntax-checking :variables syntax-checking-enable-by-default nil))) +#+END_SRC + +If you want more fine-grained control, you can configure the variable +=flycheck-global-modes= instead. Note that this variable should be manipulated +in =dotspacemacs/user-config=. + +** Bitmaps +If the original flycheck fringe bitmaps are more to your liking, you can set the +variable =syntax-checking-use-original-bitmaps= to =t=: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers + '((syntax-checking :variables syntax-checking-use-original-bitmaps t))) +#+END_SRC + +* Key Bindings + +| Key Binding | Description | +|-------------+--------------------------------------------------------------| +| ~SPC e c~ | clear errors | +| ~SPC e h~ | describe flycheck checker | +| ~SPC e l~ | display a list of all the errors | +| ~SPC e L~ | display a list of all the errors and focus the errors buffer | +| ~SPC e e~ | explain the error at point | +| ~SPC e s~ | set flycheck checker | +| ~SPC e S~ | set flycheck checker executable | +| ~SPC e v~ | verify flycheck setup | +| ~SPC t s~ | toggle flycheck | diff --git a/layers/+checkers/syntax-checking/config.el b/layers/+checkers/syntax-checking/config.el new file mode 100644 index 0000000..65c495e --- /dev/null +++ b/layers/+checkers/syntax-checking/config.el @@ -0,0 +1,24 @@ +;;; config.el --- Syntax Checking Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(defvar syntax-checking-enable-tooltips t + "If non nil some feedback are displayed in tooltips.") + +(defvar syntax-checking-enable-by-default t + "Enable syntax-checking by default.") + +(defvar syntax-checking-use-original-bitmaps nil + "If non-nil, use the original bitmaps from flycheck.") + +;; Command Prefixes + diff --git a/layers/+checkers/syntax-checking/funcs.el b/layers/+checkers/syntax-checking/funcs.el new file mode 100644 index 0000000..be0f54b --- /dev/null +++ b/layers/+checkers/syntax-checking/funcs.el @@ -0,0 +1,18 @@ +;;; funcs.el --- Syntax Checking Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spacemacs/add-flycheck-hook (mode) + "Use flycheck in MODE by default, if `syntax-checking-enable-by-default' is +true." + (when (and syntax-checking-enable-by-default + (listp flycheck-global-modes) + (not (eq 'not (car flycheck-global-modes)))) + (push mode flycheck-global-modes))) diff --git a/layers/+checkers/syntax-checking/img/flycheck.png b/layers/+checkers/syntax-checking/img/flycheck.png new file mode 100644 index 0000000..baa06a3 Binary files /dev/null and b/layers/+checkers/syntax-checking/img/flycheck.png differ diff --git a/layers/+checkers/syntax-checking/packages.el b/layers/+checkers/syntax-checking/packages.el new file mode 100644 index 0000000..874fade --- /dev/null +++ b/layers/+checkers/syntax-checking/packages.el @@ -0,0 +1,127 @@ +;;; packages.el --- Syntax Checking Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq syntax-checking-packages + '( + flycheck + flycheck-pos-tip + popwin + )) + +(defun syntax-checking/init-flycheck () + (use-package flycheck + :defer t + :init + (progn + (setq flycheck-standard-error-navigation nil + flycheck-global-modes nil) + + (spacemacs|add-toggle syntax-checking + :mode flycheck-mode + :documentation "Enable error and syntax checking." + :evil-leader "ts") + + (spacemacs|diminish flycheck-mode " ⓢ" " s") + + (when syntax-checking-enable-by-default + (global-flycheck-mode 1)) + + ;; Custom fringe indicator + (when (and (fboundp 'define-fringe-bitmap) + (not syntax-checking-use-original-bitmaps)) + (define-fringe-bitmap 'my-flycheck-fringe-indicator + (vector #b00000000 + #b00000000 + #b00000000 + #b00000000 + #b00000000 + #b00000000 + #b00000000 + #b00011100 + #b00111110 + #b00111110 + #b00111110 + #b00011100 + #b00000000 + #b00000000 + #b00000000 + #b00000000 + #b00000000))) + + (let ((bitmap (if syntax-checking-use-original-bitmaps + 'flycheck-fringe-bitmap-double-arrow + 'my-flycheck-fringe-indicator))) + (flycheck-define-error-level 'error + :severity 2 + :overlay-category 'flycheck-error-overlay + :fringe-bitmap bitmap + :fringe-face 'flycheck-fringe-error) + (flycheck-define-error-level 'warning + :severity 1 + :overlay-category 'flycheck-warning-overlay + :fringe-bitmap bitmap + :fringe-face 'flycheck-fringe-warning) + (flycheck-define-error-level 'info + :severity 0 + :overlay-category 'flycheck-info-overlay + :fringe-bitmap bitmap + :fringe-face 'flycheck-fringe-info)) + + ;; toggle flycheck window + (defun spacemacs/toggle-flycheck-error-list () + "Toggle flycheck's error list window. +If the error list is visible, hide it. Otherwise, show it." + (interactive) + (-if-let (window (flycheck-get-error-list-window)) + (quit-window nil window) + (flycheck-list-errors))) + + (defun spacemacs/goto-flycheck-error-list () + "Open and go to the error list buffer." + (interactive) + (unless (get-buffer-window (get-buffer flycheck-error-list-buffer)) + (flycheck-list-errors) + (switch-to-buffer-other-window flycheck-error-list-buffer))) + + (evilified-state-evilify-map flycheck-error-list-mode-map + :mode flycheck-error-list-mode + :bindings + "RET" 'flycheck-error-list-goto-error + "j" 'flycheck-error-list-next-error + "k" 'flycheck-error-list-previous-error) + + ;; key bindings + (spacemacs/set-leader-keys + "ec" 'flycheck-clear + "eh" 'flycheck-describe-checker + "el" 'spacemacs/toggle-flycheck-error-list + "eL" 'spacemacs/goto-flycheck-error-list + "ee" 'flycheck-explain-error-at-point + "es" 'flycheck-select-checker + "eS" 'flycheck-set-checker-executable + "ev" 'flycheck-verify-setup)))) + +(defun syntax-checking/init-flycheck-pos-tip () + (use-package flycheck-pos-tip + :if syntax-checking-enable-tooltips + :defer t + :init + (with-eval-after-load 'flycheck + (flycheck-pos-tip-mode)))) + +(defun syntax-checking/post-init-popwin () + (push '("^\\*Flycheck.+\\*$" + :regexp t + :dedicated t + :position bottom + :stick t + :noselect t) + popwin:special-display-config)) diff --git a/layers/+completion/auto-completion/README.org b/layers/+completion/auto-completion/README.org new file mode 100644 index 0000000..0b46a63 --- /dev/null +++ b/layers/+completion/auto-completion/README.org @@ -0,0 +1,256 @@ +#+TITLE: Auto-completion layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#configuration][Configuration]] + - [[#key-bindings][Key bindings]] + - [[#snippets-directories][Snippets directories]] + - [[#show-snippets-in-auto-completion-popup][Show snippets in auto-completion popup]] + - [[#tooltips][Tooltips]] + - [[#sort-results-by-usage][Sort results by usage]] + - [[#enable-company-or-auto-complete-globally][Enable company or auto-complete globally]] + - [[#replacing-company-by-auto-complete][Replacing company by auto-complete]] + - [[#add-auto-completion-in-a-layer][Add auto-completion in a layer]] + - [[#in-configel][In =config.el=]] + - [[#in-packagesel][In =packages.el=]] + - [[#completion-back-ends][Completion back ends]] + - [[#improved-faces][Improved faces]] + - [[#key-bindings-1][Key Bindings]] + - [[#company][Company]] + - [[#auto-complete][Auto-complete]] + - [[#yasnippet][Yasnippet]] + - [[#auto-yasnippet][Auto-yasnippet]] + +* Description +This layer provides auto-completion to Spacemacs. + +The following completion engines are supported: +- [[http://company-mode.github.io/][company]] +- [[http://auto-complete.org/][auto-complete]] + +Snippets are supported via [[https://github.com/capitaomorte/yasnippet][yasnippet]] and [[https://github.com/abo-abo/auto-yasnippet][auto-yasnippet]]. + +This layer also configures =hippie-expand=. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =auto-completion= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Configuration +** Key bindings +You can customize the user experience of auto-completion with the following +layer variables: + +1. =auto-completion-return-key-behavior= set the action to perform when the + ~RET~ key is pressed, the possible values are: + - =complete= completes with the current selection + - =nil= does nothing + +2. =auto-completion-tab-key-behavior= set the action to perform when the ~TAB~ + key is pressed, the possible values are: + - =complete= completes with the current selection + - =cycle= completes the common prefix and cycle between candidates + - =nil= does nothing + +3. =auto-completion-complete-with-key-sequence= is a string of two characters + denoting a key sequence that will perform a =complete= action if the sequence + as been entered quickly enough. If its value is =nil= then the feature is + disabled. + +4. =auto-completion-complete-with-key-sequence-delay= is the number of seconds + to wait for the auto-completion key sequence to be entered. The default value + is 0.1 seconds. + +The default configuration of the layer is: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers '( + (auto-completion :variables + auto-completion-return-key-behavior 'complete + auto-completion-tab-key-behavior 'cycle + auto-completion-complete-with-key-sequence nil + auto-completion-complete-with-key-sequence-delay 0.1 + auto-completion-private-snippets-directory nil) + )) +#+END_SRC + +~jk~ is a good candidate for =auto-completion-complete-with-key-sequence= if +you don't use it already. + +** Snippets directories +The following directories are added by default: +- ~/.emacs.d/elpa/yasnippet-xxxxx/snippets +- ~/.emacs.d/layers/auto-completion/snippets +- ~/.emacs.d/private/snippets (conditional to the value of =auto-completion-private-snippets-directory=) +- ~/.spacemacs.d/snippets (conditional to the existence of =~/.spacemacs.d= directory) + +You can provide additional directories by setting the variable +=auto-completion-private-snippets-directory= which can take a string in case of +a single path or a list of paths. +If its value is =nil= then the path =~/.emacs.d/private/snippets= is used. + +** Show snippets in auto-completion popup +By default, snippets are not shown in the auto-completion popup. To show them in +the popup, set the variable =auto-completion-enable-snippets-in-popup= to =t=. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers + '((auto-completion :variables + auto-completion-enable-snippets-in-popup t))) +#+END_SRC + +** Tooltips +To enable automatic docstring tooltips set =auto-completion-enable-help-tooltip= +to =t=. + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers + '((auto-completion :variables + auto-completion-enable-help-tooltip t))) +#+END_SRC + +To enable manual non-automatic invocation of docstring tooltips, set it to +=manual=. The tooltip can be invoked manually by pressing ~M-h~. + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers + '((auto-completion :variables + auto-completion-enable-help-tooltip 'manual))) +#+END_SRC + +** Sort results by usage +To enable sorting auto-completion results by their usage frequency set +=auto-completion-enable-sort-by-usage= to =t=. +This feature is provided by the [[https://github.com/company-mode/company-statistics][company-statistics]] package when =company= +is used. +The variable has no effect when =auto-complete= is used. + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers + '((auto-completion :variables + auto-completion-enable-sort-by-usage t))) +#+END_SRC + +** Enable company or auto-complete globally +By default Spacemacs enables auto-completion explicitly for each supported +major-mode, it means that =company= and =auto-complete= are not enabled +globally, it allows more flexibility to choose an auto-completion engine +for a given mode. + +You may want to enable company globally to get auto-completion +everywhere even in the modes which are not configured by Spacemacs. To do +so, you just have to add =(global-company-mode)= in the +=dotspacemacs/user -config= function of your dotfile. + +Note that if you want to enable =auto-complete= globally you will have to +disable =company= first, see the next section to do so. + +** Replacing company by auto-complete +You can disable =company= by adding it to the =dotspacemacs-excluded-packages= +variable, then you are free to enable =auto-complete= globally. + +** Add auto-completion in a layer +Here is an example to add =company= auto-completion to python buffer: + +*** In =config.el= +#+BEGIN_SRC emacs-lisp + ;; Define the buffer local company backend variable + (spacemacs|defvar-company-backends python-mode) +#+END_SRC + +*** In =packages.el= +#+BEGIN_SRC emacs-lisp + ;; Add the relevant packages to the layer + (setq python-packages + '(... + company + (company-anaconda :toggle (configuration-layer/package-usedp 'company)) + ...)) + + ;; Hook company to python-mode + (defun python/post-init-company () + (spacemacs|add-company-hook python-mode)) + + ;; Add the backend to the major-mode specific backend list + (defun python/init-company-anaconda () + (use-package company-anaconda + :defer t + :init (push 'company-anaconda company-backends-python-mode))) +#+END_SRC + +** Completion back ends +Many spacemacs layers (e.g., python, html, haskell) configure company mode +backends to provide mode-specific completion. These modes will include +completion backends specified in the `spacemacs-default-company-backends` +variable. The defaults should work well, but you can configure this variable in +your ~.spacemacs~ file with (e.g.) +#+BEGIN_SRC emacs-lisp + (setq-default + dotspacemacs-configuration-layers + '((auto-completion :variables + spacemacs-default-company-backends '(company-files company-capf)))) +#+END_SRC + +** Improved faces +For nicer-looking faces, try adding the following to `custom-set-faces` in your dotspacemacs file. + +#+BEGIN_SRC emacs-lisp +(custom-set-faces + '(company-tooltip-common + ((t (:inherit company-tooltip :weight bold :underline nil)))) + '(company-tooltip-common-selection + ((t (:inherit company-tooltip-selection :weight bold :underline nil))))) +#+END_SRC + +* Key Bindings +** Company + +| Key Binding | Description | +|-------------+------------------------------------------------------------------------------------------------------| +| ~C-d~ | open minibuffer with documentation of thing at point in company dropdown | +| ~C-/~ | show candidates in Helm (for fuzzy searching) | +| ~C-M-/~ | filter the company dropdown menu | +| ~M-h~ | show current candidate's documentation in a tooltip (requires =auto-completion-enable-help-tooltip=) | + +Vim Style: + +| Key Binding | Description | +|-------------+----------------------------------------------| +| ~C-j~ | (vim style) go down in company dropdown menu | +| ~C-k~ | (vim style) go up in company dropdown menu | +| ~C-l~ | (vim style) complete selection | + +Emacs style: + +| Key Binding | Description | +|-------------+------------------------------------------------| +| ~C-f~ | (emacs style) complete selection | +| ~C-n~ | (emacs style) go down in company dropdown menu | +| ~C-p~ | (emacs style) go up in company dropdown menu | + +** Auto-complete + +| Key Binding | Description | +|-------------+----------------------------------------------------------------------| +| ~C-j~ | select next candidate | +| ~C-k~ | select previous candidate | +| ~TAB~ | expand selection or select next candidate | +| ~S-TAB~ | select previous candidate | +| ~return~ | complete word, if word is already completed insert a carriage return | + +** Yasnippet + +| Key Binding | Description | +|-------------+----------------------------------------------------------------| +| ~M-/~ | Expand a snippet if text before point is a prefix of a snippet | +| ~SPC i s~ | List all current yasnippets for inserting | + +** Auto-yasnippet + +| Key Binding | Description | +|-------------+---------------------------------------------------------------------------| +| ~SPC i S c~ | create a snippet from an active region | +| ~SPC i S e~ | Expand the snippet just created with ~SPC i y~ | +| ~SPC i S w~ | Write the snippet inside =private/snippets= directory for future sessions | diff --git a/layers/+completion/auto-completion/config.el b/layers/+completion/auto-completion/config.el new file mode 100644 index 0000000..6e63c8e --- /dev/null +++ b/layers/+completion/auto-completion/config.el @@ -0,0 +1,53 @@ +;;; config.el --- Auto-completion configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Company ------------------------------------------------------------------- + +(defvar-local auto-completion-front-end 'company + "Which auto-completion front end to use.") + +(defvar auto-completion-return-key-behavior 'complete + "What the RET key should do when auto-completion menu is active. +Possible values are `complete' or `nil'.") + +(defvar auto-completion-tab-key-behavior 'cycle + "What the TAB key should do when auto-completion menu is active. +Possible values are `complete', `cycle' or `nil'.") + +(defvar auto-completion-complete-with-key-sequence nil + "Provide a key sequence (string) to complete the current +selection.") + +(defvar auto-completion-complete-with-key-sequence-delay 0.1 + "Timeout (seconds) when waiting for the second key of +`auto-completion-complete-with-key-sequence'.") + +(defvar auto-completion-enable-snippets-in-popup nil + "If non nil show snippets in the auto-completion popup.") + +(defvar auto-completion-enable-sort-by-usage nil + "If non nil suggestions are sorted by how often they are used.") + +(defvar auto-completion-enable-help-tooltip nil + "If non nil the docstring appears in a tooltip. +If set to `manual', help tooltip appears only when invoked +manually.") + +(defvar company-mode-completion-cancel-keywords + '("do" + "then" + "begin" + "case") + "Keywords on which to cancel completion so that you can use RET +to complet without blocking common line endings.") + +(defvar auto-completion-private-snippets-directory nil + "Configurable private snippets directory.") diff --git a/layers/+completion/auto-completion/funcs.el b/layers/+completion/auto-completion/funcs.el new file mode 100644 index 0000000..ceb2cea --- /dev/null +++ b/layers/+completion/auto-completion/funcs.el @@ -0,0 +1,271 @@ +;;; funcs.el --- Auto-completion functions File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + + +(spacemacs|add-toggle auto-completion + :status + (if (eq 'company auto-completion-front-end) + (bound-and-true-p company-mode) + (bound-and-true-p auto-complete-mode)) + :on + (progn + (if (eq 'company auto-completion-front-end) + (company-mode) + (auto-complete-mode)) + (message "Enabled auto-completion (using %S)." + auto-completion-front-end)) + :off + (progn + (if (eq 'company auto-completion-front-end) + (company-mode -1) + (auto-complete-mode -1)) + (message "Disabled auto-completion.")) + :documentation "Enable auto-completion." + :evil-leader "ta") + + +;; auto-completion key bindings functions + +(defun spacemacs//auto-completion-set-RET-key-behavior (package) + "Bind RET key appropriately for the given PACKAGE and value of +`auto-completion-return-key-behavior'." + (cond + ((eq 'company package) + (let ((map company-active-map)) + (cond + ((eq 'complete auto-completion-return-key-behavior) + (define-key map [return] 'company-complete-selection) + (define-key map (kbd "RET") 'company-complete-selection)) + (t + (define-key map [return] 'nil) + (define-key map (kbd "RET") 'nil))))) + (t (message "Not yet implemented for package %S" package)))) + +(defun spacemacs//auto-completion-set-TAB-key-behavior (package) + "Bind TAB key appropriately for the given PACKAGE and value of +`auto-completion-tab-key-behavior'." + (cond + ((eq 'company package) + (let ((map company-active-map)) + (cond + ((eq 'complete auto-completion-tab-key-behavior) + (define-key map (kbd "TAB") 'company-complete-selection) + (define-key map (kbd "") 'company-complete-selection)) + ((eq 'cycle auto-completion-tab-key-behavior) + (define-key map (kbd "TAB") 'company-complete-common-or-cycle) + (define-key map (kbd "") 'company-complete-common-or-cycle) + (define-key map (kbd "") + 'spacemacs//company-complete-common-or-cycle-backward) + (define-key map (kbd "") + 'spacemacs//company-complete-common-or-cycle-backward)) + (t + (define-key map (kbd "TAB") nil) + (define-key map (kbd "") nil))))) + (t (message "Not yet implemented for package %S" package)))) + +(defun spacemacs//auto-completion-setup-key-sequence (package) + "Setup the key sequence to complete current selection." + (when auto-completion-complete-with-key-sequence + (let ((first-key (elt auto-completion-complete-with-key-sequence 0))) + (cond ((eq 'company package) + (define-key company-active-map (kbd (char-to-string first-key)) + 'spacemacs//auto-completion-key-sequence-start)) + (t (message "Not yet implemented for package %S" package)))))) + + +;; key sequence to complete selection + +(defvar spacemacs--auto-completion-time nil) +(defvar spacemacs--auto-completion-complete-last-candidate nil) +(defvar spacemacs--auto-completion-shadowed-insert-binding nil) +(defvar spacemacs--auto-completion-shadowed-emacs-binding nil) +(defvar spacemacs--auto-completion-shadowed-hybrid-binding nil) + +(defun spacemacs//auto-completion-key-sequence-start () + "Initiate auto-completion sequence." + (interactive) + (self-insert-command 1) + (setq spacemacs--auto-completion-complete-last-candidate + (cond + ((bound-and-true-p company-mode) + (nth company-selection company-candidates)))) + ;; enable second key of the sequence + (let ((second-key (kbd (char-to-string + (elt auto-completion-complete-with-key-sequence 1))))) + (setq spacemacs--auto-completion-shadowed-insert-binding + (lookup-key evil-insert-state-map second-key)) + (setq spacemacs--auto-completion-shadowed-emacs-binding + (lookup-key evil-emacs-state-map second-key)) + (setq spacemacs--auto-completion-shadowed-hybrid-binding + (lookup-key evil-hybrid-state-map second-key)) + (define-key + evil-insert-state-map + second-key + 'spacemacs//auto-completion-key-sequence-end) + (define-key + evil-emacs-state-map + second-key + 'spacemacs//auto-completion-key-sequence-end) + (define-key + evil-hybrid-state-map + second-key + 'spacemacs//auto-completion-key-sequence-end)) + ;; set a timer to restore the old bindings + (run-at-time auto-completion-complete-with-key-sequence-delay + nil + 'spacemacs//auto-completion-key-sequence-restore) + (when spacemacs--auto-completion-complete-last-candidate + (setq spacemacs--auto-completion-time (current-time)))) + +(defun spacemacs//auto-completion-key-sequence-end () + "Check if the auto-completion key sequence has been entered." + (interactive) + (if (or (null spacemacs--auto-completion-time) + (< auto-completion-complete-with-key-sequence-delay + (float-time (time-since spacemacs--auto-completion-time)))) + (self-insert-command 1) + (cond + ((bound-and-true-p company-mode) + (unless company-candidates + ;; if the auto-completion menu is still active then we don't need to + ;; delete the last inserted first key of the sequence + (delete-char -1)) + (let ((company-idle-delay)) + (company-auto-begin) + (company-finish spacemacs--auto-completion-complete-last-candidate))))) + (spacemacs//auto-completion-key-sequence-restore) + (setq spacemacs--auto-completion-time nil)) + +(defun spacemacs//auto-completion-key-sequence-restore () + "Restore the shadowed key bindings used to auto-complete." + (let ((second-key (kbd (char-to-string + (elt auto-completion-complete-with-key-sequence 1))))) + (define-key + evil-insert-state-map + second-key + spacemacs--auto-completion-shadowed-insert-binding) + (define-key + evil-emacs-state-map + second-key + spacemacs--auto-completion-shadowed-emacs-binding) + (define-key + evil-hybrid-state-map + second-key + spacemacs--auto-completion-shadowed-hybrid-binding))) + + +;; Editing style + +(defun spacemacs//company-active-navigation (style) + "Set navigation for the given editing STYLE." + (cond + ((or (eq 'vim style) + (and (eq 'hybrid style) + hybrid-mode-enable-hjkl-bindings)) + (let ((map company-active-map)) + (define-key map (kbd "C-j") 'company-select-next) + (define-key map (kbd "C-k") 'company-select-previous) + (define-key map (kbd "C-l") 'company-complete-selection)) + (when (require 'company-quickhelp nil 'noerror) + (evil-define-key 'insert company-quickhelp-mode-map (kbd "C-k") 'company-select-previous))) + (t + (let ((map company-active-map)) + (define-key map (kbd "C-n") 'company-select-next) + (define-key map (kbd "C-p") 'company-select-previous) + (define-key map (kbd "C-f") 'company-complete-selection))))) + + +;; Transformers + +(defun spacemacs//company-transformer-cancel (candidates) + "Cancel completion if prefix is in the list +`company-mode-completion-cancel-keywords'" + (unless (member company-prefix company-mode-completion-cancel-keywords) + candidates)) + + + +(defvar-local company-fci-mode-on-p nil) + +(defun company-turn-off-fci (&rest ignore) + (when (boundp 'fci-mode) + (setq company-fci-mode-on-p fci-mode) + (when fci-mode (fci-mode -1)))) + +(defun company-maybe-turn-on-fci (&rest ignore) + (when company-fci-mode-on-p (fci-mode 1))) + + +;; helm-yas + +(defun spacemacs/helm-yas () + "Properly lazy load helm-c-yasnipper." + (interactive) + (spacemacs/load-yasnippet) + (require 'helm-c-yasnippet) + (call-interactively 'helm-yas-complete)) + + +;; Yasnippet + +(defun spacemacs/load-yasnippet () + (unless yas-global-mode (yas-global-mode 1)) + (yas-minor-mode 1)) + +(defun spacemacs/force-yasnippet-off () + (yas-minor-mode -1) + (setq yas-dont-activate t)) + + +;; Auto-Yasnippet + +(defun spacemacs/auto-yasnippet-expand () + "Call `yas-expand' and switch to `insert state'" + (interactive) + (call-interactively 'aya-expand) + (unless holy-mode (evil-insert-state))) + + +;; Yasnippet and Smartparens + +;; If enabled, smartparens will mess snippets expanded by `hippie-expand`. +;; We want to temporarily disable Smartparens during the snippet expansion and +;; switch it back to the initial state when done. +;; +;; However, there is an asymmetry in Yasnippet's hooks: +;; * `yas-before-expand-snippet-hook' is called for all snippet expansions, +;; including the nested ones. +;; * `yas-after-exit-snippet-hook' is called only for the top level snippet, +;; but NOT for the nested ones. +;; +;; That's why we introduce `spacemacs--yasnippet-expanding' below. + +(defvar spacemacs--smartparens-enabled-initially t + "Stored whether smartparens is originally enabled or not.") +(defvar spacemacs--yasnippet-expanding nil + "Whether the snippet expansion is in progress.") + +(defun spacemacs//smartparens-disable-before-expand-snippet () + "Handler for `yas-before-expand-snippet-hook'. +Disable smartparens and remember its initial state." + ;; Remember the initial smartparens state only once, when expanding a top-level snippet. + (unless spacemacs--yasnippet-expanding + (setq spacemacs--yasnippet-expanding t + spacemacs--smartparens-enabled-initially smartparens-mode)) + (smartparens-mode -1)) + +(defun spacemacs//smartparens-restore-after-exit-snippet () + "Handler for `yas-after-exit-snippet-hook'. + Restore the initial state of smartparens." + (setq spacemacs--yasnippet-expanding nil) + (when spacemacs--smartparens-enabled-initially + (smartparens-mode 1))) diff --git a/layers/+completion/auto-completion/local/snippets/emacs-lisp-mode/.yas-parents b/layers/+completion/auto-completion/local/snippets/emacs-lisp-mode/.yas-parents new file mode 100644 index 0000000..75d003f --- /dev/null +++ b/layers/+completion/auto-completion/local/snippets/emacs-lisp-mode/.yas-parents @@ -0,0 +1 @@ +prog-mode diff --git a/layers/+completion/auto-completion/local/snippets/emacs-lisp-mode/.yas-setup.el b/layers/+completion/auto-completion/local/snippets/emacs-lisp-mode/.yas-setup.el new file mode 100644 index 0000000..fb3704d --- /dev/null +++ b/layers/+completion/auto-completion/local/snippets/emacs-lisp-mode/.yas-setup.el @@ -0,0 +1,6 @@ +(defun spacemacs/get-parent-dir () + (car (cdr ; Last item + (reverse + (split-string + (file-name-sans-extension (buffer-file-name)) + "/"))))) diff --git a/layers/+completion/auto-completion/local/snippets/emacs-lisp-mode/micro-state b/layers/+completion/auto-completion/local/snippets/emacs-lisp-mode/micro-state new file mode 100644 index 0000000..7b2b44a --- /dev/null +++ b/layers/+completion/auto-completion/local/snippets/emacs-lisp-mode/micro-state @@ -0,0 +1,12 @@ +# -*- mode: snippet; require-final-newline: nil -*- +# name: micro-state +# key: micro +# binding: direct-keybinding +# -- +(spacemacs|define-micro-state ${1:micro-state-name} + ${2::doc (spacemacs//$1-ms-documentation)} + ${3::use-minibuffer t} + ${4::evil-leader "${5:Leader-key}"} + :bindings + ${} + ) \ No newline at end of file diff --git a/layers/+completion/auto-completion/local/snippets/emacs-lisp-mode/new-package b/layers/+completion/auto-completion/local/snippets/emacs-lisp-mode/new-package new file mode 100644 index 0000000..f287727 --- /dev/null +++ b/layers/+completion/auto-completion/local/snippets/emacs-lisp-mode/new-package @@ -0,0 +1,15 @@ +# -*- mode: snippet; require-final-newline: nil -*- +# contributor: Diego Berrocal (cestdiego 4t gm4il d0t com) +# name: new-package +# key: newp +# binding: direct-keybinding +# -- +(defun `(spacemacs/get-parent-dir)`/init-${2:package-name} () + ${3:(use-package $2 + ${4::defer t + }${5::init + ${;; This block executes before the package has been loaded} + }${:config + ${;; This block executes after the package has been loaded} + })}) +$0 \ No newline at end of file diff --git a/layers/+completion/auto-completion/packages.el b/layers/+completion/auto-completion/packages.el new file mode 100644 index 0000000..5420240 --- /dev/null +++ b/layers/+completion/auto-completion/packages.el @@ -0,0 +1,253 @@ +;;; packages.el --- Auto-completion Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq auto-completion-packages + '( + auto-complete + ac-ispell + company + (company-quickhelp :toggle auto-completion-enable-help-tooltip) + company-statistics + (helm-company :toggle (configuration-layer/package-usedp 'helm)) + (helm-c-yasnippet :toggle (configuration-layer/package-usedp 'helm)) + hippie-exp + yasnippet + auto-yasnippet + smartparens + )) + +;; TODO replace by company-ispell which comes with company +;; to be moved to spell-checking layer as well +(defun auto-completion/init-ac-ispell () + (use-package ac-ispell + :defer t + :init + (progn + (setq ac-ispell-requires 4) + (with-eval-after-load 'auto-complete + (ac-ispell-setup)) + ;; (add-hook 'markdown-mode-hook 'ac-ispell-ac-setup) + ))) + +(defun auto-completion/init-auto-complete () + (use-package auto-complete + :defer t + :init + (setq ac-auto-start 0 + ac-delay 0.2 + ac-quick-help-delay 1. + ac-use-fuzzy t + ac-fuzzy-enable t + ac-comphist-file (concat spacemacs-cache-directory "ac-comphist.dat") + ;; use 'complete when auto-complete is disabled + tab-always-indent 'complete + ac-dwim t) + :config + (progn + (require 'auto-complete-config) + (setq-default ac-sources '(ac-source-abbrev + ac-source-dictionary + ac-source-words-in-same-mode-buffers)) + (when (configuration-layer/package-usedp 'yasnippet) + (push 'ac-source-yasnippet ac-sources)) + (add-to-list 'completion-styles 'initials t) + (define-key ac-completing-map (kbd "C-j") 'ac-next) + (define-key ac-completing-map (kbd "C-k") 'ac-previous) + (define-key ac-completing-map (kbd "") 'ac-previous) + (spacemacs|diminish auto-complete-mode " ⓐ" " a")))) + +(defun auto-completion/init-company () + (use-package company + :defer t + :init + (progn + (setq company-idle-delay 0.2 + company-minimum-prefix-length 2 + company-require-match nil + company-dabbrev-ignore-case nil + company-dabbrev-downcase nil) + + (add-hook 'company-completion-started-hook 'company-turn-off-fci) + (add-hook 'company-completion-finished-hook 'company-maybe-turn-on-fci) + (add-hook 'company-completion-cancelled-hook 'company-maybe-turn-on-fci)) + :config + (progn + (spacemacs|diminish company-mode " ⓐ" " a") + + ;; key bindings + (defun spacemacs//company-complete-common-or-cycle-backward () + "Complete common prefix or cycle backward." + (interactive) + (company-complete-common-or-cycle -1)) + (spacemacs//auto-completion-set-RET-key-behavior 'company) + (spacemacs//auto-completion-set-TAB-key-behavior 'company) + (spacemacs//auto-completion-setup-key-sequence 'company) + + (let ((map company-active-map)) + (define-key map (kbd "C-/") 'company-search-candidates) + (define-key map (kbd "C-M-/") 'company-filter-candidates) + (define-key map (kbd "C-d") 'company-show-doc-buffer)) + (add-hook 'spacemacs-editing-style-hook 'spacemacs//company-active-navigation) + ;; ensure that the correct bindings are set at startup + (spacemacs//company-active-navigation dotspacemacs-editing-style) + + (setq company-transformers '(spacemacs//company-transformer-cancel + company-sort-by-occurrence))))) + +(defun auto-completion/init-company-statistics () + (use-package company-statistics + :if auto-completion-enable-sort-by-usage + :defer t + :init + (progn + (setq company-statistics-file (concat spacemacs-cache-directory + "company-statistics-cache.el")) + (add-hook 'company-mode-hook 'company-statistics-mode)))) + +(defun auto-completion/init-company-quickhelp () + (use-package company-quickhelp + :commands company-quickhelp-manual-begin + :init + (spacemacs|do-after-display-system-init + (with-eval-after-load 'company + (setq company-frontends (delq 'company-echo-metadata-frontend company-frontends)) + (define-key company-active-map (kbd "M-h") #'company-quickhelp-manual-begin) + (unless (eq auto-completion-enable-help-tooltip 'manual) + (company-quickhelp-mode)))))) + +(defun auto-completion/init-helm-c-yasnippet () + (use-package helm-c-yasnippet + :defer t + :init + (progn + (spacemacs/set-leader-keys "is" 'spacemacs/helm-yas) + (setq helm-c-yas-space-match-any-greedy t)))) + +(defun auto-completion/init-helm-company () + (use-package helm-company + :if (configuration-layer/package-usedp 'company) + :defer t + :init + (with-eval-after-load 'company + (define-key company-active-map (kbd "C-/") 'helm-company)))) + +(defun auto-completion/init-hippie-exp () + ;; replace dabbrev-expand + (global-set-key (kbd "M-/") 'hippie-expand) + (define-key evil-insert-state-map [remap evil-complete-previous] 'hippie-expand) + (setq hippie-expand-try-functions-list + '( + ;; Try to expand word "dynamically", searching the current buffer. + try-expand-dabbrev + ;; Try to expand word "dynamically", searching all other buffers. + try-expand-dabbrev-all-buffers + ;; Try to expand word "dynamically", searching the kill ring. + try-expand-dabbrev-from-kill + ;; Try to complete text as a file name, as many characters as unique. + try-complete-file-name-partially + ;; Try to complete text as a file name. + try-complete-file-name + ;; Try to expand word before point according to all abbrev tables. + try-expand-all-abbrevs + ;; Try to complete the current line to an entire line in the buffer. + try-expand-list + ;; Try to complete the current line to an entire line in the buffer. + try-expand-line + ;; Try to complete as an Emacs Lisp symbol, as many characters as + ;; unique. + try-complete-lisp-symbol-partially + ;; Try to complete word as an Emacs Lisp symbol. + try-complete-lisp-symbol)) + (when (configuration-layer/package-usedp 'yasnippet) + ;; Try to expand yasnippet snippets based on prefix + (push 'yas-hippie-try-expand hippie-expand-try-functions-list))) + +(defun auto-completion/init-yasnippet () + (use-package yasnippet + :commands (yas-global-mode yas-minor-mode) + :init + (progn + ;; We don't want undefined variable errors + (defvar yas-global-mode nil) + (setq yas-triggers-in-field t + yas-wrap-around-region t + helm-yas-display-key-on-candidate t) + ;; on multiple keys, fall back to completing read + ;; typically this means helm + (setq yas-prompt-functions '(yas-completing-prompt)) + ;; disable yas minor mode map + ;; use hippie-expand instead + (setq yas-minor-mode-map (make-sparse-keymap)) + ;; this makes it easy to get out of a nested expansion + (define-key yas-minor-mode-map (kbd "M-s-/") 'yas-next-field) + ;; configure snippet directories + (let* ((spacemacs--auto-completion-dir + (configuration-layer/get-layer-local-dir 'auto-completion)) + (private-yas-dir (if auto-completion-private-snippets-directory + auto-completion-private-snippets-directory + (concat + configuration-layer-private-directory + "snippets/"))) + (spacemacs-layer-snippets-dir (expand-file-name + "snippets" + spacemacs--auto-completion-dir)) + (dotspacemacs-directory-snippets-dir (when dotspacemacs-directory + (expand-file-name + "snippets" + dotspacemacs-directory)))) + (setq yas-snippet-dirs nil) + ;; ~/.emacs.d/layers/auto-completion/snippets + (push spacemacs-layer-snippets-dir yas-snippet-dirs) + ;; ~/.emacs.d/elpa/yasnippet-xxxxx/snippets + (push 'yas-installed-snippets-dir yas-snippet-dirs) + ;; ~/.spacemacs.d/snippets + (when dotspacemacs-directory-snippets-dir + (push dotspacemacs-directory-snippets-dir yas-snippet-dirs)) + ;; arbitrary directories in `auto-completion-private-snippets-directory' + (when private-yas-dir + (if (listp private-yas-dir) + (setq yas-snippet-dirs (append yas-snippet-dirs private-yas-dir)) + (push private-yas-dir yas-snippet-dirs)))) + + (spacemacs/add-to-hooks 'spacemacs/load-yasnippet '(prog-mode-hook + markdown-mode-hook + org-mode-hook)) + (spacemacs|add-toggle yasnippet + :mode yas-minor-mode + :documentation "Enable snippets." + :evil-leader "ty") + + (spacemacs/add-to-hooks + 'spacemacs/force-yasnippet-off '(term-mode-hook + shell-mode-hook + eshell-mode-hook))) + :config (spacemacs|diminish yas-minor-mode " ⓨ" " y"))) + +(defun auto-completion/init-auto-yasnippet () + (use-package auto-yasnippet + :defer t + :init + (progn + (setq aya-persist-snippets-dir + (or auto-completion-private-snippets-directory + (concat configuration-layer-private-directory "snippets/"))) + (spacemacs/declare-prefix "iS" "auto-yasnippet") + (spacemacs/set-leader-keys + "iSc" 'aya-create + "iSe" 'spacemacs/auto-yasnippet-expand + "iSw" 'aya-persist-snippet)))) + +(defun auto-completion/post-init-smartparens () + (with-eval-after-load 'smartparens + (add-hook 'yas-before-expand-snippet-hook + #'spacemacs//smartparens-disable-before-expand-snippet) + (add-hook 'yas-after-exit-snippet-hook + #'spacemacs//smartparens-restore-after-exit-snippet))) diff --git a/layers/+completion/helm/funcs.el b/layers/+completion/helm/funcs.el new file mode 100644 index 0000000..65e8923 --- /dev/null +++ b/layers/+completion/helm/funcs.el @@ -0,0 +1,215 @@ +;;; funcs.el --- Helm Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + + +(defvar spacemacs--helm-popwin-mode nil + "Temp variable to store `popwin-mode''s value.") + +(defun spacemacs//helm-cleanup () + "Cleanup some helm related states when quitting." + ;; deactivate any running transient map (transient-state) + (setq overriding-terminal-local-map nil)) + +(defun spacemacs//helm-prepare-display () + "Prepare necessary settings to make Helm display properly." + (setq spacemacs-display-buffer-alist display-buffer-alist) + ;; the only buffer to display is Helm, nothing else we must set this + ;; otherwise Helm cannot reuse its own windows for copyinng/deleting + ;; etc... because of existing popwin buffers in the alist + (setq display-buffer-alist nil) + (setq spacemacs--helm-popwin-mode popwin-mode) + (when popwin-mode + (popwin-mode -1))) + +(defun spacemacs//helm-restore-display () + ;; we must enable popwin-mode first then restore `display-buffer-alist' + ;; Otherwise, popwin keeps adding up its own buffers to + ;; `display-buffer-alist' and could slow down Emacs as the list grows + (when spacemacs--helm-popwin-mode + (popwin-mode)) + (setq display-buffer-alist spacemacs-display-buffer-alist)) + + +;; REPLs integration + +(defun helm-available-repls () + "Show all the repls available." + (interactive) + (let ((helm-available-repls + `((name . "HELM available REPLs") + (candidates . ,(mapcar #'car spacemacs-repl-list)) + (action . (lambda (candidate) + (let ((repl (cdr (assoc candidate spacemacs-repl-list)))) + (require (car repl)) + (call-interactively (cdr repl)))))))) + (helm :sources '(helm-available-repls) + :buffer "*helm repls*"))) + + +;; Search tools integration + +(defun spacemacs//helm-do-grep-region-or-symbol + (&optional targs use-region-or-symbol-p) + "Version of `helm-do-grep' with a default input." + (interactive) + (require 'helm) + (cl-letf* + (((symbol-function 'this-fn) (symbol-function 'helm-do-grep-1)) + ((symbol-function 'helm-do-grep-1) + (lambda (targets &optional recurse zgrep exts + default-input region-or-symbol-p) + (let* ((new-input (when region-or-symbol-p + (if (region-active-p) + (buffer-substring-no-properties + (region-beginning) (region-end)) + (thing-at-point 'symbol t)))) + (quoted-input (when new-input + (rxt-quote-pcre new-input)))) + (this-fn targets recurse zgrep exts + default-input quoted-input)))) + (preselection (or (dired-get-filename nil t) + (buffer-file-name (current-buffer)))) + (targets (if targs + targs + (helm-read-file-name + "Search in file(s): " + :marked-candidates t + :preselect (if helm-ff-transformer-show-only-basename + (helm-basename preselection) + preselection))))) + (helm-do-grep-1 targets nil nil nil nil use-region-or-symbol-p))) + +(defun spacemacs/helm-file-do-grep () + "Search in current file with `grep' using a default input." + (interactive) + (spacemacs//helm-do-grep-region-or-symbol + (list (buffer-file-name (current-buffer))) nil)) + +(defun spacemacs/helm-file-do-grep-region-or-symbol () + "Search in current file with `grep' using a default input." + (interactive) + (spacemacs//helm-do-grep-region-or-symbol + (list (buffer-file-name (current-buffer))) t)) + +(defun spacemacs/helm-files-do-grep () + "Search in files with `grep'." + (interactive) + (spacemacs//helm-do-grep-region-or-symbol nil nil)) + +(defun spacemacs/helm-files-do-grep-region-or-symbol () + "Search in files with `grep' using a default input." + (interactive) + (spacemacs//helm-do-grep-region-or-symbol nil t)) + +(defun spacemacs/helm-buffers-do-grep () + "Search in opened buffers with `grep'." + (interactive) + (let ((buffers (cl-loop for buffer in (buffer-list) + when (buffer-file-name buffer) + collect (buffer-file-name buffer)))) + (spacemacs//helm-do-grep-region-or-symbol buffers nil))) + +(defun spacemacs/helm-buffers-do-grep-region-or-symbol () + "Search in opened buffers with `grep' with a default input." + (interactive) + (let ((buffers (cl-loop for buffer in (buffer-list) + when (buffer-file-name buffer) + collect (buffer-file-name buffer)))) + (spacemacs//helm-do-grep-region-or-symbol buffers t))) + +(defun spacemacs/resume-last-search-buffer () + "open last helm-ag or hgrep buffer." + (interactive) + (cond ((get-buffer "*helm ag results*") + (switch-to-buffer-other-window "*helm ag results*")) + ((get-buffer "*helm-ag*") + (helm-resume "*helm-ag*")) + ((get-buffer "*hgrep*") + (switch-to-buffer-other-window "*hgrep*")) + (t + (message "No previous search buffer found")))) + +(defun spacemacs/helm-find-files (arg) + "Custom spacemacs implementation for calling helm-find-files-1. +Removes the automatic guessing of the initial value based on thing at point. " + (interactive "P") + (let* ((hist (and arg helm-ff-history (helm-find-files-history))) + (default-input hist) + (input (cond ((and (eq major-mode 'dired-mode) default-input) + (file-name-directory default-input)) + ((and (not (string= default-input "")) + default-input)) + (t (expand-file-name (helm-current-directory)))))) + (set-text-properties 0 (length input) nil input) + (helm-find-files-1 input))) + + +;; Key bindings + +(defmacro spacemacs||set-helm-key (keys func) + "Define a key bindings for FUNC using KEYS. +Ensure that helm is required before calling FUNC." + (let ((func-name (intern (format "spacemacs/%s" (symbol-name func))))) + `(progn + (defun ,func-name () + ,(format "Wrapper to ensure that `helm' is loaded before calling %s." + (symbol-name func)) + (interactive) + (require 'helm) + (call-interactively ',func)) + (spacemacs/set-leader-keys ,keys ',func-name)))) + +(defun spacemacs//helm-find-files-edit (candidate) + "Opens a dired buffer and immediately switches to editable mode." + (dired (file-name-directory candidate)) + (dired-goto-file candidate) + (dired-toggle-read-only)) + +(defun spacemacs/helm-find-files-edit () + "Exits helm, opens a dired buffer and immediately switches to editable mode." + (interactive) + (helm-exit-and-execute-action 'spacemacs//helm-find-files-edit)) + +(defun spacemacs/helm-jump-in-buffer () + "Jump in buffer using `imenu' facilities and helm." + (interactive) + (call-interactively + (cond + ((eq major-mode 'org-mode) 'helm-org-in-buffer-headings) + (t 'helm-semantic-or-imenu)))) + + +;; Generalized next-error interface + +(defun spacemacs//gne-init-helm-ag (&rest args) + (with-current-buffer "*helm ag results*" + (setq spacemacs--gne-min-line 5 + spacemacs--gne-max-line (save-excursion + (goto-char (point-max)) + (previous-line) + (line-number-at-pos)) + spacemacs--gne-line-func + (lambda (c) + (helm-ag--find-file-action + c 'find-file helm-ag--search-this-file-p)) + next-error-function 'spacemacs/gne-next))) + +(defun spacemacs//gne-init-helm-grep (&rest args) + (with-current-buffer "*hgrep*" + (setq spacemacs--gne-min-line 5 + spacemacs--gne-max-line + (save-excursion + (goto-char (point-max)) + (previous-line) + (line-number-at-pos)) + spacemacs--gne-line-func 'helm-grep-action + next-error-function 'spacemacs/gne-next))) diff --git a/layers/+completion/helm/local/helm-spacemacs-help/helm-spacemacs-help.el b/layers/+completion/helm/local/helm-spacemacs-help/helm-spacemacs-help.el new file mode 100644 index 0000000..e4c5375 --- /dev/null +++ b/layers/+completion/helm/local/helm-spacemacs-help/helm-spacemacs-help.el @@ -0,0 +1,415 @@ +;;; helm-spacemacs-help.el --- Spacemacs layer exploration with `helm'. + +;; Author: Sylvain Benner +;; Keywords: helm, spacemacs +;; Version: 0.1 +;; Package-Requires: ((helm "1.5")) + +;; This file 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, or (at your option) +;; any later version. + +;; This file 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., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: +;; This package adds a convenient way to discover Spacemacs configuration +;; layers thanks to helm. + +;;; Code: + +(require 'cl) +(require 'ht) +(require 'helm) +(require 'helm-command) +(require 'helm-org) +(require 'core-configuration-layer) + +(defvar helm-spacemacs--initialized nil + "Non nil if helm-spacemacs is initialized.") + +;;;###autoload +(define-minor-mode helm-spacemacs-help-mode + "Layers discovery with helm interface." + :group 'spacemacs + :global t) + +(defun helm-spacemacs-help//init (&optional arg) + (when (or arg (null helm-spacemacs--initialized)) + (let ((configuration-layer--load-packages-files t) + (configuration-layer--package-properties-read-onlyp t) + (configuration-layer--inhibit-warnings t)) + (configuration-layer/discover-layers) + (configuration-layer/declare-layers (configuration-layer/get-layers-list)) + (configuration-layer/make-all-packages) + (setq helm-spacemacs--initialized t)))) + +;;;###autoload +(defun helm-spacemacs-help (arg) + "Layers discovery with helm interface." + (interactive "P") + (helm-spacemacs-help-mode) + (helm-spacemacs-help//init arg) + (helm :buffer "*helm: spacemacs*" + :sources `(,(helm-spacemacs-help//documentation-source) + ,(helm-spacemacs-help//layer-source) + ,(helm-spacemacs-help//package-source) + ,(helm-spacemacs-help//dotspacemacs-source) + ,(helm-spacemacs-help//toggle-source) + ,(helm-spacemacs-help//faq-source)))) + +;;;###autoload +(defun helm-spacemacs-help-dotspacemacs () + "Helm session to search for dotfile variables." + (interactive) + (helm-spacemacs-help-mode) + (helm :buffer "*helm: spacemacs*" + :sources `(,(helm-spacemacs-help//dotspacemacs-source)))) + +;;;###autoload +(defun helm-spacemacs-help-layers () + "Helm session to search for layers." + (interactive) + (helm-spacemacs-help-mode) + (helm :buffer "*helm: spacemacs*" + :sources `(,(helm-spacemacs-help//layer-source)))) + +;;;###autoload +(defun helm-spacemacs-help-packages (arg) + "Helm session to search for packages." + (interactive "P") + (helm-spacemacs-help-mode) + (helm-spacemacs-help//init arg) + (helm :buffer "*helm: spacemacs*" + :sources `(,(helm-spacemacs-help//package-source)))) + +;;;###autoload +(defun helm-spacemacs-help-docs () + "Helm session to search for documentation." + (interactive) + (helm-spacemacs-help-mode) + (helm :buffer "*helm: spacemacs*" + :sources `(,(helm-spacemacs-help//documentation-source)))) + +;;;###autoload +(defun helm-spacemacs-help-toggles () + "Helm session to search for toggles." + (interactive) + (helm-spacemacs-help-mode) + (helm :buffer "*helm: spacemacs*" + :sources `(,(helm-spacemacs-help//toggle-source)))) + +;;;###autoload +(defun helm-spacemacs-help-faq () + "Helm session to search for the FAQ." + (interactive) + (helm-spacemacs-help-mode) + (helm :buffer "*helm: spacemacs*" + :sources `(,(helm-spacemacs-help//faq-source)))) + +(defun helm-spacemacs-help//documentation-source () + "Construct the helm source for the documentation section." + (helm-build-sync-source "Spacemacs Documentation" + :candidates #'helm-spacemacs-help//documentation-candidates + :persistent-action #'helm-spacemacs-help//documentation-action-open-file + :keymap helm-map + :action (helm-make-actions + "Open Documentation" #'helm-spacemacs-help//documentation-action-open-file))) + +(defun helm-spacemacs-help//documentation-candidates () + (let (result file-extension) + (dolist (filename (directory-files spacemacs-docs-directory)) + (setq file-extension (file-name-extension filename)) + (when (or (equal file-extension "md") + (equal file-extension "org")) + (push filename result))) + + ;; CONTRIBUTING.org is a special case as it should be at the root of the + ;; repository to be linked as the contributing guide on Github. + (push "CONTRIBUTING.org" result) + + ;; delete DOCUMENTATION.org to make it the first guide + (delete "DOCUMENTATION.org" result) + (push "DOCUMENTATION.org" result) + + ;; give each document an appropriate title + (mapcar (lambda (r) + (cond + ((string-equal r "CONTRIBUTING.org") + `("How to contribute to Spacemacs" . ,r)) + ((string-equal r "CONVENTIONS.org") + `("Spacemacs conventions" . ,r)) + ((string-equal r "DOCUMENTATION.org") + `("Spacemacs documentation" . ,r)) + ((string-equal r "FAQ.org") + `("Spacemacs FAQ" . ,r)) + ((string-equal r "LAYERS.org") + `("Tips on writing layers for Spacemacs" . ,r)) + ((string-equal r "QUICK_START.org") + `("Quick start guide for Spacemacs" . ,r)) + ((string-equal r "VIMUSERS.org") + `("Vim users migration guide" . ,r)) + (t + `(,r . ,r)))) + result))) + +(defun helm-spacemacs-help//documentation-action-open-file (candidate) + "Open documentation FILE." + (let ((file (if (string= candidate "CONTRIBUTING.org") + ;; CONTRIBUTING.org is a special case as it should be at the + ;; root of the repository to be linked as the contributing + ;; guide on Github. + (concat spacemacs-start-directory candidate) + (concat spacemacs-docs-directory candidate)))) + (cond ((and (equal (file-name-extension file) "md") + (not helm-current-prefix-arg)) + (condition-case-unless-debug nil + (with-current-buffer (find-file-noselect file) + (gh-md-render-buffer) + (spacemacs/kill-this-buffer)) + ;; if anything fails, fall back to simply open file + (find-file file))) + ((equal (file-name-extension file) "org") + (spacemacs/view-org-file file "^" 'all)) + (t + (find-file file))))) + +(defun helm-spacemacs-help//layer-source () + "Construct the helm source for the layer section." + `((name . "Layers") + (candidates . ,(sort (configuration-layer/get-layers-list) 'string<)) + (candidate-number-limit) + (keymap . ,helm-spacemacs-help--layer-map) + (action . (("Open README.org" + . helm-spacemacs-help//layer-action-open-readme) + ("Open packages.el" + . helm-spacemacs-help//layer-action-open-packages) + ("Open config.el" + . helm-spacemacs-help//layer-action-open-config) + ("Install Layer" + . helm-spacemacs-help//layer-action-install-layer) + ("Open README.org (for editing)" + . helm-spacemacs-help//layer-action-open-readme-edit))))) + +(defvar helm-spacemacs-help--layer-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "") '(lambda () (interactive) + ;; Add Layer + (helm-select-nth-action 3))) + (define-key map (kbd "") '(lambda () (interactive) + ;; Open packages.el + (helm-select-nth-action 1))) + map) + "Keymap for Spacemacs Layers sources") + +(defun helm-spacemacs-help//package-source () + "Construct the helm source for the packages." + `((name . "Packages") + (candidates . ,(helm-spacemacs-help//package-candidates)) + (candidate-number-limit) + (action . (("Go to configuration function" + . helm-spacemacs-help//package-action-goto-config-func) + ("Describe" + . helm-spacemacs-help//package-action-decribe))))) + +(defun helm-spacemacs-help//package-candidates () + "Return the sorted candidates for package source." + (let (result) + (dolist (pkg-name (configuration-layer/get-packages-list)) + (let* ((pkg (configuration-layer/get-package pkg-name)) + (owner (cfgl-package-get-safe-owner pkg)) + ;; the notion of owner does not make sense if the layer is not used + (init-type (if (configuration-layer/layer-usedp owner) + "owner" "init"))) + (when owner + (push (format "%s (%s: %S layer)" + (propertize (symbol-name (oref pkg :name)) + 'face 'font-lock-type-face) + init-type + owner) + result)) + (dolist (initfuncs `((,(oref pkg :owners) "init") + (,(oref pkg :pre-layers) "pre-init") + (,(oref pkg :post-layers) "post-init"))) + (dolist (layer (car initfuncs)) + (unless (and owner (eq owner layer)) + (push (format "%s (%s: %S layer)" + (propertize (symbol-name (oref pkg :name)) + 'face 'font-lock-type-face) + (cadr initfuncs) + layer) + result)))))) + (sort result 'string<))) + +(defun helm-spacemacs-help//toggle-source () + "Construct the helm source for the toggles." + (let ((candidates (helm-spacemacs-help//toggle-candidates))) + (helm-build-sync-source "Toggles" + :candidates candidates + :persistent-action #'helm-spacemacs-help//toggle + :keymap helm-map + :action (helm-make-actions "Toggle" #'helm-spacemacs-help//toggle)))) + +(defun helm-spacemacs-help//toggle-candidates () + "Return the sorted candidates for toggle source." + (let (result) + (dolist (toggle spacemacs-toggles) + (let* ((toggle-symbol (symbol-name (car toggle))) + (toggle-status (funcall (plist-get (cdr toggle) :predicate))) + (toggle-name (capitalize (replace-regexp-in-string "-" " " toggle-symbol))) + (toggle-doc (format "(%s) %s: %s" + (if toggle-status "+" "-") + toggle-name + (propertize + (or (plist-get (cdr toggle) :documentation) "") + 'face 'font-lock-doc-face)))) + (when (plist-member (cdr toggle) :evil-leader) + (let ((key (key-description + (kbd (concat dotspacemacs-leader-key " " + (plist-get (cdr toggle) :evil-leader)))))) + (setq toggle-doc + (format "%s (%s)" + toggle-doc + (propertize key 'face 'helm-M-x-key))))) + (if (plist-member (cdr toggle) :documentation) + (push `(,toggle-doc . ,toggle-symbol) result) + (push `(,toggle-name . ,toggle-symbol) result)))) + (setq result (cl-sort result 'string< :key 'car)) + result)) + +(defun helm-spacemacs-help//dotspacemacs-source () + `((name . "Dotfile") + (candidates . ,(helm-spacemacs-help//dotspacemacs-candidates)) + (candidate-number-limit) + (action . (("Go to variable" . helm-spacemacs-help//go-to-dotfile-variable))))) + +(defun helm-spacemacs-help//dotspacemacs-candidates () + "Return the sorted candidates for all the dospacemacs variables." + (sort (dotspacemacs/get-variable-string-list) 'string<)) + +(defun helm-spacemacs-help//layer-action-open-file + (file candidate &optional edit) + "Open FILE of the passed CANDIDATE. If EDIT is false, open in view mode." + (let ((path (configuration-layer/get-layer-path (intern candidate)))) + (if (and (equal (file-name-extension file) "org") + (not helm-current-prefix-arg)) + (if edit + (find-file (concat path file)) + (spacemacs/view-org-file (concat path file) "^" 'all)) + (let ((filepath (concat path file))) + (if (file-exists-p filepath) + (find-file filepath) + (message "%s does not have %s" candidate file)))))) + +(defun helm-spacemacs-help//layer-action-open-readme (candidate) + "Open the `README.org' file of the passed CANDIDATE for reading." + (helm-spacemacs-help//layer-action-open-file "README.org" candidate)) + +(defun helm-spacemacs-help//layer-action-install-layer (candidate-layer) + "Add CANDIDATE-LAYER to dotspacemacs file and reloads configuration" + (when (dotspacemacs/add-layer (intern candidate-layer)) + (dotspacemacs/sync-configuration-layers))) + +(defun helm-spacemacs-help//layer-action-open-readme-edit (candidate) + "Open the `README.org' file of the passed CANDIDATE for editing." + (helm-spacemacs-help//layer-action-open-file "README.org" candidate t)) + +(defun helm-spacemacs-help//layer-action-open-packages (candidate) + "Open the `packages.el' file of the passed CANDIDATE." + (helm-spacemacs-help//layer-action-open-file "packages.el" candidate)) + +(defun helm-spacemacs-help//layer-action-open-config (candidate) + "Open the `config.el' file of the passed CANDIDATE." + (helm-spacemacs-help//layer-action-open-file "config.el" candidate)) + +(defun helm-spacemacs-help//package-action-decribe (candidate) + "Describe the passed package using Spacemacs describe function." + (save-match-data + (string-match "^\\(.+\\)\s(\\(.+\\) layer)$" candidate) + (let* ((package (match-string 1 candidate))) + (configuration-layer/describe-package (intern package))))) + +(defun helm-spacemacs-help//package-action-goto-config-func (candidate) + "Open the file `packages.el' and go to the init function." + (save-match-data + (string-match "^\\(.+\\)\s(\\(.*\\):\s\\(.+\\) layer.*)$" candidate) + (let* ((package (match-string 1 candidate)) + (init-type (match-string 2 candidate)) + (layer (match-string 3 candidate)) + (path (file-name-as-directory + (configuration-layer/get-layer-path (intern layer)))) + (filename (concat path "packages.el"))) + (when (string-match-p "owner" init-type) + (setq init-type "init")) + (find-file filename) + (goto-char (point-min)) + (re-search-forward (format "%s-%s" init-type package)) + (beginning-of-line)))) + +(defun helm-spacemacs-help//toggle (candidate) + "Toggle candidate." + (let ((toggle (assq (intern candidate) spacemacs-toggles))) + (when toggle + (funcall (plist-get (cdr toggle) :function))))) + +(defun helm-spacemacs-help//go-to-dotfile-variable (candidate) + "Go to candidate in the dotfile." + (find-file dotspacemacs-filepath) + (goto-char (point-min)) + ;; try to exclude comments + (re-search-forward (format "^[a-z\s\\(\\-]*%s" candidate)) + (beginning-of-line)) + +(defvar helm-spacemacs-help--faq-filename + (concat spacemacs-docs-directory "FAQ.org") + "Location of the FAQ file.") + +(defun helm-spacemacs-help//faq-source () + "Construct the helm source for the FAQ." + `((name . "FAQ") + (candidates . ,(helm-spacemacs-help//faq-candidates)) + (candidate-number-limit) + (action . (("Go to question" . helm-spacemacs-help//faq-goto-marker))))) + +(defun helm-spacemacs-help//faq-candidate (cand) + (let ((str (substring-no-properties (car cand)))) + (when (string-match "\\`.*/\\([^/]*\\)/\\(.*\\)\\'" str) + (cons (concat (propertize + (match-string 1 str) + 'face 'font-lock-type-face) + ": " (match-string 2 str)) + (cdr cand))))) + +(defun helm-spacemacs-help//faq-candidates () + (let* ((helm-org-format-outline-path nil) + (cands (helm-org-get-candidates (list helm-spacemacs-help--faq-filename))) + section result) + (dolist (c cands) + (let ((str (substring-no-properties (car c)))) + (when (string-match "\\`\\* \\(.*\\)\\'" str) + (setq section (match-string 1 str))) + (when (string-match "\\`\\*\\* \\(.*\\)\\'" str) + (push (cons (concat (propertize section 'face 'font-lock-type-face) + ": " (match-string 1 str)) + (cdr c)) + result)))) + result)) + +(defun helm-spacemacs-help//faq-goto-marker (marker) + (find-file helm-spacemacs-help--faq-filename) + (goto-char marker) + (org-show-context) + (org-show-entry)) + +(provide 'helm-spacemacs-help) + +;;; helm-spacemacs-help.el ends here diff --git a/layers/+completion/helm/packages.el b/layers/+completion/helm/packages.el new file mode 100644 index 0000000..c4d13be --- /dev/null +++ b/layers/+completion/helm/packages.el @@ -0,0 +1,595 @@ +;;; packages.el --- Helm Layer packages File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq helm-packages + '( + ace-jump-helm-line + auto-highlight-symbol + bookmark + helm + helm-ag + helm-descbinds + helm-flx + helm-make + helm-mode-manager + helm-projectile + helm-swoop + helm-themes + (helm-spacemacs-help :location local) + imenu + popwin + projectile + )) + +;; Initialization of packages + +(defun helm/init-ace-jump-helm-line () + (use-package ace-jump-helm-line + :defer t + :init + (with-eval-after-load 'helm + (define-key helm-map (kbd "C-q") 'ace-jump-helm-line)))) + +(defun helm/pre-init-auto-highlight-symbol () + (spacemacs|use-package-add-hook auto-highlight-symbol + :post-init + ;; add some functions to ahs transient states + (setq spacemacs--symbol-highlight-transient-state-doc + (concat spacemacs--symbol-highlight-transient-state-doc + " [_b_] search buffers [_/_] search proj [_f_] search files") + spacemacs-symbol-highlight-transient-state-add-bindings + '(("/" spacemacs/helm-project-smart-do-search-region-or-symbol :exit t) + ("b" spacemacs/helm-buffers-smart-do-search-region-or-symbol :exit t) + ("f" spacemacs/helm-files-smart-do-search-region-or-symbol :exit t))))) + +(defun helm/post-init-bookmark () + (spacemacs/set-leader-keys "fb" 'helm-filtered-bookmarks)) + +(defun helm/init-helm () + (use-package helm + :defer 1 + :commands (spacemacs/helm-find-files) + :init + (progn + (add-hook 'helm-cleanup-hook #'spacemacs//helm-cleanup) + ;; key bindings + ;; Use helm to provide :ls, unless ibuffer is used + (unless (configuration-layer/package-usedp 'ibuffer) + (evil-ex-define-cmd "buffers" 'helm-buffers-list)) + ;; use helm by default for M-x, C-x C-f, and C-x b + (unless (configuration-layer/package-usedp 'smex) + (global-set-key (kbd "M-x") 'helm-M-x)) + (global-set-key (kbd "C-x C-f") 'spacemacs/helm-find-files) + (global-set-key (kbd "C-x b") 'helm-buffers-list) + ;; use helm everywhere + (spacemacs/set-leader-keys + "" 'helm-apropos + "a'" 'helm-available-repls + "bb" 'helm-mini + "Cl" 'helm-colors + "ff" 'spacemacs/helm-find-files + "fF" 'helm-find-files + "fL" 'helm-locate + "fr" 'helm-recentf + "hdd" 'helm-apropos + "hdF" 'spacemacs/helm-faces + "hi" 'helm-info-at-point + "hm" 'helm-man-woman + "iu" 'helm-ucs + "jI" 'helm-imenu-in-all-buffers + "rm" 'helm-all-mark-rings + "rl" 'helm-resume + "rr" 'helm-register + "rs" 'spacemacs/resume-last-search-buffer + "ry" 'helm-show-kill-ring + "sl" 'spacemacs/resume-last-search-buffer + "sj" 'spacemacs/helm-jump-in-buffer) + ;; search with grep + (spacemacs/set-leader-keys + "sgb" 'spacemacs/helm-buffers-do-grep + "sgB" 'spacemacs/helm-buffers-do-grep-region-or-symbol + "sgf" 'spacemacs/helm-files-do-grep + "sgF" 'spacemacs/helm-files-do-grep-region-or-symbol + "sgg" 'spacemacs/helm-file-do-grep + "sgG" 'spacemacs/helm-file-do-grep-region-or-symbol) + ;; various key bindings + (spacemacs||set-helm-key "fel" helm-locate-library) + (spacemacs||set-helm-key "hdm" describe-mode) + (spacemacs||set-helm-key "sww" helm-wikipedia-suggest) + (spacemacs||set-helm-key "swg" helm-google-suggest) + (with-eval-after-load 'helm-files + (define-key helm-find-files-map + (kbd "C-c C-e") 'spacemacs/helm-find-files-edit)) + ;; Add minibuffer history with `helm-minibuffer-history' + (define-key minibuffer-local-map (kbd "C-c C-l") 'helm-minibuffer-history) + ;; define the key binding at the very end in order to allow the user + ;; to overwrite any key binding + (add-hook 'emacs-startup-hook + (lambda () + (unless (configuration-layer/package-usedp 'smex) + (spacemacs/set-leader-keys + dotspacemacs-emacs-command-key 'helm-M-x))))) + :config + (progn + (helm-mode) + (advice-add 'helm-grep-save-results-1 :after 'spacemacs//gne-init-helm-grep) + ;; helm-locate uses es (from everything on windows which doesnt like fuzzy) + (helm-locate-set-command) + (setq helm-locate-fuzzy-match (string-match "locate" helm-locate-command)) + ;; alter helm-bookmark key bindings to be simpler + ;; TODO check if there is a more elegant solution to setup these bindings + (defun simpler-helm-bookmark-keybindings () + (define-key helm-bookmark-map (kbd "C-d") 'helm-bookmark-run-delete) + (define-key helm-bookmark-map (kbd "C-e") 'helm-bookmark-run-edit) + (define-key helm-bookmark-map + (kbd "C-f") 'helm-bookmark-toggle-filename) + (define-key helm-bookmark-map + (kbd "C-o") 'helm-bookmark-run-jump-other-window) + (define-key helm-bookmark-map (kbd "C-/") 'helm-bookmark-help)) + (add-hook 'helm-mode-hook 'simpler-helm-bookmark-keybindings) + (with-eval-after-load 'helm-mode ; required + (spacemacs|hide-lighter helm-mode))))) + +(defun helm/init-helm-ag () + (use-package helm-ag + :defer t + :init + (progn + (defun spacemacs//helm-do-ag-region-or-symbol (func &optional dir) + "Search with `ag' with a default input." + (require 'helm-ag) + (cl-letf* (((symbol-value 'helm-ag-insert-at-point) 'symbol) + ;; make thing-at-point choosing the active region first + ((symbol-function 'this-fn) (symbol-function 'thing-at-point)) + ((symbol-function 'thing-at-point) + (lambda (thing) + (let ((res (if (region-active-p) + (buffer-substring-no-properties + (region-beginning) (region-end)) + (this-fn thing)))) + (when res (rxt-quote-pcre res)))))) + (funcall func dir))) + + (defun spacemacs//helm-do-search-find-tool (base tools default-inputp) + "Create a cond form given a TOOLS string list and evaluate it." + (eval + `(cond + ,@(mapcar + (lambda (x) + `((executable-find ,x) + ',(let ((func + (intern + (format (if default-inputp + "spacemacs/%s-%s-region-or-symbol" + "spacemacs/%s-%s") + base x)))) + (if (fboundp func) + func + (intern (format "%s-%s" base x)))))) + tools) + (t 'helm-do-grep)))) + + ;; Search in current file ---------------------------------------------- + + (defun spacemacs/helm-file-do-ag (&optional _) + "Wrapper to execute `helm-ag-this-file.'" + (interactive) + (helm-ag-this-file)) + + (defun spacemacs/helm-file-do-ag-region-or-symbol () + "Search in current file with `ag' using a default input." + (interactive) + (spacemacs//helm-do-ag-region-or-symbol 'spacemacs/helm-file-do-ag)) + + (defun spacemacs/helm-file-smart-do-search (&optional default-inputp) + "Search in current file using `dotspacemacs-search-tools'. +Search for a search tool in the order provided by `dotspacemacs-search-tools' +If DEFAULT-INPUTP is non nil then the current region or symbol at point +are used as default input." + (interactive) + (call-interactively + (spacemacs//helm-do-search-find-tool "helm-file-do" + dotspacemacs-search-tools + default-inputp))) + + (defun spacemacs/helm-file-smart-do-search-region-or-symbol () + "Search in current file using `dotspacemacs-search-tools' with + default input. +Search for a search tool in the order provided by `dotspacemacs-search-tools'." + (interactive) + (spacemacs/helm-file-smart-do-search t)) + + ;; Search in files ----------------------------------------------------- + + (defun spacemacs/helm-files-do-ag (&optional dir) + "Search in files with `ag' using a default input." + (interactive) + (helm-do-ag dir)) + + (defun spacemacs/helm-files-do-ag-region-or-symbol () + "Search in files with `ag' using a default input." + (interactive) + (spacemacs//helm-do-ag-region-or-symbol 'spacemacs/helm-files-do-ag)) + + (defun spacemacs/helm-files-do-ack (&optional dir) + "Search in files with `ack'." + (interactive) + (let ((helm-ag-base-command "ack --nocolor --nogroup")) + (helm-do-ag dir))) + + (defun spacemacs/helm-files-do-ack-region-or-symbol () + "Search in files with `ack' using a default input." + (interactive) + (spacemacs//helm-do-ag-region-or-symbol 'spacemacs/helm-files-do-ack)) + + (defun spacemacs/helm-files-do-pt (&optional dir) + "Search in files with `pt'." + (interactive) + (let ((helm-ag-base-command "pt -e --nocolor --nogroup")) + (helm-do-ag dir))) + + (defun spacemacs/helm-files-do-pt-region-or-symbol () + "Search in files with `pt' using a default input." + (interactive) + (spacemacs//helm-do-ag-region-or-symbol 'spacemacs/helm-files-do-pt)) + + (defun spacemacs/helm-files-smart-do-search (&optional default-inputp) + "Search in opened buffers using `dotspacemacs-search-tools'. +Search for a search tool in the order provided by `dotspacemacs-search-tools' +If DEFAULT-INPUTP is non nil then the current region or symbol at point +are used as default input." + (interactive) + (call-interactively + (spacemacs//helm-do-search-find-tool "helm-files-do" + dotspacemacs-search-tools + default-inputp))) + + (defun spacemacs/helm-files-smart-do-search-region-or-symbol () + "Search in opened buffers using `dotspacemacs-search-tools'. +with default input. +Search for a search tool in the order provided by `dotspacemacs-search-tools'." + (interactive) + (spacemacs/helm-files-smart-do-search t)) + + ;; Search in buffers --------------------------------------------------- + + (defun spacemacs/helm-buffers-do-ag (&optional _) + "Wrapper to execute `helm-ag-buffers.'" + (interactive) + (helm-do-ag-buffers)) + + (defun spacemacs/helm-buffers-do-ag-region-or-symbol () + "Search in opened buffers with `ag' with a default input." + (interactive) + (spacemacs//helm-do-ag-region-or-symbol 'spacemacs/helm-buffers-do-ag)) + + (defun spacemacs/helm-buffers-do-ack (&optional _) + "Search in opened buffers with `ack'." + (interactive) + (let ((helm-ag-base-command "ack --nocolor --nogroup")) + (helm-do-ag-buffers))) + + (defun spacemacs/helm-buffers-do-ack-region-or-symbol () + "Search in opened buffers with `ack' with a default input." + (interactive) + (spacemacs//helm-do-ag-region-or-symbol 'spacemacs/helm-buffers-do-ack)) + + (defun spacemacs/helm-buffers-do-pt (&optional _) + "Search in opened buffers with `pt'." + (interactive) + (let ((helm-ag-base-command "pt -e --nocolor --nogroup")) + (helm-do-ag-buffers))) + + (defun spacemacs/helm-buffers-do-pt-region-or-symbol () + "Search in opened buffers with `pt' using a default input." + (interactive) + (spacemacs//helm-do-ag-region-or-symbol 'spacemacs/helm-buffers-do-pt)) + + (defun spacemacs/helm-buffers-smart-do-search (&optional default-inputp) + "Search in opened buffers using `dotspacemacs-search-tools'. +Search for a search tool in the order provided by `dotspacemacs-search-tools' +If DEFAULT-INPUTP is non nil then the current region or symbol at point +are used as default input." + (interactive) + (call-interactively + (spacemacs//helm-do-search-find-tool "helm-buffers-do" + dotspacemacs-search-tools + default-inputp))) + + (defun spacemacs/helm-buffers-smart-do-search-region-or-symbol () + "Search in opened buffers using `dotspacemacs-search-tools' with +default input. +Search for a search tool in the order provided by `dotspacemacs-search-tools'." + (interactive) + (spacemacs/helm-buffers-smart-do-search t)) + + ;; Search in project --------------------------------------------------- + + (defun spacemacs/helm-project-do-ag () + "Search in current project with `ag'." + (interactive) + (let ((dir (projectile-project-root))) + (if dir + (helm-do-ag dir) + (message "error: Not in a project.")))) + + (defun spacemacs/helm-project-do-ag-region-or-symbol () + "Search in current project with `ag' using a default input." + (interactive) + (let ((dir (projectile-project-root))) + (if dir + (spacemacs//helm-do-ag-region-or-symbol 'helm-do-ag dir) + (message "error: Not in a project.")))) + + (defun spacemacs/helm-project-do-ack () + "Search in current project with `ack'." + (interactive) + (let ((dir (projectile-project-root))) + (if dir + (spacemacs/helm-files-do-ack dir) + (message "error: Not in a project.")))) + + (defun spacemacs/helm-project-do-ack-region-or-symbol () + "Search in current project with `ack' using a default input." + (interactive) + (let ((dir (projectile-project-root))) + (if dir + (spacemacs//helm-do-ag-region-or-symbol + 'spacemacs/helm-files-do-ack dir) + (message "error: Not in a project.")))) + + (defun spacemacs/helm-project-do-pt () + "Search in current project with `pt'." + (interactive) + (let ((dir (projectile-project-root))) + (if dir + (spacemacs/helm-files-do-pt dir) + (message "error: Not in a project.")))) + + (defun spacemacs/helm-project-do-pt-region-or-symbol () + "Search in current project with `pt' using a default input." + (interactive) + (let ((dir (projectile-project-root))) + (if dir + (spacemacs//helm-do-ag-region-or-symbol + 'spacemacs/helm-files-do-pt dir) + (message "error: Not in a project.")))) + + (defun spacemacs/helm-project-smart-do-search (&optional default-inputp) + "Search in current project using `dotspacemacs-search-tools'. +Search for a search tool in the order provided by `dotspacemacs-search-tools' +If DEFAULT-INPUTP is non nil then the current region or symbol at point +are used as default input." + (interactive) + (let ((projectile-require-project-root nil)) + (call-interactively + (spacemacs//helm-do-search-find-tool "helm-project-do" + dotspacemacs-search-tools + default-inputp)))) + + (defun spacemacs/helm-project-smart-do-search-region-or-symbol () + "Search in current project using `dotspacemacs-search-tools' with + default input. +Search for a search tool in the order provided by `dotspacemacs-search-tools'." + (interactive) + (spacemacs/helm-project-smart-do-search t)) + + ;; This overrides the default C-s action in helm-projectile-switch-project + ;; to search using ag/pt/whatever instead of just grep + (with-eval-after-load 'helm-projectile + (defun spacemacs/helm-project-smart-do-search-in-dir (dir) + (interactive) + (let ((default-directory dir)) + (spacemacs/helm-project-smart-do-search))) + (define-key helm-projectile-projects-map + (kbd "C-s") + (lambda () + (interactive) + (helm-exit-and-execute-action + 'spacemacs/helm-project-smart-do-search-in-dir)))) + + ;; evilify the helm-grep buffer + (evilified-state-evilify helm-grep-mode helm-grep-mode-map + (kbd "RET") 'helm-grep-mode-jump-other-window + (kbd "q") 'quit-window) + + (spacemacs/set-leader-keys + ;; helm-ag marks + "s`" 'helm-ag-pop-stack + ;; opened buffers scope + "sb" 'spacemacs/helm-buffers-smart-do-search + "sB" 'spacemacs/helm-buffers-smart-do-search-region-or-symbol + "sab" 'helm-do-ag-buffers + "saB" 'spacemacs/helm-buffers-do-ag-region-or-symbol + "skb" 'spacemacs/helm-buffers-do-ack + "skB" 'spacemacs/helm-buffers-do-ack-region-or-symbol + "stb" 'spacemacs/helm-buffers-do-pt + "stB" 'spacemacs/helm-buffers-do-pt-region-or-symbol + ;; current file scope + "ss" 'spacemacs/helm-file-smart-do-search + "sS" 'spacemacs/helm-file-smart-do-search-region-or-symbol + "saa" 'helm-ag-this-file + "saA" 'spacemacs/helm-file-do-ag-region-or-symbol + ;; files scope + "sf" 'spacemacs/helm-files-smart-do-search + "sF" 'spacemacs/helm-files-smart-do-search-region-or-symbol + "saf" 'helm-do-ag + "saF" 'spacemacs/helm-files-do-ag-region-or-symbol + "skf" 'spacemacs/helm-files-do-ack + "skF" 'spacemacs/helm-files-do-ack-region-or-symbol + "stf" 'spacemacs/helm-files-do-pt + "stF" 'spacemacs/helm-files-do-pt-region-or-symbol + ;; current project scope + "/" 'spacemacs/helm-project-smart-do-search + "*" 'spacemacs/helm-project-smart-do-search-region-or-symbol + "sp" 'spacemacs/helm-project-smart-do-search + "sP" 'spacemacs/helm-project-smart-do-search-region-or-symbol + "sap" 'spacemacs/helm-project-do-ag + "saP" 'spacemacs/helm-project-do-ag-region-or-symbol + "skp" 'spacemacs/helm-project-do-ack + "skP" 'spacemacs/helm-project-do-ack-region-or-symbol + "stp" 'spacemacs/helm-project-do-pt + "stP" 'spacemacs/helm-project-do-pt-region-or-symbol)) + :config + (progn + (advice-add 'helm-ag--save-results :after 'spacemacs//gne-init-helm-ag) + (evil-define-key 'normal helm-ag-map "SPC" spacemacs-default-map) + (evilified-state-evilify helm-ag-mode helm-ag-mode-map + (kbd "RET") 'helm-ag-mode-jump-other-window + (kbd "gr") 'helm-ag--update-save-results + (kbd "q") 'quit-window)))) + +(defun helm/init-helm-descbinds () + (use-package helm-descbinds + :defer t + :init + (progn + (setq helm-descbinds-window-style 'split) + (add-hook 'helm-mode-hook 'helm-descbinds-mode) + (spacemacs/set-leader-keys "?" 'helm-descbinds)))) + +(defun helm/init-helm-flx () + (use-package helm-flx + :defer t) + (spacemacs|use-package-add-hook helm + :pre-config + (progn + ;; Disable for helm-find-files until performance issues are sorted + ;; https://github.com/PythonNut/helm-flx/issues/9 + (setq helm-flx-for-helm-find-files nil) + (helm-flx-mode)))) + +(defun helm/init-helm-make () + (use-package helm-make + :defer t + :init + (spacemacs/set-leader-keys + "cc" 'helm-make-projectile + "cm" 'helm-make))) + +(defun helm/init-helm-mode-manager () + (use-package helm-mode-manager + :defer t + :init + (spacemacs/set-leader-keys + "hM" 'helm-switch-major-mode + ;; "hm" 'helm-disable-minor-mode + "h C-m" 'helm-enable-minor-mode))) + +(defun helm/init-helm-projectile () + (use-package helm-projectile + :commands (helm-projectile-switch-to-buffer + helm-projectile-find-dir + helm-projectile-dired-find-dir + helm-projectile-recentf + helm-projectile-find-file + helm-projectile-grep + helm-projectile + helm-projectile-switch-project) + :init + (progn + ;; needed for smart search if user's default tool is grep + (defalias 'spacemacs/helm-project-do-grep 'helm-projectile-grep) + (defalias + 'spacemacs/helm-project-do-grep-region-or-symbol + 'helm-projectile-grep) + ;; overwrite projectile settings + (spacemacs|use-package-add-hook projectile + :post-init + (progn + (setq projectile-switch-project-action 'helm-projectile) + (spacemacs/set-leader-keys + "pb" 'helm-projectile-switch-to-buffer + "pd" 'helm-projectile-find-dir + "pf" 'helm-projectile-find-file + "pF" 'helm-projectile-find-file-dwim + "ph" 'helm-projectile + "pp" 'helm-projectile-switch-project + "pr" 'helm-projectile-recentf + "sgp" 'helm-projectile-grep)))))) + +(defun helm/init-helm-spacemacs-help () + (use-package helm-spacemacs-help + :commands (helm-spacemacs-help-dotspacemacs + helm-spacemacs-help + helm-spacemacs-help-faq + helm-spacemacs-help-layers + helm-spacemacs-help-packages + helm-spacemacs-help-docs + helm-spacemacs-help-toggles) + :init + (progn + (defun spacemacs-base/helm-spacemacs-deprecated (arg) + "Provide helm-spacemacs with a binding's depreciation message." + (interactive "P") + (warn (concat "The 'SPC f e h' (or 'M-m f e h') binding is now " + "deprecated and will be remove in the next release. " + "Please use 'SPC h SPC' (or 'M-m h SPC') instead.")) + (helm-spacemacs arg)) + (spacemacs/set-leader-keys "feh" 'spacemacs-base/helm-spacemacs-deprecated) + (spacemacs/set-leader-keys "fef" 'helm-spacemacs-help-faq) + (spacemacs/set-leader-keys + "h ." 'helm-spacemacs-help-dotspacemacs + "h SPC" 'helm-spacemacs-help + "h f" 'helm-spacemacs-help-faq + "h l" 'helm-spacemacs-help-layers + "h p" 'helm-spacemacs-help-packages + "h r" 'helm-spacemacs-help-docs + "h t" 'helm-spacemacs-help-toggles)))) + +(defun helm/init-helm-swoop () + (use-package helm-swoop + :defer t + :init + (progn + (setq helm-swoop-split-with-multiple-windows t + helm-swoop-split-direction 'split-window-vertically + helm-swoop-speed-or-color t + helm-swoop-split-window-function 'helm-default-display-buffer + helm-swoop-pre-input-function (lambda () "")) + + (defun spacemacs/helm-swoop-region-or-symbol () + "Call `helm-swoop' with default input." + (interactive) + (let ((helm-swoop-pre-input-function + (lambda () + (if (region-active-p) + (buffer-substring-no-properties (region-beginning) + (region-end)) + (let ((thing (thing-at-point 'symbol t))) + (if thing thing "")))))) + (call-interactively 'helm-swoop))) + + (spacemacs/set-leader-keys + "ss" 'helm-swoop + "sS" 'spacemacs/helm-swoop-region-or-symbol + "s C-s" 'helm-multi-swoop-all) + (defadvice helm-swoop (before add-evil-jump activate) + (evil-set-jump))))) + +(defun helm/init-helm-themes () + (use-package helm-themes + :defer t + :init + (spacemacs/set-leader-keys + "Ts" 'helm-themes))) + +(defun helm/post-init-imenu () + (spacemacs/set-leader-keys "ji" 'spacemacs/helm-jump-in-buffer)) + +(defun helm/post-init-popwin () + ;; disable popwin-mode while Helm session is running + (add-hook 'helm-after-initialize-hook #'spacemacs//helm-prepare-display) + ;; Restore popwin-mode after a Helm session finishes. + (add-hook 'helm-cleanup-hook #'spacemacs//helm-restore-display)) + +(defun helm/post-init-projectile () + (setq projectile-completion-system 'helm)) diff --git a/layers/+completion/ivy/config.el b/layers/+completion/ivy/config.el new file mode 100644 index 0000000..c2aa029 --- /dev/null +++ b/layers/+completion/ivy/config.el @@ -0,0 +1,45 @@ +;;; config.el --- Ivy Layer Configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + +;; Variables + +(defvar spacemacs--counsel-commands + '(("ag" . "ag --nocolor --nogroup %s %S .") + ("pt" . "pt -e --nocolor --nogroup %s %S .") + ("ack" . "ack --nocolor --nogroup %s %S .") + ("grep" . "grep -nrP %s %S .")) + "Alist of search commands and their corresponding commands +with options to run in the shell.") + +(defvar spacemacs--counsel-search-max-path-length 30 + "Truncate the current path in counsel search if it is longer +than this amount.") + +(defvar spacemacs--counsel-initial-number-cand 100) + +(defvar spacemacs--ivy-file-actions + '(("f" find-file-other-frame "other frame") + ("w" find-file-other-window "other window") + ("v" spacemacs/find-file-vsplit "in vertical split") + ("s" spacemacs/find-file-split "in horizontal split") + ("l" find-file-literally "literally") + ("d" spacemacs/delete-file "delete file") + ("r" spacemacs/rename-file "rename file")) + "Default ivy actions for files.") + +(defvar spacemacs--ivy-grep-actions + (loop for j in spacemacs--ivy-file-actions + for key = (nth 0 j) + for func = (nth 1 j) + for desc = (nth 2 j) + collect `(,key (lambda (x) (spacemacs//counsel-with-git-grep (quote ,func) x)) ,desc)) + "Default ivy actions to be used with git-grep output.") diff --git a/layers/+completion/ivy/funcs.el b/layers/+completion/ivy/funcs.el new file mode 100644 index 0000000..94973f9 --- /dev/null +++ b/layers/+completion/ivy/funcs.el @@ -0,0 +1,395 @@ +;;; funcs.el --- Ivy Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + +;; Counsel + +;; async + +(defvar spacemacs--counsel-initial-cands-shown nil) + +(defun spacemacs//counsel-async-command (cmd) + (let* ((counsel--process " *counsel*") + (proc (get-process counsel--process)) + (buff (get-buffer counsel--process))) + (when proc + (delete-process proc)) + (when buff + (kill-buffer buff)) + (setq proc (start-process-shell-command + counsel--process + counsel--process + cmd)) + (setq spacemacs--counsel-initial-cands-shown nil) + (setq counsel--async-time (current-time)) + (set-process-sentinel proc #'counsel--async-sentinel) + (set-process-filter proc #'spacemacs//counsel-async-filter))) + +(defun spacemacs//counsel-async-filter (process str) + (with-current-buffer (process-buffer process) + (insert str)) + (when (or (null spacemacs--counsel-initial-cands-shown) + (time-less-p + ;; 0.5s + '(0 0 500000 0) + (time-since counsel--async-time))) + (let (size display-now) + (with-current-buffer (process-buffer process) + (goto-char (point-min)) + (setq size (- (buffer-size) (forward-line (buffer-size)))) + (when (and (null spacemacs--counsel-initial-cands-shown) + (> size spacemacs--counsel-initial-number-cand)) + (setq ivy--all-candidates + (split-string (buffer-string) "\n" t)) + (setq display-now t) + (setq spacemacs--counsel-initial-cands-shown t))) + (let ((ivy--prompt + (format (ivy-state-prompt ivy-last) + size))) + (if display-now + (ivy--insert-minibuffer + (ivy--format ivy--all-candidates)) + (ivy--insert-prompt)))) + (setq counsel--async-time (current-time)))) + +;; search + +(defvar spacemacs--counsel-search-cmd) + +;; see `counsel-ag-function' +(defun spacemacs//make-counsel-search-function (tool) + (lexical-let ((base-cmd + (cdr (assoc-string tool spacemacs--counsel-commands)))) + (lambda (string &optional _pred &rest _unused) + "Grep in the current directory for STRING." + (if (< (length string) 3) + (counsel-more-chars 3) + (let* ((default-directory counsel--git-grep-dir) + (args (if (string-match-p " -- " string) + (let ((split (split-string string " -- "))) + (prog1 (pop split) + (setq string (mapconcat #'identity split " -- ")))) + "")) + (regex (counsel-unquote-regex-parens + (setq ivy--old-re + (ivy--regex string))))) + (setq spacemacs--counsel-search-cmd (format base-cmd args regex)) + (spacemacs//counsel-async-command spacemacs--counsel-search-cmd) + nil))))) + +(defun spacemacs//counsel-save-in-buffer () + (interactive) + (ivy-quit-and-run + (let ((buf "*ivy results*")) + (with-current-buffer (get-buffer-create buf) + (erase-buffer) + (dolist (c ivy--all-candidates) + (insert c "\n")) + (spacemacs//gne-init-counsel)) + (pop-to-buffer buf)))) + +(defun spacemacs//gne-init-counsel () + (with-current-buffer "*ivy results*" + (setq spacemacs--gne-min-line 1 + spacemacs--gne-max-line + (save-excursion + (goto-char (point-max)) + (previous-line) + (line-number-at-pos)) + spacemacs--gne-line-func + (lambda (c) + (let ((counsel--git-grep-dir default-directory)) + (counsel-git-grep-action c))) + next-error-function 'spacemacs/gne-next))) + +(defvar spacemacs--counsel-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "") 'spacemacs//counsel-save-in-buffer) + map)) + +;; see `counsel-ag' +(defun spacemacs/counsel-search + (&optional tools use-initial-input initial-directory) + "Search using the first available tool in TOOLS. Default tool +to try is grep. If INPUT is non nil, use the region or the symbol +around point as the initial input. If DIR is non nil start in +that directory." + (interactive) + (require 'counsel) + (letf* ((initial-input (if use-initial-input + (if (region-active-p) + (buffer-substring-no-properties + (region-beginning) (region-end)) + (thing-at-point 'symbol t)) + "")) + (tool (catch 'tool + (dolist (tool tools) + (when (and (assoc-string tool spacemacs--counsel-commands) + (executable-find tool)) + (throw 'tool tool))) + (throw 'tool "grep")))) + (setq counsel--git-grep-dir + (or initial-directory + (read-directory-name "Start from directory: "))) + (ivy-read + (concat ivy-count-format + (format "%s from [%s]: " + tool + (if (< (length counsel--git-grep-dir) + spacemacs--counsel-search-max-path-length) + counsel--git-grep-dir + (concat + "..." (substring counsel--git-grep-dir + (- (length counsel--git-grep-dir) + spacemacs--counsel-search-max-path-length) + (length counsel--git-grep-dir)))))) + (spacemacs//make-counsel-search-function tool) + :initial-input (rxt-quote-pcre initial-input) + :dynamic-collection t + :history 'counsel-git-grep-history + :action #'counsel-git-grep-action + :caller 'spacemacs/counsel-search + :keymap spacemacs--counsel-map + :unwind (lambda () + (counsel-delete-process) + (swiper--cleanup))))) + +;; Define search functions for each tool +(cl-loop + for (tools tool-name) in '((dotspacemacs-search-tools "auto") + ((list "ag") "ag") + ((list "pt") "pt") + ((list "ack") "ack") + ((list "grep") "grep")) + do + (eval + `(progn + (defun ,(intern (format "spacemacs/search-%s" tool-name)) () + ,(format + "Use `spacemacs/counsel-search' to search in the current + directory with %s." (if (string= tool-name "auto") + "a tool selected from `dotspacemacs-search-tools'." + tool-name)) + (interactive) + (spacemacs/counsel-search ,tools)) + (defun ,(intern (format "spacemacs/search-%s-region-or-symbol" + tool-name)) () + ,(format + "Use `spacemacs/counsel-search' to search for + the selected region or the symbol around point in the current + directory with %s." (if (string= tool-name "auto") + "a tool selected from `dotspacemacs-search-tools'." + tool-name)) + (interactive) + (spacemacs/counsel-search ,tools t)) + (defun ,(intern (format "spacemacs/search-project-%s" tool-name)) () + ,(format + "Use `spacemacs/counsel-search' to search in the current + project with %s." (if (string= tool-name "auto") + "a tool selected from `dotspacemacs-search-tools'." + tool-name)) + (interactive) + (spacemacs/counsel-search ,tools nil (projectile-project-root))) + (defun ,(intern (format "spacemacs/search-project-%s-region-or-symbol" + tool-name)) () + ,(format + "Use `spacemacs/counsel-search' to search for + the selected region or the symbol around point in the current + project with %s." (if (string= tool-name "auto") + "a tool selected from `dotspacemacs-search-tools'." + tool-name)) + (interactive) + (spacemacs/counsel-search ,tools t (projectile-project-root)))))) + +(defun spacemacs/counsel-git-grep-region-or-symbol () + "Use `counsel-git-grep' to search for the selected region or + the symbol around point in the current project with git grep." + (interactive) + (let ((input (if (region-active-p) + (buffer-substring-no-properties + (region-beginning) (region-end)) + (thing-at-point 'symbol t)))) + (counsel-git-grep nil input))) + +(defun spacemacs/counsel-search-docs () + "Search spacemacs docs using `spacemacs/counsel-search'" + (interactive) + (spacemacs/counsel-search dotspacemacs-search-tools + nil spacemacs-docs-directory)) + +(defun spacemacs//counsel-occur () + "Generate a custom occur buffer for `counsel-git-grep'." + (ivy-occur-grep-mode) + (setq default-directory counsel--git-grep-dir) + (let ((cands ivy--old-cands)) + ;; Need precise number of header lines for `wgrep' to work. + (insert (format "-*- mode:grep; default-directory: %S -*-\n\n\n" + default-directory)) + (insert (format "%d candidates:\n" (length cands))) + (ivy--occur-insert-lines + (mapcar + (lambda (cand) (concat "./" cand)) + ivy--old-cands)))) + +(defun spacemacs/counsel-up-directory-no-error () + "`counsel-up-directory' ignoring errors." + (interactive) + (ignore-errors + (call-interactively 'counsel-up-directory))) + +(when (configuration-layer/package-usedp 'counsel) + (with-eval-after-load 'counsel + (defun spacemacs/describe-mode () + "Dummy wrapper to prevent an key binding error from helm. + +By default the emacs leader is M-m, turns out that Helm does this: + (cl-dolist (k (where-is-internal 'describe-mode global-map)) + (define-key map k 'helm-help)) +after doing this: + (define-key map (kbd \"M-m\") 'helm-toggle-all-marks) +So when Helm is loaded we get the error: + Key sequence M-m h d m starts with non-prefix key M-m + +To prevent this error we just wrap `describe-mode' to defeat the + Helm hack." + (interactive) + (call-interactively 'describe-mode)))) + +(defun spacemacs//counsel-with-git-grep (func x) + (when (string-match "\\`\\(.*?\\):\\([0-9]+\\):\\(.*\\)\\'" x) + (with-ivy-window + (let ((file-name (match-string-no-properties 1 x)) + (line-number (match-string-no-properties 2 x))) + (funcall func + (expand-file-name file-name counsel--git-grep-dir)) + (goto-char (point-min)) + (forward-line (1- (string-to-number line-number))) + (re-search-forward (ivy--regex ivy-text t) (line-end-position) t) + (unless (eq ivy-exit 'done) + (swiper--cleanup) + (swiper--add-overlays (ivy--regex ivy-text))))))) + +;; Ivy + +(defun spacemacs//ivy-command-not-implemented-yet (key) + (lexical-let ((-key key)) + (spacemacs/set-leader-keys + -key (lambda () + (interactive) + (message (concat "The command usually bound to %s %s has " + "not been implemented for the `ivy' layer yet.") + dotspacemacs-leader-key -key))))) + +(defun spacemacs/ivy-available-repls () + "Show available repls." + (interactive) + (ivy-read "Repls: " + (mapcar #'car spacemacs-repl-list) + :action (lambda (candidate) + (let ((repl (cdr (assoc candidate spacemacs-repl-list)))) + (require (car repl)) + (call-interactively (cdr repl)))))) + +;; Evil + +(defun spacemacs/ivy-evil-registers () + "Show evil registers" + (interactive) + (let ((ivy-height 24)) + (ivy-read "Evil Registers:" + (cl-loop for (key . val) in (evil-register-list) + collect (eval `(format "%s : %s" (propertize ,(char-to-string key) 'face 'font-lock-builtin-face) + ,(or (and val + (stringp val) + (replace-regexp-in-string "\n" "^J" val)) + "")))) + :action #'spacemacs/ivy-insert-evil-register))) + +(defun spacemacs/ivy-insert-evil-register (candidate) + (insert (replace-regexp-in-string "\\^J" "\n" + (substring-no-properties candidate 4)))) + +;; Layouts + +(defun spacemacs/ivy-spacemacs-layouts () + "Control Panel for Spacemacs layouts. Has many actions. +If match is found +\(default) Select layout +c: Close Layout(s) <- mark with C-SPC to close more than one-window +k: Kill Layout(s) + +If match is not found + Creates layout + +Closing doesn't kill buffers inside the layout while killing layouts does." + (interactive) + (ivy-read "Layouts: " + (persp-names) + :caller 'spacemacs/ivy-spacemacs-layouts + :action (lambda (name) + (let ((persp-reset-windows-on-nil-window-conf t)) + (persp-switch name) + (unless + (member name + (persp-names-current-frame-fast-ordered)) + (spacemacs/home)))))) + +(defun spacemacs/ivy-spacemacs-layout-buffer () + "Switch to layout buffer using ivy." + (interactive) + (let (ivy-use-virtual-buffers) + (with-persp-buffer-list () + (call-interactively 'ivy-switch-buffer)))) + +(defun spacemacs/ivy-spacemacs-layout-close-other () + "Kills layouts without killing the buffers" + (interactive) + (ivy-read (format "Close layout [current %s]: " + (spacemacs//current-layout-name)) + (persp-names) + :action 'persp-kill-without-buffers)) + +(defun spacemacs/ivy-spacemacs-layout-kill-other () + "Kills layouts with all their buffers" + (interactive) + (ivy-read (format "Kill layout [current %s]: " + (spacemacs//current-layout-name)) + (persp-names) + :action 'persp-kill)) + + +;; Swiper + +(defun spacemacs/swiper-region-or-symbol () + "Run `swiper' with the selected region or the symbol +around point as the initial input." + (interactive) + (let ((input (if (region-active-p) + (buffer-substring-no-properties + (region-beginning) (region-end)) + (thing-at-point 'symbol t)))) + (swiper input))) + +(defun spacemacs/swiper-all-region-or-symbol () + "Run `swiper-all' with the selected region or the symbol +around point as the initial input." + (interactive) + (ivy-read "Swiper: " (swiper--multi-candidates + (cl-remove-if-not + #'buffer-file-name + (buffer-list))) + :initial-input (if (region-active-p) + (buffer-substring-no-properties + (region-beginning) (region-end)) + (thing-at-point 'symbol t)) + :action 'swiper-multi-action-2 + :unwind #'swiper--cleanup + :caller 'swiper-multi)) diff --git a/layers/+completion/ivy/layers.el b/layers/+completion/ivy/layers.el new file mode 100644 index 0000000..865828a --- /dev/null +++ b/layers/+completion/ivy/layers.el @@ -0,0 +1,15 @@ +;;; layers.el --- Ivy Layer layers File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; smex is handled by the `ivy' layer and we don't want +;; to use the ownership mechanism of layers because it is dependent +;; on the order of layer declaration +(configuration-layer/remove-layer 'smex) diff --git a/layers/+completion/ivy/local/ivy-spacemacs-help/ivy-spacemacs-help.el b/layers/+completion/ivy/local/ivy-spacemacs-help/ivy-spacemacs-help.el new file mode 100644 index 0000000..fdef1af --- /dev/null +++ b/layers/+completion/ivy/local/ivy-spacemacs-help/ivy-spacemacs-help.el @@ -0,0 +1,397 @@ +;;; ivy-spacemacs-help.el --- Spacemacs layer exploration with `ivy'. + +;; Author: Justin Burkett +;; Keywords: ivy, spacemacs +;; Version: 0.1 +;; Package-Requires: ((ivy "0.7")) + +;; This file 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, or (at your option) +;; any later version. + +;; This file 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., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: +;; This package adds a convenient way to discover Spacemacs configuration +;; layers thanks to ivy. + +;;; Code: + +(require 'cl) +(require 'ht) +(require 'ivy) +(require 'core-configuration-layer) + +(defvar ivy-spacemacs--initialized nil + "Non nil if ivy-spacemacs is initialized.") + +;; (defvar ivy-spacemacs-help-all-layers nil +;; "Alist of all configuration layers.") + +;; (defvar ivy-spacemacs-help-all-packages nil +;; "Hash table of all packages in all layers.") + +(defun ivy-spacemacs-help//init (&optional arg) + (when (or arg (null ivy-spacemacs--initialized)) + (let ((configuration-layer--load-packages-files t) + (configuration-layer--package-properties-read-onlyp t) + (configuration-layer--inhibit-warnings t)) + (configuration-layer/discover-layers) + (configuration-layer/declare-layers (configuration-layer/get-layers-list)) + (configuration-layer/make-all-packages) + (setq ivy-spacemacs--initialized t)))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Docs + +(defun ivy-spacemacs-help//documentation-candidates () + (let (result file-extension) + (dolist (filename (directory-files spacemacs-docs-directory)) + (setq file-extension (file-name-extension filename)) + (when (or (equal file-extension "md") + (equal file-extension "org")) + (push filename result))) + + ;; CONTRIBUTING.org is a special case as it should be at the root of the + ;; repository to be linked as the contributing guide on Github. + (push "CONTRIBUTING.org" result) + + ;; delete DOCUMENTATION.org to make it the first guide + (delete "DOCUMENTATION.org" result) + (push "DOCUMENTATION.org" result) + + ;; give each document an appropriate title + (mapcar (lambda (r) + (cond + ((string-equal r "CONTRIBUTING.org") + `("How to contribute to Spacemacs" . ,r)) + ((string-equal r "CONVENTIONS.org") + `("Spacemacs conventions" . ,r)) + ((string-equal r "DOCUMENTATION.org") + `("Spacemacs documentation" . ,r)) + ((string-equal r "FAQ.org") + `("Spacemacs FAQ" . ,r)) + ((string-equal r "LAYERS.org") + `("Tips on writing layers for Spacemacs" . ,r)) + ((string-equal r "QUICK_START.org") + `("Quick start guide for Spacemacs" . ,r)) + ((string-equal r "VIMUSERS.org") + `("Vim users migration guide" . ,r)) + (t + `(r . ,r)))) + result))) + +(defun ivy-spacemacs-help//documentation-action-open-file (candidate) + "Open documentation FILE." + (let* ((candidate (cdr candidate)) + (file (if (string= candidate "CONTRIBUTING.org") + ;; CONTRIBUTING.org is a special case as it should be at the + ;; root of the repository to be linked as the contributing + ;; guide on Github. + (concat spacemacs-start-directory candidate) + (concat spacemacs-docs-directory candidate)))) + (cond ((equal (file-name-extension file) "md") + (condition-case-unless-debug nil + (with-current-buffer (find-file-noselect file) + (gh-md-render-buffer) + (spacemacs/kill-this-buffer)) + ;; if anything fails, fall back to simply open file + (find-file file))) + ((equal (file-name-extension file) "org") + (spacemacs/view-org-file file "^" 'all)) + (t + (find-file file))))) + +;;;###autoload +(defun ivy-spacemacs-help-docs (arg) + (interactive "P") + (ivy-spacemacs-help//init arg) + (ivy-read "Spacemacs Documentation: " + (ivy-spacemacs-help//documentation-candidates) + :action #'ivy-spacemacs-help//documentation-action-open-file)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Layers + +(defun ivy-spacemacs-help//layer-candidates () + (sort (mapcar 'symbol-name (configuration-layer/get-layers-list)) + 'string<)) + +(defun ivy-spacemacs-help//layer-action-get-directory (candidate) + "Get directory of layer passed CANDIDATE." + (configuration-layer/get-layer-path (intern candidate))) + +(defun ivy-spacemacs-help//layer-action-open-file (file candidate &optional edit) + "Open FILE of the passed CANDIDATE. If EDIT is false, open in view mode." + (let ((path (configuration-layer/get-layer-path (intern candidate)))) + (if (equal (file-name-extension file) "org") + (if edit + (find-file (concat path file)) + (spacemacs/view-org-file (concat path file) "^" 'all)) + (let ((filepath (concat path file))) + (if (file-exists-p filepath) + (find-file filepath) + (message "%s does not have %s" candidate file)))))) + +(defun ivy-spacemacs-help//layer-action-open-readme (candidate) + "Open the `README.org' file of the passed CANDIDATE for reading." + (ivy-spacemacs-help//layer-action-open-file "README.org" candidate)) + +(defun ivy-spacemacs-help//layer-action-add-layer (candidate) + "Adds layer to dotspacemacs file and reloads configuration" + (if (configuration-layer/layer-usedp (intern candidate)) + (message "Layer already added.") + (let ((dotspacemacs (find-file-noselect (dotspacemacs/location)))) + (with-current-buffer dotspacemacs + (beginning-of-buffer) + (let ((insert-point (re-search-forward + "dotspacemacs-configuration-layers *\n?.*\\((\\)"))) + (insert (format "\n%s\n" candidate)) + (indent-region insert-point (+ insert-point (length candidate))) + (save-current-buffer))) + (dotspacemacs/sync-configuration-layers)))) + +(defun ivy-spacemacs-help//layer-action-open-dired (candidate) + "Open dired at the location of the passed layer CANDIDATE." + (dired + (ivy-spacemacs-help//layer-action-get-directory candidate))) + +(defun ivy-spacemacs-help//layer-action-open-readme-edit (candidate) + "Open the `README.org' file of the passed CANDIDATE for editing." + (ivy-spacemacs-help//layer-action-open-file "README.org" candidate t)) + +(defun ivy-spacemacs-help//layer-action-open-config (candidate) + "Open the `config.el' file of the passed CANDIDATE." + (ivy-spacemacs-help//layer-action-open-file "config.el" candidate)) + +(defun ivy-spacemacs-help//layer-action-open-packages (candidate) + "Open the `packages.el' file of the passed CANDIDATE." + (ivy-spacemacs-help//layer-action-open-file "packages.el" candidate)) + +;;;###autoload +(defun ivy-spacemacs-help-layers () + (interactive) + (ivy-spacemacs-help//init) + (ivy-read "Spacemacs Layers: " + (ivy-spacemacs-help//layer-candidates) + :action 'ivy-spacemacs-help//layer-action-open-readme + :caller 'ivy-spacemacs-help-layers)) + +(ivy-set-actions + 'ivy-spacemacs-help-layers + '(("a" ivy-spacemacs-help//layer-action-add-layer "add layer") + ("d" ivy-spacemacs-help//layer-action-open-dired "open dired at layer location") + ("e" ivy-spacemacs-help//layer-action-open-readme-edit "open readme for editing") + ("c" ivy-spacemacs-help//layer-action-open-config "open config.el") + ("p" ivy-spacemacs-help//layer-action-open-packages "open packages.el") + ("r" ivy-spacemacs-help//layer-action-open-readme "open readme"))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Layers and packages + +(defun ivy-spacemacs-help//help-candidates () + "Return the sorted candidates for package source." + (let (result + (left-column-width + (number-to-string + (cl-reduce + (lambda (a x) (max (length (symbol-name x)) a)) + (configuration-layer/get-layers-list) :initial-value 0))) + (owners (cl-remove-duplicates + (mapcar (lambda (pkg) + (let ((obj (configuration-layer/get-package pkg))) + (car (oref obj :owners)))) + (configuration-layer/get-packages-list))))) + (dolist (pkg-name (configuration-layer/get-packages-list)) + (let ((pkg (configuration-layer/get-package pkg-name))) + (push (list (format (concat "%-" left-column-width "S %s %s") + (car (oref pkg :owners )) + (propertize (symbol-name (oref pkg :name)) + 'face 'font-lock-type-face) + (propertize + (if (package-installed-p (oref pkg :name)) + "[installed]" "") + 'face 'font-lock-comment-face)) + (symbol-name + (car (oref pkg :owners ))) + (symbol-name (oref pkg :name))) + result))) + (dolist (layer (delq nil + (cl-remove-if + (lambda (x) (memq x owners)) + (configuration-layer/get-layers-list)))) + (push (list (format (concat "%-" left-column-width "S %s") + layer + (propertize "no packages" + 'face 'warning)) + layer + nil) + result)) + (sort result (lambda (a b) (string< (car a) (car b)))))) + +(defun ivy-spacemacs-help//help-action (args) + "Open the file `packages.el' and go to the init function." + (if (null (caddr args)) + (message "There are no packages associated with this layer.") + (let* ((layer-str (cadr args)) + (layer-sym (intern layer-str)) + (package-str (caddr args)) + (path (configuration-layer/get-layer-path layer-sym)) + (filename (concat path "packages.el"))) + (find-file filename) + (goto-char (point-min)) + (re-search-forward (format "init-%s" package-str)) + (beginning-of-line)))) + +(defun ivy-spacemacs-help//help-action-describe-package (args) + "Describe the passed package using Spacemacs describe function." + (if (null (caddr args)) + (message "There are no packages associated with this layer.") + (let ((package-str (caddr args))) + (configuration-layer/describe-package (intern package-str))))) + +(defun ivy-spacemacs-help//help-action-open-dired (args) + "Open the `packages.el' file of the passed `car' of ARGS." + (dired + (ivy-spacemacs-help//layer-action-get-directory (cadr args)))) + +(defun ivy-spacemacs-help//help-action-open-config (args) + "Open the `packages.el' file of the passed CANDIDATE." + (ivy-spacemacs-help//layer-action-open-file "config.el" (cadr args))) + +(defun ivy-spacemacs-help//help-action-open-packages (args) + "Open the `packages.el' file of the passed CANDIDATE." + (ivy-spacemacs-help//layer-action-open-file "packages.el" (cadr args))) + +(defun ivy-spacemacs-help//help-action-open-readme (args) + "Open the `README.org' file of the passed CANDIDATE for reading." + (ivy-spacemacs-help//layer-action-open-file "README.org" (cadr args))) + +(defun ivy-spacemacs-help//help-action-open-readme-edit (args) + "Open the `README.org' file of the passed CANDIDATE for editing." + (ivy-spacemacs-help//layer-action-open-file "README.org" (cadr args) t)) + +(defun ivy-spacemacs-help//help-action-add-layer (args) + "Adds layer to dotspacemacs file and reloads configuration" + (if (configuration-layer/layer-usedp (intern (cadr args))) + (message "Layer already added.") + (let ((dotspacemacs (find-file-noselect (dotspacemacs/location)))) + (with-current-buffer dotspacemacs + (beginning-of-buffer) + (let ((insert-point (re-search-forward + "dotspacemacs-configuration-layers *\n?.*\\((\\)"))) + (insert (format "\n%s\n" (cadr args))) + (indent-region insert-point (+ insert-point (length (cadr args)))) + (save-current-buffer))) + (dotspacemacs/sync-configuration-layers)))) + +;;;###autoload +(defun ivy-spacemacs-help () + (interactive) + (ivy-spacemacs-help//init) + (ivy-read "Spacemacs Layers and Packages: " + (ivy-spacemacs-help//help-candidates) + :action 'ivy-spacemacs-help//help-action + :caller 'ivy-spacemacs-help)) + +(ivy-set-actions + 'ivy-spacemacs-help + '(("a" ivy-spacemacs-help//help-action-add-layer "add layer") + ("d" ivy-spacemacs-help//help-action-open-dired "open dired at layer location") + ("D" ivy-spacemacs-help//help-action-describe-package "describe package") + ("e" ivy-spacemacs-help//help-action-open-readme-edit "open readme for editing") + ("c" ivy-spacemacs-help//help-action-open-config "open config.el") + ("p" ivy-spacemacs-help//help-action-open-packages "open packages.el") + ("r" ivy-spacemacs-help//help-action-open-readme "open readme"))) + +;;;###autoload +(defalias 'ivy-spacemacs-help-packages 'ivy-spacemacs-help) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Toggles + +(defun ivy-spacemacs-help//toggle-candidates () + "Return the sorted candidates for toggle source." + (let (result) + (dolist (toggle spacemacs-toggles) + (let* ((toggle-symbol (symbol-name (car toggle))) + (toggle-status (funcall (plist-get (cdr toggle) :predicate))) + (toggle-name (capitalize (replace-regexp-in-string "-" " " toggle-symbol))) + (toggle-doc (format "(%s) %s: %s" + (if toggle-status "+" "-") + toggle-name + (propertize + (or (plist-get (cdr toggle) :documentation) "") + 'face 'font-lock-doc-face)))) + (when (plist-member (cdr toggle) :evil-leader) + (let ((key (key-description + (kbd (concat dotspacemacs-leader-key " " + (plist-get (cdr toggle) :evil-leader)))))) + (setq toggle-doc + (format "%s (%s)" + toggle-doc + (propertize key 'face 'font-lock-keyword-face))))) + (if (plist-member (cdr toggle) :documentation) + (push `(,toggle-doc . ,toggle-symbol) result) + (push `(,toggle-name . ,toggle-symbol) result)))) + (setq result (cl-sort result 'string< :key 'car)) + result)) + +(defun ivy-spacemacs-help//toggle (candidate) + "Toggle candidate." + (let ((toggle (assq (intern candidate) spacemacs-toggles))) + (when toggle + (funcall (plist-get (cdr toggle) :function))))) + +;;;###autoload +(defun ivy-spacemacs-help-toggles () + (interactive) + (ivy-read "Spacemacs Toggles: " + (ivy-spacemacs-help//toggle-candidates) + :action 'ivy-spacemacs-help//toggle)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; .spacemacs vars + +(defun ivy-spacemacs-help//dotspacemacs-candidates () + "Return the sorted candidates for all the dospacemacs variables." + (sort (dotspacemacs/get-variable-string-list) 'string<)) + +(defun ivy-spacemacs-help//go-to-dotfile-variable (candidate) + "Go to candidate in the dotfile." + (find-file dotspacemacs-filepath) + (goto-char (point-min)) + ;; try to exclude comments + (re-search-forward (format "^[a-z\s\\(\\-]*%s" candidate)) + (beginning-of-line)) + +;;;###autoload +(defun ivy-spacemacs-help-dotspacemacs () + (interactive) + (ivy-read ".spacemacs variables: " + (ivy-spacemacs-help//dotspacemacs-candidates) + :action 'ivy-spacemacs-help//go-to-dotfile-variable)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; FAQ + +;;;###autoload +(defun ivy-spacemacs-help-faq () + "Show FAQ and launch swiper session." + (interactive) + (find-file-read-only + (expand-file-name "FAQ.org" spacemacs-docs-directory)) + (swiper "\\*\\* ")) + +(provide 'ivy-spacemacs-help) + +;;; ivy-spacemacs-help.el ends here diff --git a/layers/+completion/ivy/packages.el b/layers/+completion/ivy/packages.el new file mode 100644 index 0000000..5881475 --- /dev/null +++ b/layers/+completion/ivy/packages.el @@ -0,0 +1,246 @@ +;;; packages.el --- Ivy Layer packages File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq ivy-packages + '( + auto-highlight-symbol + counsel + (counsel-projectile :toggle (configuration-layer/package-usedp 'projectile)) + evil + flx + helm-make + imenu + ivy + ivy-hydra + (ivy-spacemacs-help :location local) + persp-mode + projectile + smex + swiper + wgrep + )) + +(defun ivy/pre-init-auto-highlight-symbol () + (spacemacs|use-package-add-hook auto-highlight-symbol + :post-init + ;; add some functions to ahs transient states + (setq spacemacs--symbol-highlight-transient-state-doc + (concat spacemacs--symbol-highlight-transient-state-doc + " [_b_] search buffers [_/_] search proj [_f_] search files") + spacemacs-symbol-highlight-transient-state-add-bindings + '(("/" spacemacs/search-project-auto-region-or-symbol :exit t) + ("b" spacemacs/swiper-all-region-or-symbol :exit t) + ("f" spacemacs/search-auto-region-or-symbol :exit t))))) + +(defun ivy/init-counsel () + (use-package counsel + :config + (progn + (define-key counsel-find-file-map (kbd "C-h") 'counsel-up-directory) + (spacemacs/set-leader-keys + dotspacemacs-emacs-command-key 'counsel-M-x + ;; files + "ff" 'counsel-find-file + "fL" 'counsel-locate + ;; help + "?" 'counsel-descbinds + "hdf" 'counsel-describe-function + "hdm" 'spacemacs/describe-mode + "hdv" 'counsel-describe-variable + "hR" 'spacemacs/counsel-search-docs + ;; insert + "iu" 'counsel-unicode-char + ;; jump + ;; register/ring + "ry" 'counsel-yank-pop + ;; jumping + "sj" 'counsel-imenu + ;; themes + "Ts" 'counsel-load-theme + ;; search + "/" 'spacemacs/search-project-auto + "*" 'spacemacs/search-project-auto-region-or-symbol + "sf" 'spacemacs/search-auto + "sF" 'spacemacs/search-auto-region-or-symbol + "sp" 'spacemacs/search-project-auto + "sP" 'spacemacs/search-project-auto-region-or-symbol + "saf" 'spacemacs/search-ag + "saF" 'spacemacs/search-ag-region-or-symbol + "sap" 'spacemacs/search-project-ag + "saP" 'spacemacs/search-project-ag-region-or-symbol + "stf" 'spacemacs/search-pt + "stF" 'spacemacs/search-pt-region-or-symbol + "stp" 'spacemacs/search-project-pt + "stP" 'spacemacs/search-project-pt-region-or-symbol + "sgf" 'spacemacs/search-grep + "sgF" 'spacemacs/search-grep-region-or-symbol + "sgp" 'counsel-git-grep + "sgP" 'spacemacs/counsel-git-grep-region-or-symbol + "skf" 'spacemacs/search-ack + "skF" 'spacemacs/search-ack-region-or-symbol + "skp" 'spacemacs/search-project-ack + "skP" 'spacemacs/search-project-ack-region-or-symbol) + + ;; set additional ivy actions + (ivy-set-actions + 'counsel-find-file + spacemacs--ivy-file-actions) + + ;; remaps built-in commands that have a counsel replacement + (counsel-mode 1) + (spacemacs|hide-lighter counsel-mode) + ;; TODO Commands to port + (spacemacs//ivy-command-not-implemented-yet "jI") + ;; Set syntax highlighting for counsel search results + (ivy-set-display-transformer 'spacemacs/counsel-search 'counsel-git-grep-transformer)))) + +(defun ivy/init-counsel-projectile () + (use-package counsel-projectile + :defer t + :init + ;; overwrite projectile settings + (spacemacs|use-package-add-hook projectile + :post-init + (progn + (setq projectile-switch-project-action 'counsel-projectile-find-file) + (spacemacs/set-leader-keys + "p SPC" 'counsel-projectile + "pb" 'counsel-projectile-switch-to-buffer + "pd" 'counsel-projectile-find-dir + "pp" 'counsel-projectile-switch-project + "pf" 'counsel-projectile-find-file + "pr" 'projectile-recentf))))) + +(defun ivy/post-init-evil () + (spacemacs/set-leader-keys + "re" 'spacemacs/ivy-evil-registers)) + +(defun ivy/init-flx ()) + +(defun ivy/init-helm-make () + (use-package helm-make + :defer t + :init + (progn + (setq helm-make-completion-method 'ivy) + (spacemacs/set-leader-keys + "cc" 'helm-make-projectile + "cm" 'helm-make)))) + +(defun ivy/post-init-imenu () + (spacemacs/set-leader-keys "ji" 'counsel-imenu)) + +(defun ivy/init-ivy () + (use-package ivy + :config + (progn + (with-eval-after-load 'recentf + ;; merge recentf and bookmarks into buffer switching. If we set this + ;; before recentf loads, then ivy-mode loads recentf for us, + ;; which messes up the spacemacs version of recentf. + (setq ivy-use-virtual-buffers t)) + ;; Key bindings + (spacemacs/set-leader-keys + "a'" 'spacemacs/ivy-available-repls + "fr" 'counsel-recentf + "rl" 'ivy-resume + "bb" 'ivy-switch-buffer) + + ;; custom actions for recentf + (ivy-set-actions + 'counsel-recentf + spacemacs--ivy-file-actions) + + (ivy-mode 1) + (global-set-key (kbd "C-c C-r") 'ivy-resume) + (global-set-key (kbd "") 'ivy-resume) + ;; Occur + (evil-make-overriding-map ivy-occur-mode-map 'normal) + (ivy-set-occur 'spacemacs/counsel-search + 'spacemacs//counsel-occur) + (spacemacs/set-leader-keys-for-major-mode 'ivy-occur-grep-mode + "w" 'ivy-wgrep-change-to-wgrep-mode) + ;; Why do we do this ? + (ido-mode -1)))) + +(defun ivy/init-ivy-hydra () + (use-package ivy-hydra)) + +(defun ivy/post-init-persp-mode () + ;; based on https://gist.github.com/Bad-ptr/1aca1ec54c3bdb2ee80996eb2b68ad2d#file-persp-ivy-el + (add-hook 'ivy-ignore-buffers #'spacemacs//layout-not-contains-buffer-p) + (setq ivy-sort-functions-alist + (append ivy-sort-functions-alist + '((persp-kill-buffer . nil) + (persp-remove-buffer . nil) + (persp-add-buffer . nil) + (persp-switch . nil) + (persp-window-switch . nil) + (persp-frame-switch . nil)))) + + (ivy-set-actions + 'spacemacs/ivy-spacemacs-layouts + '(("c" persp-kill-without-buffers "Close layout(s)") + ("k" persp-kill "Kill layout(s)"))) + (setq spacemacs-layouts-transient-state-remove-bindings + '("b" "l" "C" "X")) + (setq spacemacs-layouts-transient-state-add-bindings + '(("b" spacemacs/ivy-spacemacs-layout-buffer) + ("l" spacemacs/ivy-spacemacs-layouts :exit t) + ("C" spacemacs/ivy-spacemacs-layout-close-other :exit t) + ("X" spacemacs/ivy-spacemacs-layout-kill-other :exit t)))) + +(defun ivy/post-init-projectile () + (setq projectile-completion-system 'ivy) + (spacemacs/set-leader-keys + "pv" 'projectile-vc)) + +(defun ivy/init-smex () + (use-package smex + :defer t + :init (setq-default smex-history-length 32 + smex-save-file (concat spacemacs-cache-directory + ".smex-items")))) + +(defun ivy/init-ivy-spacemacs-help () + (use-package ivy-spacemacs-help + :commands (ivy-spacemacs-help-dotspacemacs + ivy-spacemacs-help + ivy-spacemacs-help-faq + ivy-spacemacs-help-layers + ivy-spacemacs-help-packages + ivy-spacemacs-help-docs + ivy-spacemacs-help-toggles) + :init (spacemacs/set-leader-keys + "h ." 'ivy-spacemacs-help-dotspacemacs + "h SPC" 'ivy-spacemacs-help + "h f" 'ivy-spacemacs-help-faq + "h l" 'ivy-spacemacs-help-layers + "h p" 'ivy-spacemacs-help-packages + "h r" 'ivy-spacemacs-help-docs + "h t" 'ivy-spacemacs-help-toggles))) + +(defun ivy/init-swiper () + (use-package swiper + :config + (progn + (spacemacs/set-leader-keys + "ss" 'swiper + "sS" 'spacemacs/swiper-region-or-symbol + "sb" 'swiper-all + "sB" 'spacemacs/swiper-all-region-or-symbol) + (global-set-key "\C-s" 'swiper)))) + +(defun ivy/init-wgrep () + (evil-define-key 'normal wgrep-mode-map ",," 'wgrep-finish-edit) + (evil-define-key 'normal wgrep-mode-map ",c" 'wgrep-finish-edit) + (evil-define-key 'normal wgrep-mode-map ",a" 'wgrep-abort-changes) + (evil-define-key 'normal wgrep-mode-map ",k" 'wgrep-abort-changes)) diff --git a/layers/+distributions/spacemacs-base/config.el b/layers/+distributions/spacemacs-base/config.el new file mode 100644 index 0000000..8fededb --- /dev/null +++ b/layers/+distributions/spacemacs-base/config.el @@ -0,0 +1,211 @@ +;;; config.el --- Spacemacs Base Layer configuration File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; --------------------------------------------------------------------------- +;; Navigation +;; --------------------------------------------------------------------------- + +;; Auto refresh +(global-auto-revert-mode 1) +;; Also auto refresh dired, but be quiet about it +(setq global-auto-revert-non-file-buffers t + auto-revert-verbose nil) + +;; Make dired "guess" target directory for some operations, like copy to +;; directory visited in other split buffer. +(setq dired-dwim-target t) + +;; Regexp for useful and useless buffers for smarter buffer switching +(defvar spacemacs-useless-buffers-regexp '("*\.\+") + "Regexp used to determine if a buffer is not useful.") +(defvar spacemacs-useful-buffers-regexp '("\\*scratch\\*") + "Regexp used to define buffers that are useful despite matching +`spacemacs-useless-buffers-regexp'.") + +;; no beep pleeeeeease ! (and no visual blinking too please) +(setq ring-bell-function 'ignore + visible-bell nil) + +;; Hack to fix a bug with tabulated-list.el +;; see: http://redd.it/2dgy52 +(defun tabulated-list-revert (&rest ignored) + "The `revert-buffer-function' for `tabulated-list-mode'. +It runs `tabulated-list-revert-hook', then calls `tabulated-list-print'." + (interactive) + (unless (derived-mode-p 'tabulated-list-mode) + (error "The current buffer is not in Tabulated List mode")) + (run-hooks 'tabulated-list-revert-hook) + ;; hack is here + ;; (tabulated-list-print t) + (tabulated-list-print)) + +;; Mouse cursor in terminal mode +(xterm-mouse-mode 1) + +;; Highlight and allow to open http link at point in programming buffers +;; goto-address-prog-mode only highlights links in strings and comments +(add-hook 'prog-mode-hook 'goto-address-prog-mode) +;; Highlight and follow bug references in comments and strings +(add-hook 'prog-mode-hook 'bug-reference-prog-mode) + +;; Keep focus while navigating help buffers +(setq help-window-select 't) + +;; Scroll compilation to first error or end +(setq compilation-scroll-output 'first-error) + +;; Don't try to ping things that look like domain names +(setq ffap-machine-p-known 'reject) + +;; --------------------------------------------------------------------------- +;; Edit +;; --------------------------------------------------------------------------- + +;; start scratch in text mode (usefull to get a faster Emacs load time +;; because it avoids autoloads of elisp modes) +(setq initial-major-mode 'text-mode) + +;; use only spaces and no tabs +(setq-default indent-tabs-mode nil + tab-width 2) + +;; Text +(setq longlines-show-hard-newlines t) + +;; Use system trash for file deletion +;; should work on Windows and Linux distros +;; on OS X, see contrib/osx layer +(setq delete-by-moving-to-trash t) + +;; auto fill breaks line beyond buffer's fill-column +(setq-default fill-column 80) +(spacemacs|diminish auto-fill-function " Ⓕ" " F") + +;; persistent abbreviation file +(setq abbrev-file-name (concat spacemacs-cache-directory "abbrev_defs")) + +;; Save clipboard contents into kill-ring before replace them +(setq save-interprogram-paste-before-kill t) + +;; Single space between sentences is more widespread than double +(setq-default sentence-end-double-space nil) + +;; The C-d rebinding that most shell-like buffers inherit from +;; comint-mode assumes non-evil configuration with its +;; `comint-delchar-or-maybe-eof' function, so we disable it +(with-eval-after-load 'comint + (define-key comint-mode-map (kbd "C-d") nil)) + +;; Prompt to open file literally if large file. +(add-hook 'find-file-hook 'spacemacs/check-large-file) + +;; --------------------------------------------------------------------------- +;; UI +;; --------------------------------------------------------------------------- + +;; important for golden-ratio to better work +(setq window-combination-resize t) +;; Show column number in mode line +(setq column-number-mode t) + +;; highlight current line +(global-hl-line-mode t) +;; no blink +(blink-cursor-mode 0) +;; When emacs asks for "yes" or "no", let "y" or "n" suffice +(fset 'yes-or-no-p 'y-or-n-p) +;; draw underline lower +(setq x-underline-at-descent-line t) +;; don't let the cursor go into minibuffer prompt +;; Tip taken from Xah Lee: http://ergoemacs.org/emacs/emacs_stop_cursor_enter_prompt.html +(setq minibuffer-prompt-properties + '(read-only t point-entered minibuffer-avoid-prompt face minibuffer-prompt)) +;; Fullscreen/maximize frame on startup +(if dotspacemacs-fullscreen-at-startup + ;; spacemacs/toggle-fullscreen-frame-on is NOT available during the startup, + ;; but IS available during the subsequent config reloads + (if (fboundp 'spacemacs/toggle-fullscreen-frame-on) + (spacemacs/toggle-fullscreen-frame-on) + (spacemacs/toggle-frame-fullscreen)) + (if dotspacemacs-maximized-at-startup + (add-hook 'window-setup-hook 'toggle-frame-maximized))) + +(setq ns-use-native-fullscreen (not dotspacemacs-fullscreen-use-non-native)) + +;; make `next-buffer', `other-buffer', etc. ignore useless buffers (see +;; `spacemacs/useless-buffer-p') +(let ((buf-pred-entry (assq 'buffer-predicate default-frame-alist))) + (if buf-pred-entry + ;; `buffer-predicate' entry exists, modify it + (setcdr buf-pred-entry #'spacemacs/useful-buffer-p) + ;; `buffer-predicate' entry doesn't exist, create it + (push '(buffer-predicate . spacemacs/useful-buffer-p) default-frame-alist))) + +;; --------------------------------------------------------------------------- +;; Session +;; --------------------------------------------------------------------------- + +;; save custom variables in ~/.spacemacs +(unless (bound-and-true-p custom-file) + (setq custom-file (dotspacemacs/location))) +;; scratch buffer empty +(setq initial-scratch-message nil) +;; don't create backup~ files +(setq make-backup-files nil) + +;; Auto-save file +(setq auto-save-default (not (null dotspacemacs-auto-save-file-location))) +(setq auto-save-list-file-prefix (concat spacemacs-auto-save-directory)) +;; always save TRAMP URLs to cache directory no matter what is the value +;; of `dotspacemacs-auto-save-file-location' +(let ((autosave-dir (concat spacemacs-auto-save-directory "dist/"))) + (setq auto-save-file-name-transforms + `(("\\`/[^/]*:\\([^/]*/\\)*\\([^/]*\\)\\'" ,autosave-dir t))) + (unless (or (file-exists-p autosave-dir) + (null dotspacemacs-auto-save-file-location)) + (make-directory autosave-dir t))) +;; Choose auto-save location +(cl-case dotspacemacs-auto-save-file-location + (cache (let ((autosave-dir (concat spacemacs-auto-save-directory "site/"))) + (add-to-list 'auto-save-file-name-transforms + `(".*" ,autosave-dir t) 'append) + (unless (file-exists-p autosave-dir) + (make-directory autosave-dir t)))) + (original (setq auto-save-visited-file-name t)) + (_ (setq auto-save-default nil + auto-save-list-file-prefix nil))) + +;; remove annoying ellipsis when printing sexp in message buffer +(setq eval-expression-print-length nil + eval-expression-print-level nil) + +;; cache files +(setq tramp-persistency-file-name (concat spacemacs-cache-directory "tramp")) + +;; seems pointless to warn. There's always undo. +(put 'narrow-to-region 'disabled nil) +(put 'upcase-region 'disabled nil) +(put 'downcase-region 'disabled nil) +(put 'erase-buffer 'disabled nil) +(put 'scroll-left 'disabled nil) +(put 'dired-find-alternate-file 'disabled nil) +;; remove prompt if the file is opened in other clients +(defun server-remove-kill-buffer-hook () + (remove-hook 'kill-buffer-query-functions 'server-kill-buffer-query-function)) +(add-hook 'server-visit-hook 'server-remove-kill-buffer-hook) + +;; --------------------------------------------------------------------------- +;; Other +;; --------------------------------------------------------------------------- + +;; hook into `hack-local-variables' in order to allow switching spacemacs +;; configurations based on local variables +(add-hook 'hack-local-variables-hook #'spacemacs//run-local-vars-mode-hook) diff --git a/layers/+distributions/spacemacs-base/funcs.el b/layers/+distributions/spacemacs-base/funcs.el new file mode 100644 index 0000000..c4550ab --- /dev/null +++ b/layers/+distributions/spacemacs-base/funcs.el @@ -0,0 +1,910 @@ +;;; funcs.el --- Spacemacs Base Layer functions File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(require 'cl-lib) + +(defun spacemacs//run-local-vars-mode-hook () + "Run a hook for the major-mode after the local variables have been processed." + (run-hooks (intern (format "%S-local-vars-hook" major-mode)))) + +(defun spacemacs/split-and-new-line () + "Split a quoted string or s-expression and insert a new line with +auto-indent." + (interactive) + (sp-split-sexp 1) + (sp-newline)) + +(defun spacemacs/push-mark-and-goto-beginning-of-line () + "Push a mark at current location and go to the beginning of the line." + (interactive) + (push-mark (point)) + (evil-beginning-of-line)) + +(defun spacemacs/push-mark-and-goto-end-of-line () + "Push a mark at current location and go to the end of the line." + (interactive) + (push-mark (point)) + (evil-end-of-line)) + +(defun spacemacs/evil-insert-line-above (count) + "Insert one or several lines above the current point's line without changing +the current state and point position." + (interactive "p") + (dotimes (_ count) (save-excursion (evil-insert-newline-above)))) + +(defun spacemacs/evil-insert-line-below (count) + "Insert one or several lines below the current point's line without changing +the current state and point position." + (interactive "p") + (dotimes (_ count) (save-excursion (evil-insert-newline-below)))) + +(defun spacemacs/evil-goto-next-line-and-indent (&optional count) + (interactive "p") + (let ((counter (or count 1))) + (while (> counter 0) + (join-line 1) + (newline-and-indent) + (setq counter (1- counter))))) + +;; from Prelude +;; TODO: dispatch these in the layers +(defvar spacemacs-indent-sensitive-modes + '(coffee-mode + elm-mode + haml-mode + haskell-mode + slim-mode + makefile-mode + makefile-bsdmake-mode + makefile-gmake-mode + makefile-imake-mode + python-mode + yaml-mode) + "Modes for which auto-indenting is suppressed.") + +(defcustom spacemacs-yank-indent-threshold 1000 + "Threshold (# chars) over which indentation does not automatically occur." + :type 'number + :group 'spacemacs) + +(defcustom spacemacs-large-file-modes-list + '(archive-mode tar-mode jka-compr git-commit-mode image-mode + doc-view-mode doc-view-mode-maybe ebrowse-tree-mode + pdf-view-mode) + "Major modes which `spacemacs/check-large-file' will not be +automatically applied to." + :group 'spacemacs + :type '(list symbol)) + + +(defun spacemacs/indent-region-or-buffer () + "Indent a region if selected, otherwise the whole buffer." + (interactive) + (unless (member major-mode spacemacs-indent-sensitive-modes) + (save-excursion + (if (region-active-p) + (progn + (indent-region (region-beginning) (region-end)) + (message "Indented selected region.")) + (progn + (evil-indent (point-min) (point-max)) + (message "Indented buffer."))) + (whitespace-cleanup)))) + +;; from https://gist.github.com/3402786 +(defun spacemacs/toggle-maximize-buffer () + "Maximize buffer" + (interactive) + (if (and (= 1 (length (window-list))) + (assoc ?_ register-alist)) + (jump-to-register ?_) + (progn + (window-configuration-to-register ?_) + (delete-other-windows)))) + +;; https://tsdh.wordpress.com/2007/03/28/deleting-windows-vertically-or-horizontally/ +(defun spacemacs/maximize-horizontally () + "Delete all windows left or right of the current window." + (interactive) + (require 'windmove) + (save-excursion + (while (condition-case nil (windmove-left) (error nil)) + (delete-window)) + (while (condition-case nil (windmove-right) (error nil)) + (delete-window)))) + +(defun spacemacs/toggle-centered-buffer-mode () + "Toggle `spacemacs-centered-buffer-mode'." + (interactive) + (when (require 'centered-buffer-mode nil t) + (call-interactively 'spacemacs-centered-buffer-mode))) + +(defun spacemacs/centered-buffer-mode-full-width () + "Center buffer in the frame." + (interactive) + (when (require 'centered-buffer-mode nil t) + (spacemacs/maximize-horizontally) + (call-interactively 'spacemacs-centered-buffer-mode))) + +(defun spacemacs/useful-buffer-p (buffer) + "Determines if a buffer is useful." + (let ((buf-name (buffer-name buffer))) + (or (with-current-buffer buffer + (derived-mode-p 'comint-mode)) + (cl-loop for useful-regexp in spacemacs-useful-buffers-regexp + thereis (string-match-p useful-regexp buf-name)) + (cl-loop for useless-regexp in spacemacs-useless-buffers-regexp + never (string-match-p useless-regexp buf-name))))) + +(defun spacemacs/useless-buffer-p (buffer) + "Determines if a buffer is useless." + (not (spacemacs/useful-buffer-p buffer))) + +;; from magnars modified by ffevotte for dedicated windows support +(defun spacemacs/rotate-windows (count) + "Rotate each window forwards. +A negative prefix argument rotates each window backwards. +Dedicated (locked) windows are left untouched." + (interactive "p") + (let* ((non-dedicated-windows (remove-if 'window-dedicated-p (window-list))) + (num-windows (length non-dedicated-windows)) + (i 0) + (step (+ num-windows count))) + (cond ((not (> num-windows 1)) + (message "You can't rotate a single window!")) + (t + (dotimes (counter (- num-windows 1)) + (let* ((next-i (% (+ step i) num-windows)) + + (w1 (elt non-dedicated-windows i)) + (w2 (elt non-dedicated-windows next-i)) + + (b1 (window-buffer w1)) + (b2 (window-buffer w2)) + + (s1 (window-start w1)) + (s2 (window-start w2))) + (set-window-buffer w1 b2) + (set-window-buffer w2 b1) + (set-window-start w1 s2) + (set-window-start w2 s1) + (setq i next-i))))))) + +(defun spacemacs/rotate-windows-backward (count) + "Rotate each window backwards. +Dedicated (locked) windows are left untouched." + (interactive "p") + (spacemacs/rotate-windows (* -1 count))) + +(defun spacemacs/rename-file (filename &optional new-filename) + "Rename FILENAME to NEW-FILENAME. + +When NEW-FILENAME is not specified, asks user for a new name. + +Also renames associated buffer (if any exists), invalidates +projectile cache when it's possible and update recentf list." + (interactive "f") + (when (and filename (file-exists-p filename)) + (let* ((buffer (find-buffer-visiting filename)) + (short-name (file-name-nondirectory filename)) + (new-name (if new-filename new-filename + (read-file-name + (format "Rename %s to: " short-name))))) + (cond ((get-buffer new-name) + (error "A buffer named '%s' already exists!" new-name)) + (t + (let ((dir (file-name-directory new-name))) + (when (and (not (file-exists-p dir)) (yes-or-no-p (format "Create directory '%s'?" dir))) + (make-directory dir t))) + (rename-file filename new-name 1) + (when buffer + (kill-buffer buffer) + (find-file new-name)) + (when (fboundp 'recentf-add-file) + (recentf-add-file new-name) + (recentf-remove-if-non-kept filename)) + (when (and (configuration-layer/package-usedp 'projectile) + (projectile-project-p)) + (call-interactively #'projectile-invalidate-cache)) + (message "File '%s' successfully renamed to '%s'" short-name (file-name-nondirectory new-name))))))) + +;; from magnars +(defun spacemacs/rename-current-buffer-file () + "Renames current buffer and file it is visiting." + (interactive) + (let* ((name (buffer-name)) + (filename (buffer-file-name)) + (dir (file-name-directory filename))) + (if (not (and filename (file-exists-p filename))) + (error "Buffer '%s' is not visiting a file!" name) + (let ((new-name (read-file-name "New name: " dir))) + (cond ((get-buffer new-name) + (error "A buffer named '%s' already exists!" new-name)) + (t + (let ((dir (file-name-directory new-name))) + (when (and (not (file-exists-p dir)) (yes-or-no-p (format "Create directory '%s'?" dir))) + (make-directory dir t))) + (rename-file filename new-name 1) + (rename-buffer new-name) + (set-visited-file-name new-name) + (set-buffer-modified-p nil) + (when (fboundp 'recentf-add-file) + (recentf-add-file new-name) + (recentf-remove-if-non-kept filename)) + (when (and (configuration-layer/package-usedp 'projectile) + (projectile-project-p)) + (call-interactively #'projectile-invalidate-cache)) + (message "File '%s' successfully renamed to '%s'" name (file-name-nondirectory new-name)))))))) + +(defun spacemacs/delete-file (filename &optional ask-user) + "Remove specified file or directory. + +Also kills associated buffer (if any exists) and invalidates +projectile cache when it's possible. + +When ASK-USER is non-nil, user will be asked to confirm file +removal." + (interactive "f") + (when (and filename (file-exists-p filename)) + (let ((buffer (find-buffer-visiting filename))) + (when buffer + (kill-buffer buffer))) + (when (or (not ask-user) + (yes-or-no-p "Are you sure you want to delete this file? ")) + (delete-file filename) + (when (and (configuration-layer/package-usedp 'projectile) + (projectile-project-p)) + (call-interactively #'projectile-invalidate-cache))))) + +;; from magnars +(defun spacemacs/delete-current-buffer-file () + "Removes file connected to current buffer and kills buffer." + (interactive) + (let ((filename (buffer-file-name)) + (buffer (current-buffer)) + (name (buffer-name))) + (if (not (and filename (file-exists-p filename))) + (ido-kill-buffer) + (when (yes-or-no-p "Are you sure you want to delete this file? ") + (delete-file filename t) + (kill-buffer buffer) + (when (and (configuration-layer/package-usedp 'projectile) + (projectile-project-p)) + (call-interactively #'projectile-invalidate-cache)) + (message "File '%s' successfully removed" filename))))) + +;; from magnars +(defun spacemacs/sudo-edit (&optional arg) + (interactive "p") + (let ((fname (if (or arg (not buffer-file-name)) + (read-file-name "File: ") + buffer-file-name))) + (find-file + (cond ((string-match-p "^/ssh:" fname) + (with-temp-buffer + (insert fname) + (search-backward ":") + (let ((last-match-end nil) + (last-ssh-hostname nil)) + (while (string-match "@\\\([^:|]+\\\)" fname last-match-end) + (setq last-ssh-hostname (or (match-string 1 fname) + last-ssh-hostname)) + (setq last-match-end (match-end 0))) + (insert (format "|sudo:%s" (or last-ssh-hostname "localhost")))) + (buffer-string))) + (t (concat "/sudo:root@localhost:" fname)))))) + +;; check when opening large files - literal file open +(defun spacemacs/check-large-file () + (let* ((filename (buffer-file-name)) + (size (nth 7 (file-attributes filename)))) + (when (and + (not (memq major-mode spacemacs-large-file-modes-list)) + size (> size (* 1024 1024 dotspacemacs-large-file-size)) + (y-or-n-p (format (concat "%s is a large file, open literally to " + "avoid performance issues?") + filename))) + (setq buffer-read-only t) + (buffer-disable-undo) + (fundamental-mode)))) + +(defun spacemacs/delete-window (&optional arg) + "Delete the current window. +If the universal prefix argument is used then kill the buffer too." + (interactive "P") + (if (equal '(4) arg) + (kill-buffer-and-window) + (delete-window))) + +(defun spacemacs/ace-delete-window (&optional arg) + "Ace delete window. +If the universal prefix argument is used then kill the buffer too." + (interactive "P") + (require 'ace-window) + (aw-select + " Ace - Delete Window" + (lambda (window) + (when (equal '(4) arg) + (with-selected-window window + (spacemacs/kill-this-buffer arg))) + (aw-delete-window window)))) + +;; our own implementation of kill-this-buffer from menu-bar.el +(defun spacemacs/kill-this-buffer (&optional arg) + "Kill the current buffer. +If the universal prefix argument is used then kill also the window." + (interactive "P") + (if (window-minibuffer-p) + (abort-recursive-edit) + (if (equal '(4) arg) + (kill-buffer-and-window) + (kill-buffer)))) + +(defun spacemacs/ace-kill-this-buffer (&optional arg) + "Ace kill visible buffer in a window. +If the universal prefix argument is used then kill also the window." + (interactive "P") + (require 'ace-window) + (let (golden-ratio-mode) + (aw-select + " Ace - Kill buffer in Window" + (lambda (window) + (with-selected-window window + (spacemacs/kill-this-buffer arg)))))) + +;; found at http://emacswiki.org/emacs/KillingBuffers +(defun spacemacs/kill-other-buffers (&optional arg) + "Kill all other buffers. +If the universal prefix argument is used then will the windows too." + (interactive "P") + (when (yes-or-no-p (format "Killing all buffers except \"%s\"? " + (buffer-name))) + (mapc 'kill-buffer (delq (current-buffer) (buffer-list))) + (when (equal '(4) arg) (delete-other-windows)) + (message "Buffers deleted!"))) + +;; from http://dfan.org/blog/2009/02/19/emacs-dedicated-windows/ +(defun spacemacs/toggle-current-window-dedication () + "Toggle dedication state of a window." + (interactive) + (let* ((window (selected-window)) + (dedicated (window-dedicated-p window))) + (set-window-dedicated-p window (not dedicated)) + (message "Window %sdedicated to %s" + (if dedicated "no longer " "") + (buffer-name)))) + +;; http://camdez.com/blog/2013/11/14/emacs-show-buffer-file-name/ +(defun spacemacs/show-and-copy-buffer-filename () + "Show and copy the full path to the current file in the minibuffer." + (interactive) + ;; list-buffers-directory is the variable set in dired buffers + (let ((file-name (or (buffer-file-name) list-buffers-directory))) + (if file-name + (message (kill-new file-name)) + (error "Buffer not visiting a file")))) + +;; adapted from bozhidar +;; http://emacsredux.com/blog/2013/05/18/instant-access-to-init-dot-el/ +(defun spacemacs/find-user-init-file () + "Edit the `user-init-file', in the current window." + (interactive) + (find-file-existing user-init-file)) + +(defun spacemacs/find-dotfile () + "Edit the `dotfile', in the current window." + (interactive) + (find-file-existing (dotspacemacs/location))) + +(defun spacemacs/ediff-dotfile-and-template () + "ediff the current `dotfile' with the template" + (interactive) + (ediff-files (dotspacemacs/location) + (concat dotspacemacs-template-directory ".spacemacs.template"))) + +(defun spacemacs/new-empty-buffer () + "Create a new buffer called untitled()" + (interactive) + (let ((newbuf (generate-new-buffer-name "untitled"))) + (switch-to-buffer newbuf))) + +;; from https://gist.github.com/timcharper/493269 +(defun spacemacs/split-window-vertically-and-switch () + (interactive) + (split-window-vertically) + (other-window 1)) + +(defun spacemacs/split-window-horizontally-and-switch () + (interactive) + (split-window-horizontally) + (other-window 1)) + +(defun spacemacs/layout-triple-columns () + " Set the layout to triple columns. " + (interactive) + (delete-other-windows) + (dotimes (i 2) (split-window-right)) + (balance-windows)) + +(defun spacemacs/layout-double-columns () + " Set the layout to double columns. " + (interactive) + (delete-other-windows) + (split-window-right)) + +(defun spacemacs/insert-line-above-no-indent (count) + "Insert a new line above with no indentation." + (interactive "p") + (let ((p (+ (point) count))) + (save-excursion + (if (eq (line-number-at-pos) 1) + (evil-move-beginning-of-line) + (progn + (evil-previous-line) + (evil-move-end-of-line))) + (while (> count 0) + (insert "\n") + (setq count (1- count)))) + (goto-char p))) + +(defun spacemacs/insert-line-below-no-indent (count) + "Insert a new line below with no indentation." + (interactive "p") + (save-excursion + (evil-move-end-of-line) + (while (> count 0) + (insert "\n") + (setq count (1- count))))) + +;; from https://github.com/gempesaw/dotemacs/blob/emacs/dg-defun.el +(defun spacemacs/kill-matching-buffers-rudely (regexp &optional internal-too) + "Kill buffers whose name matches the specified REGEXP. This +function, unlike the built-in `kill-matching-buffers` does so +WITHOUT ASKING. The optional second argument indicates whether to +kill internal buffers too." + (interactive "sKill buffers matching this regular expression: \nP") + (dolist (buffer (buffer-list)) + (let ((name (buffer-name buffer))) + (when (and name (not (string-equal name "")) + (or internal-too (/= (aref name 0) ?\s)) + (string-match regexp name)) + (kill-buffer buffer))))) + +;; advise to prevent server from closing + +(defvar spacemacs-really-kill-emacs nil + "prevent window manager close from closing instance.") + +(defun spacemacs//persistent-server-running-p () + "Requires spacemacs-really-kill-emacs to be toggled and +dotspacemacs-persistent-server to be t" + (and (fboundp 'server-running-p) + (server-running-p) + dotspacemacs-persistent-server)) + +(defadvice kill-emacs (around spacemacs-really-exit activate) + "Only kill emacs if a prefix is set" + (if (and (not spacemacs-really-kill-emacs) + (spacemacs//persistent-server-running-p)) + (spacemacs/frame-killer) + ad-do-it)) + +(defadvice save-buffers-kill-emacs (around spacemacs-really-exit activate) + "Only kill emacs if a prefix is set" + (if (or spacemacs-really-kill-emacs (not dotspacemacs-persistent-server)) + ad-do-it + (spacemacs/frame-killer))) + +(defun spacemacs/save-buffers-kill-emacs () + "Save all changed buffers and exit Spacemacs" + (interactive) + (setq spacemacs-really-kill-emacs t) + (save-buffers-kill-emacs)) + +(defun spacemacs/kill-emacs () + "Lose all changes and exit Spacemacs" + (interactive) + (setq spacemacs-really-kill-emacs t) + (kill-emacs)) + +(defun spacemacs/prompt-kill-emacs () + "Prompt to save changed buffers and exit Spacemacs" + (interactive) + (setq spacemacs-really-kill-emacs t) + (save-some-buffers) + (kill-emacs)) + +(defun spacemacs/frame-killer () + "Kill server buffer and hide the main Emacs window" + (interactive) + (condition-case-unless-debug nil + (delete-frame nil 1) + (error + (make-frame-invisible nil 1)))) + +(defun spacemacs/toggle-frame-fullscreen () + "Respect the `dotspacemacs-fullscreen-use-non-native' variable when +toggling fullscreen." + (interactive) + (if dotspacemacs-fullscreen-use-non-native + (spacemacs/toggle-frame-fullscreen-non-native) + (toggle-frame-fullscreen))) + +(defun spacemacs/toggle-fullscreen () + "Toggle full screen on X11 and Carbon" + (interactive) + (cond + ((eq window-system 'x) + (set-frame-parameter nil 'fullscreen + (when (not (frame-parameter nil 'fullscreen)) + 'fullboth))) + ((eq window-system 'mac) + (set-frame-parameter + nil 'fullscreen + (when (not (frame-parameter nil 'fullscreen)) 'fullscreen))))) + +(defun spacemacs/toggle-frame-fullscreen-non-native () + "Toggle full screen non-natively. Uses the `fullboth' frame paramerter + rather than `fullscreen'. Useful to fullscreen on OSX w/o animations." + (interactive) + (modify-frame-parameters + nil + `((maximized + . ,(unless (memq (frame-parameter nil 'fullscreen) '(fullscreen fullboth)) + (frame-parameter nil 'fullscreen))) + (fullscreen + . ,(if (memq (frame-parameter nil 'fullscreen) '(fullscreen fullboth)) + (if (eq (frame-parameter nil 'maximized) 'maximized) + 'maximized) + 'fullboth))))) + +;; taken from Prelude: https://github.com/bbatsov/prelude +(defmacro spacemacs|advise-commands (advice-name commands class &rest body) + "Apply advice named ADVICE-NAME to multiple COMMANDS. +The body of the advice is in BODY." + `(progn + ,@(mapcar (lambda (command) + `(defadvice ,command + (,class ,(intern (format "%S-%s" command advice-name)) + activate) + ,@body)) + commands))) + +(defun spacemacs/safe-revert-buffer () + "Prompt before reverting the file." + (interactive) + (revert-buffer nil nil)) + +(defun spacemacs/safe-erase-buffer () + "Prompt before erasing the content of the file." + (interactive) + (if (y-or-n-p (format "Erase content of buffer %s ? " (current-buffer))) + (erase-buffer))) + +(defun spacemacs//find-ert-test-buffer (ert-test) + "Return the buffer where ERT-TEST is defined." + (car (find-definition-noselect (ert-test-name ert-test) 'ert-deftest))) + +(defun spacemacs/ert-run-tests-buffer () + "Run all the tests in the current buffer." + (interactive) + (save-buffer) + (load-file (buffer-file-name)) + (let ((cbuf (current-buffer))) + (ert '(satisfies (lambda (test) + (eq cbuf (spacemacs//find-ert-test-buffer test))))))) + +(defun spacemacs//open-in-external-app (file-path) + "Open `file-path' in external application." + (cond + ((spacemacs/system-is-mswindows) (w32-shell-execute "open" (replace-regexp-in-string "/" "\\\\" file-path))) + ((spacemacs/system-is-mac) (shell-command (format "open \"%s\"" file-path))) + ((spacemacs/system-is-linux) (let ((process-connection-type nil)) + (start-process "" nil "xdg-open" file-path))))) + +(defun spacemacs/open-file-or-directory-in-external-app (arg) + "Open current file in external application. +If the universal prefix argument is used then open the folder +containing the current file by the default explorer." + (interactive "P") + (if arg + (spacemacs//open-in-external-app (expand-file-name default-directory)) + (let ((file-path (if (derived-mode-p 'dired-mode) + (dired-get-file-for-visit) + buffer-file-name))) + (if file-path + (spacemacs//open-in-external-app file-path) + (message "No file associated to this buffer."))))) + +(defun spacemacs/switch-to-minibuffer-window () + "switch to minibuffer window (if active)" + (interactive) + (when (active-minibuffer-window) + (select-window (active-minibuffer-window)))) + +;; http://stackoverflow.com/a/10216338/4869 +(defun spacemacs/copy-whole-buffer-to-clipboard () + "Copy entire buffer to clipboard" + (interactive) + (clipboard-kill-ring-save (point-min) (point-max))) + +(defun spacemacs/copy-clipboard-to-whole-buffer () + "Copy clipboard and replace buffer" + (interactive) + (delete-region (point-min) (point-max)) + (clipboard-yank) + (deactivate-mark)) + +;; BEGIN align functions + +;; modified function from http://emacswiki.org/emacs/AlignCommands +(defun spacemacs/align-repeat (start end regexp &optional justify-right after) + "Repeat alignment with respect to the given regular expression. +If JUSTIFY-RIGHT is non nil justify to the right instead of the +left. If AFTER is non-nil, add whitespace to the left instead of +the right." + (interactive "r\nsAlign regexp: ") + (let* ((ws-regexp (if (string-empty-p regexp) + "\\(\\s-+\\)" + "\\(\\s-*\\)")) + (complete-regexp (if after + (concat regexp ws-regexp) + (concat ws-regexp regexp))) + (group (if justify-right -1 1))) + (message "%S" complete-regexp) + (align-regexp start end complete-regexp group 1 t))) + +;; Modified answer from http://emacs.stackexchange.com/questions/47/align-vertical-columns-of-numbers-on-the-decimal-point +(defun spacemacs/align-repeat-decimal (start end) + "Align a table of numbers on decimal points and dollar signs (both optional)" + (interactive "r") + (require 'align) + (align-region start end nil + '((nil (regexp . "\\([\t ]*\\)\\$?\\([\t ]+[0-9]+\\)\\.?") + (repeat . t) + (group 1 2) + (spacing 1 1) + (justify nil t))) + nil)) + +(defmacro spacemacs|create-align-repeat-x (name regexp &optional justify-right default-after) + (let ((new-func (intern (concat "spacemacs/align-repeat-" name)))) + `(defun ,new-func (start end switch) + (interactive "r\nP") + (let ((after (not (eq (if switch t nil) (if ,default-after t nil))))) + (spacemacs/align-repeat start end ,regexp ,justify-right after))))) + +(spacemacs|create-align-repeat-x "comma" "," nil t) +(spacemacs|create-align-repeat-x "semicolon" ";" nil t) +(spacemacs|create-align-repeat-x "colon" ":" nil t) +(spacemacs|create-align-repeat-x "equal" "=") +(spacemacs|create-align-repeat-x "math-oper" "[+\\-*/]") +(spacemacs|create-align-repeat-x "ampersand" "&") +(spacemacs|create-align-repeat-x "bar" "|") +(spacemacs|create-align-repeat-x "left-paren" "(") +(spacemacs|create-align-repeat-x "right-paren" ")" t) +(spacemacs|create-align-repeat-x "backslash" "\\\\") + +;; END align functions + +(defun spacemacs/dos2unix () + "Converts the current buffer to UNIX file format." + (interactive) + (set-buffer-file-coding-system 'undecided-unix nil)) + +(defun spacemacs/unix2dos () + "Converts the current buffer to DOS file format." + (interactive) + (set-buffer-file-coding-system 'undecided-dos nil)) + +(defun spacemacs/copy-file () + "Write the file under new name." + (interactive) + (call-interactively 'write-file)) + +(defun spacemacs/uniquify-lines () + "Remove duplicate adjacent lines in region or current buffer" + (interactive) + (save-excursion + (save-restriction + (let ((beg (if (region-active-p) (region-beginning) (point-min))) + (end (if (region-active-p) (region-end) (point-max)))) + (goto-char beg) + (while (re-search-forward "^\\(.*\n\\)\\1+" end t) + (replace-match "\\1")))))) + +(defun spacemacs/sort-lines () + "Sort lines in region or current buffer" + (interactive) + (let ((beg (if (region-active-p) (region-beginning) (point-min))) + (end (if (region-active-p) (region-end) (point-max)))) + (sort-lines nil beg end))) + +;; BEGIN linum mouse helpers + +(defvar spacemacs-linum-mdown-line nil + "Define persistent variable for linum selection") + +(defun spacemacs//line-at-click () + "Determine the visual line at click" + (save-excursion + (let ((click-y (cddr (mouse-position))) + (debug-on-error t) + (line-move-visual t)) + (goto-char (window-start)) + (next-line (1- click-y)) + (1+ (line-number-at-pos)) + ))) + +(defun spacemacs/md-select-linum (event) + "Set point as spacemacs-linum-mdown-line" + (interactive "e") + (mouse-select-window event) + (goto-line (spacemacs//line-at-click)) + (set-mark (point)) + (setq spacemacs-linum-mdown-line + (line-number-at-pos))) + +(defun spacemacs/mu-select-linum () + "Select code block between point and spacemacs-linum-mdown-line" + (interactive) + (when spacemacs-linum-mdown-line + (let (mu-line) + (setq mu-line (spacemacs//line-at-click)) + (goto-line (max spacemacs-linum-mdown-line mu-line)) + (set-mark (line-end-position)) + (goto-line (min spacemacs-linum-mdown-line mu-line)) + (setq spacemacs-linum-mdown-line nil)))) + +(defun spacemacs/select-current-block () + "Select the current block of text between blank lines." + (interactive) + (let (p1 p2) + (progn + (if (re-search-backward "\n[ \t]*\n" nil "move") + (progn (re-search-forward "\n[ \t]*\n") + (setq p1 (point))) + (setq p1 (point))) + (if (re-search-forward "\n[ \t]*\n" nil "move") + (progn (re-search-backward "\n[ \t]*\n") + (setq p2 (point))) + (setq p2 (point)))) + (set-mark p1))) + +;; END linum mouse helpers + +;; From http://xugx2007.blogspot.ca/2007/06/benjamin-rutts-emacs-c-development-tips.html +(setq compilation-finish-function + (lambda (buf str) + + (if (or (string-match "exited abnormally" str) + (string-match "FAILED" (buffer-string))) + + ;; there were errors + (message "There were errors. SPC-e-n to visit.") + (unless (or (string-match "Grep finished" (buffer-string)) + (string-match "Ag finished" (buffer-string)) + (string-match "nosetests" (buffer-name))) + + ;; no errors + (message "compilation ok."))))) + +;; from http://www.emacswiki.org/emacs/WordCount +(defun spacemacs/count-words-analysis (start end) + "Count how many times each word is used in the region. + Punctuation is ignored." + (interactive "r") + (let (words alist_words_compare (formated "")) + (save-excursion + (goto-char start) + (while (re-search-forward "\\w+" end t) + (let* ((word (intern (match-string 0))) + (cell (assq word words))) + (if cell + (setcdr cell (1+ (cdr cell))) + (setq words (cons (cons word 1) words)))))) + (defun alist_words_compare (a b) + "Compare elements from an associative list of words count. +Compare them on count first,and in case of tie sort them alphabetically." + (let ((a_key (car a)) + (a_val (cdr a)) + (b_key (car b)) + (b_val (cdr b))) + (if (eq a_val b_val) + (string-lessp a_key b_key) + (> a_val b_val)))) + (setq words (cl-sort words 'alist_words_compare)) + (while words + (let* ((word (pop words)) + (name (car word)) + (count (cdr word))) + (setq formated (concat formated (format "[%s: %d], " name count))))) + (when (interactive-p) + (if (> (length formated) 2) + (message (substring formated 0 -2)) + (message "No words."))) + words)) + +;; indent on paste +;; from Prelude: https://github.com/bbatsov/prelude +(defun spacemacs/yank-advised-indent-function (beg end) + "Do indentation, as long as the region isn't too large." + (if (<= (- end beg) spacemacs-yank-indent-threshold) + (indent-region beg end nil))) + +(spacemacs|advise-commands + "indent" (yank yank-pop evil-paste-before evil-paste-after) around + "If current mode is not one of spacemacs-indent-sensitive-modes + indent yanked text (with universal arg don't indent)." + (evil-start-undo-step) + ad-do-it + (if (and (not (equal '(4) (ad-get-arg 0))) + (not (member major-mode spacemacs-indent-sensitive-modes)) + (or (derived-mode-p 'prog-mode) + (member major-mode spacemacs-indent-sensitive-modes))) + (let ((transient-mark-mode nil) + (save-undo buffer-undo-list)) + (spacemacs/yank-advised-indent-function (region-beginning) + (region-end)))) + (evil-end-undo-step)) + +;; find file functions in split +(defun spacemacs//display-in-split (buffer alist) + "Split selected window and display BUFFER in the new window. +BUFFER and ALIST have the same form as in `display-buffer'. If ALIST contains +a split-side entry, its value must be usable as the SIDE argument for +`split-window'." + (let ((window (split-window nil nil (cdr (assq 'split-side alist))))) + (window--display-buffer buffer window 'window alist) + window)) + +(defun spacemacs/find-file-vsplit (file) + "find file in vertical split" + (interactive "FFind file (vsplit): ") + (let ((buffer (find-file-noselect file))) + (pop-to-buffer buffer '(spacemacs//display-in-split (split-side . right))))) + +(defun spacemacs/find-file-split (file) + "find file in horizontal split" + (interactive "FFind file (split): ") + (let ((buffer (find-file-noselect file))) + (pop-to-buffer buffer '(spacemacs//display-in-split (split-side . below))))) + +(defun spacemacs/switch-to-scratch-buffer () + "Switch to the `*scratch*' buffer. Create it first if needed." + (interactive) + (let ((exists (get-buffer "*scratch*"))) + (switch-to-buffer (get-buffer-create "*scratch*")) + (when (and (not exists) + (not (eq major-mode dotspacemacs-scratch-mode)) + (fboundp dotspacemacs-scratch-mode)) + (funcall dotspacemacs-scratch-mode)))) + +(defun spacemacs/close-compilation-window () + "Close the window containing the '*compilation*' buffer." + (interactive) + (when compilation-last-buffer + (delete-windows-on compilation-last-buffer))) + +(defun spacemacs/no-linum (&rest ignore) + "Disable linum if current buffer." + (when (or 'linum-mode global-linum-mode) + (linum-mode 0))) + +(defun spacemacs/linum-update-window-scale-fix (win) + "Fix linum for scaled text in the window WIN." + (set-window-margins win + (ceiling (* (if (boundp 'text-scale-mode-step) + (expt text-scale-mode-step + text-scale-mode-amount) 1) + (if (car (window-margins)) + (car (window-margins)) 1))))) + diff --git a/layers/+distributions/spacemacs-base/keybindings.el b/layers/+distributions/spacemacs-base/keybindings.el new file mode 100644 index 0000000..bb214fb --- /dev/null +++ b/layers/+distributions/spacemacs-base/keybindings.el @@ -0,0 +1,633 @@ +;;; keybindings.el --- Spacemacs Base Layer key-bindings File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; --------------------------------------------------------------------------- +;; Prefixes +;; --------------------------------------------------------------------------- + +;; We define prefix commands only for the sake of which-key +(setq spacemacs/key-binding-prefixes '(("a" "applications") + ("ai" "irc") + ("as" "shells") + ("b" "buffers") + ("c" "compile/comments") + ("C" "capture/colors") + ("e" "errors") + ("f" "files") + ("fC" "files/convert") + ("fe" "emacs(spacemacs)") + ("fv" "variables") + ("g" "git/versions-control") + ("h" "help") + ("hd" "help-describe") + ("i" "insertion") + ("j" "jump/join/split") + ("k" "lisp") + ("kd" "delete") + ("kD" "delete-backward") + ("k`" "hybrid") + ("n" "narrow/numbers") + ("p" "projects") + ("p$" "projects/shell") + ("q" "quit") + ("r" "registers/rings/resume") + ("Re" "elisp") + ("Rp" "pcre") + ("s" "search/symbol") + ("sa" "ag") + ("sg" "grep") + ("sk" "ack") + ("st" "pt") + ("sw" "web") + ("t" "toggles") + ("tC" "colors") + ("tE" "editing-styles") + ("th" "highlight") + ("tm" "modeline") + ("T" "UI toggles/themes") + ("C-t" "other toggles") + ("w" "windows") + ("wp" "popup") + ("x" "text") + ("xa" "align") + ("xd" "delete") + ("xg" "google-translate") + ("xl" "lines") + ("xm" "move") + ("xt" "transpose") + ("xw" "words") + ("z" "zoom"))) +(mapc (lambda (x) (apply #'spacemacs/declare-prefix x)) + spacemacs/key-binding-prefixes) + +;; instantly display current keystrokes in mini buffer +(setq echo-keystrokes 0.02) +;; auto-indent on RET +(define-key global-map (kbd "RET") 'newline-and-indent) + +;; improve delete-other-windows +(define-key global-map (kbd "C-x 1") 'spacemacs/toggle-maximize-buffer) + +;; alternate binding to search next occurrence with isearch without +;; exiting isearch +(define-key isearch-mode-map (kbd "S-") 'isearch-repeat-forward) +(define-key isearch-mode-map (kbd "M-S-") 'isearch-repeat-backward) +;; Escape from isearch-mode("/" and "?" in evil-mode) like vim +(define-key isearch-mode-map (kbd "") 'isearch-cancel) + +;; Make quit as much as possible +(define-key minibuffer-local-map (kbd "") 'keyboard-escape-quit) +(define-key minibuffer-local-ns-map (kbd "") 'keyboard-escape-quit) +(define-key minibuffer-local-completion-map (kbd "") 'keyboard-escape-quit) +(define-key minibuffer-local-must-match-map (kbd "") 'keyboard-escape-quit) +(define-key minibuffer-local-isearch-map (kbd "") 'keyboard-escape-quit) + +;; linum margin bindings------------------------------------------------------- +(global-set-key (kbd " ") 'spacemacs/md-select-linum) +(global-set-key (kbd " ") 'spacemacs/mu-select-linum) +(global-set-key (kbd " ") 'spacemacs/select-current-block) +(global-set-key (kbd " ") 'spacemacs/mu-select-linum) + +;; --------------------------------------------------------------------------- +;; spacemacs leader key bindings +;; --------------------------------------------------------------------------- + +;; Universal argument --------------------------------------------------------- +(spacemacs/set-leader-keys "u" 'universal-argument) +(when (memq dotspacemacs-editing-style '(vim hybrid)) + (define-key universal-argument-map + (kbd (concat dotspacemacs-leader-key " u")) + 'universal-argument-more)) +;; shell command ------------------------------------------------------------- +(spacemacs/set-leader-keys "!" 'shell-command) +;; applications --------------------------------------------------------------- +(spacemacs/set-leader-keys + "ac" 'calc-dispatch + "ap" 'list-processes + "aP" 'proced + "au" 'undo-tree-visualize) +;; buffers -------------------------------------------------------------------- +(spacemacs/set-leader-keys + "TAB" 'spacemacs/alternate-buffer + "bd" 'spacemacs/kill-this-buffer + "be" 'spacemacs/safe-erase-buffer + "bh" 'spacemacs/home + "b C-d" 'spacemacs/kill-matching-buffers-rudely + "bn" 'next-buffer + "bm" 'spacemacs/kill-other-buffers + "bN" 'spacemacs/new-empty-buffer + "bP" 'spacemacs/copy-clipboard-to-whole-buffer + "bp" 'previous-buffer + "bR" 'spacemacs/safe-revert-buffer + "bs" 'spacemacs/switch-to-scratch-buffer + "bY" 'spacemacs/copy-whole-buffer-to-clipboard + "bw" 'read-only-mode) +;; Cycling settings ----------------------------------------------------------- +(spacemacs/set-leader-keys "Tn" 'spacemacs/cycle-spacemacs-theme) +;; errors --------------------------------------------------------------------- +(spacemacs/set-leader-keys + "en" 'spacemacs/next-error + "eN" 'spacemacs/previous-error + "ep" 'spacemacs/previous-error) +(spacemacs|define-transient-state error + :title "Error transient state" + :hint-is-doc t + :dynamic-hint + (let ((sys (spacemacs/error-delegate))) + (cond + ((eq 'flycheck sys) + "\nBrowsing flycheck errors from this buffer.") + ((eq 'emacs sys) + (let ((buf (next-error-find-buffer))) + (if buf + (concat "\nBrowsing entries from \"" + (buffer-name buf) + "\"" + (with-current-buffer buf + (when spacemacs--gne-line-func + (format " (%d of %d)" + (max 1 (1+ (- spacemacs--gne-cur-line + spacemacs--gne-min-line))) + (1+ (- spacemacs--gne-max-line + spacemacs--gne-min-line)))))) + "\nNo next-error capable buffer found."))))) + :bindings + ("n" spacemacs/next-error "next") + ("p" spacemacs/previous-error "prev") + ("q" nil "quit" :exit t) + :evil-leader "e.") +;; file ----------------------------------------------------------------------- +(spacemacs/set-leader-keys + "fc" 'spacemacs/copy-file + "fD" 'spacemacs/delete-current-buffer-file + "fei" 'spacemacs/find-user-init-file + "fed" 'spacemacs/find-dotfile + "feD" 'spacemacs/ediff-dotfile-and-template + "feR" 'dotspacemacs/sync-configuration-layers + "fev" 'spacemacs/display-and-copy-version + "fCd" 'spacemacs/unix2dos + "fCu" 'spacemacs/dos2unix + "fg" 'rgrep + "fl" 'find-file-literally + "fE" 'spacemacs/sudo-edit + "fo" 'spacemacs/open-file-or-directory-in-external-app + "fR" 'spacemacs/rename-current-buffer-file + "fS" 'evil-write-all + "fs" 'save-buffer + "fvd" 'add-dir-local-variable + "fvf" 'add-file-local-variable + "fvp" 'add-file-local-variable-prop-line + "fy" 'spacemacs/show-and-copy-buffer-filename) +;; help ----------------------------------------------------------------------- +(spacemacs/set-leader-keys + "hdb" 'describe-bindings + "hdc" 'describe-char + "hdf" 'describe-function + "hdk" 'describe-key + "hdl" 'spacemacs/describe-last-keys + "hdp" 'describe-package + "hdP" 'configuration-layer/describe-package + "hds" 'spacemacs/describe-system-info + "hdt" 'describe-theme + "hdv" 'describe-variable + "hI" 'spacemacs/report-issue + "hn" 'view-emacs-news) +;; insert stuff --------------------------------------------------------------- +(spacemacs/set-leader-keys + "iJ" 'spacemacs/insert-line-below-no-indent + "iK" 'spacemacs/insert-line-above-no-indent + "ik" 'spacemacs/evil-insert-line-above + "ij" 'spacemacs/evil-insert-line-below) +;; format --------------------------------------------------------------------- +;; `SPC j k' key binding for a frequent action: go and indent line below the point +;; `SPC J' split the current line at point and indent it +(spacemacs/set-leader-keys + "jo" 'open-line + "j=" 'spacemacs/indent-region-or-buffer + "jS" 'spacemacs/split-and-new-line + "jk" 'spacemacs/evil-goto-next-line-and-indent) + +;; navigation/jumping --------------------------------------------------------- +(spacemacs/set-leader-keys + "j0" 'spacemacs/push-mark-and-goto-beginning-of-line + "j$" 'spacemacs/push-mark-and-goto-end-of-line + "jf" 'find-function + "jv" 'find-variable) + +;; Compilation ---------------------------------------------------------------- +(spacemacs/set-leader-keys + "cC" 'compile + "ck" 'kill-compilation + "cr" 'recompile + "cd" 'spacemacs/close-compilation-window) +(with-eval-after-load 'compile + (define-key compilation-mode-map "r" 'recompile) + (define-key compilation-mode-map "g" nil)) +;; narrow & widen ------------------------------------------------------------- +(spacemacs/set-leader-keys + "nr" 'narrow-to-region + "np" 'narrow-to-page + "nf" 'narrow-to-defun + "nw" 'widen) +;; toggle --------------------------------------------------------------------- +(spacemacs|add-toggle highlight-current-line-globally + :mode global-hl-line-mode + :documentation "Globally highlight the current line." + :evil-leader "thh") +(spacemacs|add-toggle truncate-lines + :status truncate-lines + :on (toggle-truncate-lines) + :off (toggle-truncate-lines -1) + :documentation "Truncate long lines (no wrap)." + :evil-leader "tl") +(spacemacs|add-toggle visual-line-navigation + :status visual-line-mode + :on + (progn + (visual-line-mode) + (evil-define-minor-mode-key 'motion 'visual-line-mode "j" 'evil-next-visual-line) + (evil-define-minor-mode-key 'motion 'visual-line-mode "k" 'evil-previous-visual-line) + (when (bound-and-true-p evil-escape-mode) + (evil-escape-mode -1) + (setq evil-escape-motion-state-shadowed-func nil) + (evil-define-minor-mode-key 'motion 'visual-line-mode "j" 'evil-next-visual-line) + (evil-define-minor-mode-key 'motion 'visual-line-mode "k" 'evil-previous-visual-line) + (evil-escape-mode)) + (evil-normalize-keymaps)) + :off + (progn + (visual-line-mode -1) + (evil-normalize-keymaps)) + :documentation "Move point according to visual lines." + :evil-leader "tL") +(spacemacs|add-toggle auto-fill-mode + :status auto-fill-function + :on (auto-fill-mode) + :off (auto-fill-mode -1) + :documentation "Break line beyond `current-fill-column` while editing." + :evil-leader "tF") +(spacemacs|add-toggle debug-on-error + :status debug-on-error + :on (setq debug-on-error t) + :off (setq debug-on-error nil) + :documentation "Toggle display of backtrace when an error happens." + :evil-leader "tD") +(spacemacs|add-toggle fringe + :status (not (equal fringe-mode 0)) + :on (call-interactively 'fringe-mode) + :off (fringe-mode 0) + :documentation "Display the fringe in GUI mode." + :evil-leader "Tf") +(spacemacs|add-toggle fullscreen-frame + :status (memq (frame-parameter nil 'fullscreen) '(fullscreen fullboth)) + :on (spacemacs/toggle-frame-fullscreen) + :off (spacemacs/toggle-frame-fullscreen) + :documentation "Display the current frame in full screen." + :evil-leader "TF") +(spacemacs|add-toggle maximize-frame + :status (eq (frame-parameter nil 'fullscreen) 'maximized) + :on (toggle-frame-maximized) + :off (toggle-frame-maximized) + :documentation "Maximize the current frame." + :evil-leader "TM") +(spacemacs|add-toggle mode-line + :status (not hidden-mode-line-mode) + :on (hidden-mode-line-mode -1) + :off (hidden-mode-line-mode) + :documentation "Toggle the visibility of modeline." + :evil-leader "tmt") +(spacemacs|add-toggle transparent-frame + :status nil + :on (spacemacs/toggle-transparency) + :documentation "Make the current frame non-opaque." + :evil-leader "TT") +(spacemacs|add-toggle tool-bar + :if window-system + :mode tool-bar-mode + :documentation "Display the tool bar in GUI mode." + :evil-leader "Tt") +(spacemacs|add-toggle menu-bar + :if window-system + :mode menu-bar-mode + :documentation "Display the menu bar." + :evil-leader "Tm") +(spacemacs|add-toggle semantic-stickyfunc + :mode semantic-stickyfunc-mode + :documentation "Enable semantic-stickyfunc." + :evil-leader "TS") +(spacemacs|add-toggle semantic-stickyfunc-globally + :mode global-semantic-stickyfunc-mode + :documentation "Enable semantic-stickyfunc globally." + :evil-leader "T C-S") +;; quit ----------------------------------------------------------------------- +(spacemacs/set-leader-keys + "qs" 'spacemacs/save-buffers-kill-emacs + "qq" 'spacemacs/prompt-kill-emacs + "qQ" 'spacemacs/kill-emacs + "qz" 'spacemacs/frame-killer) +;; window --------------------------------------------------------------------- +(defun split-window-below-and-focus () + "Split the window vertically and focus the new window." + (interactive) + (split-window-below) + (windmove-down) + (when (and (boundp 'golden-ratio-mode) + (symbol-value golden-ratio-mode)) + (golden-ratio))) + +(defun split-window-right-and-focus () + "Split the window horizontally and focus the new window." + (interactive) + (split-window-right) + (windmove-right) + (when (and (boundp 'golden-ratio-mode) + (symbol-value golden-ratio-mode)) + (golden-ratio))) + +(spacemacs/set-leader-keys + "w2" 'spacemacs/layout-double-columns + "w3" 'spacemacs/layout-triple-columns + "wb" 'spacemacs/switch-to-minibuffer-window + "wd" 'spacemacs/delete-window + "wt" 'spacemacs/toggle-current-window-dedication + "wf" 'follow-mode + "wF" 'make-frame + "wH" 'evil-window-move-far-left + "w " 'evil-window-move-far-left + "wh" 'evil-window-left + "w " 'evil-window-left + "wJ" 'evil-window-move-very-bottom + "w " 'evil-window-move-very-bottom + "wj" 'evil-window-down + "w " 'evil-window-down + "wK" 'evil-window-move-very-top + "w " 'evil-window-move-very-top + "wk" 'evil-window-up + "w " 'evil-window-up + "wL" 'evil-window-move-far-right + "w " 'evil-window-move-far-right + "wl" 'evil-window-right + "w " 'evil-window-right + "wm" 'spacemacs/toggle-maximize-buffer + "wc" 'spacemacs/toggle-centered-buffer-mode + "wC" 'spacemacs/centered-buffer-mode-full-width + "wo" 'other-frame + "wr" 'spacemacs/rotate-windows + "wR" 'spacemacs/rotate-windows-backward + "ws" 'split-window-below + "wS" 'split-window-below-and-focus + "w-" 'split-window-below + "wU" 'winner-redo + "wu" 'winner-undo + "wv" 'split-window-right + "wV" 'split-window-right-and-focus + "ww" 'other-window + "w/" 'split-window-right + "w=" 'balance-windows + "w_" 'spacemacs/maximize-horizontally) +;; text ----------------------------------------------------------------------- +(defalias 'count-region 'count-words-region) + +(spacemacs/set-leader-keys + "xa&" 'spacemacs/align-repeat-ampersand + "xa(" 'spacemacs/align-repeat-left-paren + "xa)" 'spacemacs/align-repeat-right-paren + "xa," 'spacemacs/align-repeat-comma + "xa." 'spacemacs/align-repeat-decimal + "xa:" 'spacemacs/align-repeat-colon + "xa;" 'spacemacs/align-repeat-semicolon + "xa=" 'spacemacs/align-repeat-equal + "xa\\" 'spacemacs/align-repeat-backslash + "xaa" 'align + "xac" 'align-current + "xam" 'spacemacs/align-repeat-math-oper + "xar" 'spacemacs/align-repeat + "xa|" 'spacemacs/align-repeat-bar + "xc" 'count-region + "xdw" 'delete-trailing-whitespace + "xjc" 'set-justification-center + "xjf" 'set-justification-full + "xjl" 'set-justification-left + "xjn" 'set-justification-none + "xjr" 'set-justification-right + "xls" 'spacemacs/sort-lines + "xlu" 'spacemacs/uniquify-lines + "xtc" 'transpose-chars + "xtl" 'transpose-lines + "xtw" 'transpose-words + "xU" 'upcase-region + "xu" 'downcase-region + "xwc" 'spacemacs/count-words-analysis + "x TAB" 'indent-rigidly) + +(define-key indent-rigidly-map "h" 'indent-rigidly-left) +(define-key indent-rigidly-map "l" 'indent-rigidly-right) +(define-key indent-rigidly-map "H" 'indent-rigidly-left-to-tab-stop) +(define-key indent-rigidly-map "L" 'indent-rigidly-right-to-tab-stop) + +;; shell ---------------------------------------------------------------------- +(with-eval-after-load 'shell + (evil-define-key 'insert comint-mode-map [up] 'comint-previous-input) + (evil-define-key 'insert comint-mode-map [down] 'comint-next-input)) + +;; --------------------------------------------------------------------------- +;; Transient-states +;; --------------------------------------------------------------------------- + +;; Buffer transient state + +(spacemacs|define-transient-state buffer + :title "Buffer Selection Transient State" + :bindings + ("n" next-buffer "next") + ("N" previous-buffer "previous") + ("p" previous-buffer "previous") + ("K" spacemacs/kill-this-buffer "kill") + ("q" nil "quit" :exit t)) +(spacemacs/set-leader-keys "b." 'spacemacs/buffer-transient-state/body) + +;; end of Buffer transient state + +;; Window Manipulation Transient State + +(defun spacemacs/shrink-window-horizontally (delta) + "Wrap `spacemacs/shrink-window-horizontally'." + (interactive "p") + (shrink-window delta t)) + +(defun spacemacs/shrink-window (delta) + "Wrap `spacemacs/shrink-window'." + (interactive "p") + (shrink-window delta)) + +(defun spacemacs/enlarge-window (delta) + "Wrap `spacemacs/enlarge-window'." + (interactive "p") + (enlarge-window delta)) + +(defun spacemacs/enlarge-window-horizontally (delta) + "Wrap `spacemacs/enlarge-window-horizontally'." + (interactive "p") + (enlarge-window delta t)) + +(spacemacs|define-transient-state window-manipulation + :title "Window Manipulation Transient State" + :doc (concat " + Select^^^^ Move^^^^ Split^^ Resize^^ Other^^ + ──────^^^^───────────── ────^^^^───────────── ─────^^─────────────── ──────^^──────────────────── ─────^^────────────────────────────── + [_j_/_k_] down/up [_J_/_K_] down/up [_s_] vertical [_[_] shrink horizontally [_q_] quit + [_h_/_l_] left/right [_H_/_L_] left/right [_S_] vert & follow [_]_] enlarge horizontally [_u_] restore prev layout + [_0_-_9_] window N [_r_]^^ rotate fwd [_v_] horizontal [_{_] shrink vertically [_U_] restore next layout + [_w_]^^ other window [_R_]^^ rotate bwd [_V_] horiz & follow [_}_] enlarge vertically [_d_] close current + [_o_]^^ other frame ^^^^ ^^ ^^ [_D_] close other" + (if (configuration-layer/package-usedp 'golden-ratio) + "\n ^^^^ ^^^^ ^^ ^^ [_g_] golden-ratio %`golden-ratio-mode" + "")) + :bindings + ("q" nil :exit t) + ("0" select-window-0) + ("1" select-window-1) + ("2" select-window-2) + ("3" select-window-3) + ("4" select-window-4) + ("5" select-window-5) + ("6" select-window-6) + ("7" select-window-7) + ("8" select-window-8) + ("9" select-window-9) + ("-" split-window-below-and-focus) + ("/" split-window-right-and-focus) + ("[" spacemacs/shrink-window-horizontally) + ("]" spacemacs/enlarge-window-horizontally) + ("{" spacemacs/shrink-window) + ("}" spacemacs/enlarge-window) + ("d" delete-window) + ("D" delete-other-windows) + ("h" evil-window-left) + ("" evil-window-left) + ("j" evil-window-down) + ("" evil-window-down) + ("k" evil-window-up) + ("" evil-window-up) + ("l" evil-window-right) + ("" evil-window-right) + ("H" evil-window-move-far-left) + ("" evil-window-move-far-left) + ("J" evil-window-move-very-bottom) + ("" evil-window-move-very-bottom) + ("K" evil-window-move-very-top) + ("" evil-window-move-very-top) + ("L" evil-window-move-far-right) + ("" evil-window-move-far-right) + ("o" other-frame) + ("r" spacemacs/rotate-windows) + ("R" spacemacs/rotate-windows-backward) + ("s" split-window-below) + ("S" split-window-below-and-focus) + ("u" winner-undo) + ("U" winner-redo) + ("v" split-window-right) + ("V" split-window-right-and-focus) + ("w" other-window)) +(spacemacs/set-leader-keys "w." + 'spacemacs/window-manipulation-transient-state/body) + +;; end of Window Manipulation Transient State + +;; text Manipulation Transient State + +(defun spacemacs/scale-up-or-down-font-size (direction) + "Scale the font. If DIRECTION is positive or zero the font is scaled up, +otherwise it is scaled down." + (interactive) + (let ((scale 0.5)) + (if (eq direction 0) + (text-scale-set 0) + (if (< direction 0) + (text-scale-decrease scale) + (text-scale-increase scale))))) + +(defun spacemacs/scale-up-font () + "Scale up the font." + (interactive) + (spacemacs/scale-up-or-down-font-size 1)) + +(defun spacemacs/scale-down-font () + "Scale up the font." + (interactive) + (spacemacs/scale-up-or-down-font-size -1)) + +(defun spacemacs/reset-font-size () + "Reset the font size." + (interactive) + (spacemacs/scale-up-or-down-font-size 0)) + +(spacemacs|define-transient-state scale-font + :title "Font Scaling Transient State" + :doc "\n[_+_/_=_] scale up [_-_] scale down [_0_] reset font [_q_] quit" + :bindings + ("+" spacemacs/scale-up-font) + ("=" spacemacs/scale-up-font) + ("-" spacemacs/scale-down-font) + ("0" spacemacs/reset-font-size) + ("q" nil :exit t)) +(spacemacs/set-leader-keys "zx" 'spacemacs/scale-font-transient-state/body) + +;; end of Text Manipulation Transient State + +;; Transparency transient-state + +(defun spacemacs/toggle-transparency (&optional frame) + "Toggle between transparent and opaque state for FRAME. +If FRAME is nil, it defaults to the selected frame." + (interactive) + (let* ((alpha (frame-parameter frame 'alpha)) + (dotfile-setting (cons dotspacemacs-active-transparency + dotspacemacs-inactive-transparency))) + (set-frame-parameter + frame 'alpha + (if (not (equal alpha dotfile-setting)) + dotfile-setting + '(100 . 100))))) + +(defun spacemacs/increase-transparency (&optional frame) + "Increase transparency for FRAME. +If FRAME is nil, it defaults to the selected frame." + (interactive) + (let* ((current-alpha (car (frame-parameter frame 'alpha))) + (increased-alpha (- current-alpha 5))) + (when (>= increased-alpha frame-alpha-lower-limit) + (set-frame-parameter frame 'alpha + (cons increased-alpha increased-alpha))))) + +(defun spacemacs/decrease-transparency (&optional frame) + "Decrease transparency for FRAME. +If FRAME is nil, it defaults to the selected frame." + (interactive) + (let* ((current-alpha (car (frame-parameter frame 'alpha))) + (decreased-alpha (+ current-alpha 5))) + (when (<= decreased-alpha 100) + (set-frame-parameter frame 'alpha + (cons decreased-alpha decreased-alpha))))) + +(spacemacs|define-transient-state scale-transparency + :title "Frame Transparency Transient State" + :doc "\n[_+_/_=_] increase transparency [_-_] decrease [_T_] toggle [_q_] quit" + :bindings + ("+" spacemacs/increase-transparency) + ("=" spacemacs/increase-transparency) + ("-" spacemacs/decrease-transparency) + ("T" spacemacs/toggle-transparency) + ("q" nil :exit t)) +(spacemacs/set-leader-keys "TT" + 'spacemacs/scale-transparency-transient-state/spacemacs/toggle-transparency) + +;; end of Transparency Transient State diff --git a/layers/+distributions/spacemacs-base/local/centered-buffer-mode/centered-buffer-mode.el b/layers/+distributions/spacemacs-base/local/centered-buffer-mode/centered-buffer-mode.el new file mode 100644 index 0000000..3682cb5 --- /dev/null +++ b/layers/+distributions/spacemacs-base/local/centered-buffer-mode/centered-buffer-mode.el @@ -0,0 +1,269 @@ +;;; centered-buffer-mode.el --- Minor mode for centering buffers. + +;; Copyright (C) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Eugene "JAremko" Yaremenko +;; Keywords: centering buffer minor-mode +;; Created: 1 July 2016 +;; Version: 1.01 +;; Package-Requires: ((emacs "24.4")) +;; URL: https://github.com/syl20bnr/spacemacs + +;; 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 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 this program. If not, see . + +;;; Code: +(require 'face-remap) + +(defgroup spacemacs-centered-buffer-mode nil "Minor mode to center buffer in its window." + :group 'convenience) + +(defcustom spacemacs-centered-buffer-mode-min-fringe-width 50 + "Minimal fringe width." + :type 'integer + :group 'spacemacs-centered-buffer-mode) + +(defcustom spacemacs-centered-buffer-mode-safety-gap-width 20 + "Add extra width to the modified buffer to make sure +that differed modifications won't cause an overflow." + :type 'integer + :group 'spacemacs-centered-buffer-mode) + +(defcustom spacemacs-centered-buffer-mode-fringe-color "black" + "Color of the fringes." + :type 'color + :group 'spacemacs-centered-buffer-mode) + +(defvar-local spacemacs--centered-buffer-mode-origin-buffer nil) +(defvar-local spacemacs--centered-buffer-mode-indirect-buffer nil) +(defvar-local spacemacs--centered-buffer-mode-text-pixel-size nil) +(defvar spacemacs-centered-buffer-mode-default-fringe-color (face-background 'fringe)) +(defvar spacemacs--centered-buffer-mode-indirect-buffers (list)) + +(define-minor-mode spacemacs-centered-buffer-mode + "Minor mode to center buffer in its window." + :init-value nil + :group 'spacemacs-centered-buffer-mode + (if spacemacs-centered-buffer-mode + (if (not (window-dedicated-p)) + (spacemacs//centered-buffer-mode-enable-branch (called-interactively-p 'any)) + (setq spacemacs-centered-buffer-mode nil) + (when (called-interactively-p 'any) + (message "Can't center in dedicated window!"))) + (spacemacs//centered-buffer-mode-disable-branch))) + +(defun spacemacs//centered-buffer-mode-enable-branch (interact) + "Used it `spacemacs-centered-buffer-mode'. +Assume to be called interactively when INTERACT has non nil value." + ;; Mode will be applied to the indirect buffer. + (setq spacemacs-centered-buffer-mode nil) + ;; Don't run if the mode is enabled(we are in the indirect buffer). + (unless spacemacs--centered-buffer-mode-origin-buffer + (let* ((window (selected-window)) + (origin-buffer (window-buffer window)) + (indirect-buffer + (if (buffer-live-p + spacemacs--centered-buffer-mode-indirect-buffer) + spacemacs--centered-buffer-mode-indirect-buffer + (setq spacemacs--centered-buffer-mode-indirect-buffer + (make-indirect-buffer origin-buffer + (format "%s(centered)" + origin-buffer) + t))))) + (spacemacs//centered-buffer-mode-buffer-fringr-color-toggle origin-buffer t) + (setq spacemacs--centered-buffer-mode-indirect-buffer + indirect-buffer + spacemacs-centered-buffer-mode-default-fringe-color + (face-background 'fringe)) + (when (derived-mode-p 'org-mode) + (setq-local org-startup-folded nil) + (outline-show-all)) + (switch-to-buffer indirect-buffer nil t) + (with-mode-disabled + page-break-lines-mode + (let* ((fringe-w (spacemacs//centered-buffer-calc-fringe + window))) + (if (> fringe-w spacemacs-centered-buffer-mode-min-fringe-width) + (progn + ;; Fix visual glitch. + (spacemacs/toggle-line-numbers) + (spacemacs/toggle-line-numbers) + ;; + (setq spacemacs--centered-buffer-mode-indirect-buffers + (append (list indirect-buffer) + spacemacs--centered-buffer-mode-indirect-buffers) + spacemacs--centered-buffer-mode-origin-buffer origin-buffer + spacemacs-centered-buffer-mode t + indicate-empty-lines nil + fringes-outside-margins t + left-fringe-width fringe-w + right-fringe-width fringe-w + ;; looks better with some margin. + left-margin-width (if (or (not left-margin-width) + (= left-margin-width 0)) + 1 + left-margin-width) + spacemacs--centered-buffer-mode-text-pixel-size + (car (window-text-pixel-size window))) + (face-remap-add-relative 'fringe :background + spacemacs-centered-buffer-mode-fringe-color) + (set-window-buffer window indirect-buffer) + (advice-add 'previous-buffer + :before + #'spacemacs//centered-buffer-mode-prev-next-buffer-advice) + (advice-add 'next-buffer + :before + #'spacemacs//centered-buffer-mode-prev-next-buffer-advice) + (add-hook 'after-change-functions + #'spacemacs//centered-buffer-after-change-function + nil + t) + (add-hook 'buffer-list-update-hook + 'spacemacs//centered-buffer-buffer-list-update-fringes) + (add-hook 'window-configuration-change-hook + 'spacemacs//centered-buffer-buffer-list-update-fringes)) + (setq spacemacs--centered-buffer-mode-origin-buffer nil) + (set-buffer origin-buffer) + (spacemacs//centered-buffer-mode-buffer-fringr-color-toggle origin-buffer nil) + (kill-buffer indirect-buffer) + (setq spacemacs--centered-buffer-mode-indirect-buffer nil) + (when interact + (message "Not enough space to center the buffer!")))))))) + +(defun spacemacs//centered-buffer-mode-prev-next-buffer-advice () + "Disables `spacemacs-centered-buffer-mode' when `spacemacs/previous-buffer' +or `spacemacs/next-buffer' is called." + (when (bound-and-true-p spacemacs-centered-buffer-mode) + (spacemacs-centered-buffer-mode -1))) + +(defun spacemacs//centered-buffer-mode-disable-branch () + "Used in `spacemacs-centered-buffer-mode'." + ;; Don't run if the mode is disabled(we are not in the indirect buffer). + (when spacemacs--centered-buffer-mode-origin-buffer + (let* ((window (selected-window)) + (origin-buffer spacemacs--centered-buffer-mode-origin-buffer) + (indirect-buffer (window-buffer window))) + (setq spacemacs--centered-buffer-mode-origin-buffer nil) + (switch-to-buffer origin-buffer nil t) + (spacemacs//centered-buffer-mode-buffer-fringr-color-toggle origin-buffer nil) + (setq spacemacs--centered-buffer-mode-indirect-buffer nil) + (when (buffer-live-p indirect-buffer) + (dolist (window (get-buffer-window-list indirect-buffer 2)) + (set-window-buffer window origin-buffer)) + (kill-buffer indirect-buffer))))) + +(defun spacemacs//centered-buffer-mode-buffer-fringr-color-toggle (buffer flag) + "Change fringe color of the BUFFER if FLAG has non-nil value. +Revert changes Otherwise." + (with-current-buffer buffer + (if flag + (face-remap-add-relative 'fringe :background + spacemacs-centered-buffer-mode-fringe-color) + (face-remap-reset-base 'fringe) + (face-remap-add-relative 'fringe + :background + spacemacs-centered-buffer-mode-default-fringe-color)))) + +(defun spacemacs//centered-buffer-calc-fringe (&optional window text-pixel-size) + "Calculate fringe width for `spacemacs-centered-buffer-mode'. +Uses text-pixel-size if provided, otherwise calculates it with `window-pixel-width'." + (-(/ (- (window-pixel-width window) + (or text-pixel-size + (car (window-text-pixel-size window)))) + 2) + (if (bound-and-true-p org-indent-mode) 40 + spacemacs-centered-buffer-mode-safety-gap-width))) + +(defun spacemacs//centered-buffer-buffer-update-window-fringes (window) + "Update fringe width of WINDOW if it displays `centered-buffer-mode' buffer." + (when (and (buffer-local-value 'spacemacs--centered-buffer-mode-origin-buffer + (window-buffer window)) + ;; Might be needed because + ;; (spacemacs-centered-buffer-mode -1) kills buffers. + (buffer-live-p (window-buffer window))) + (let ((fringe-w (spacemacs//centered-buffer-calc-fringe + window + spacemacs--centered-buffer-mode-text-pixel-size))) + (if (> fringe-w spacemacs-centered-buffer-mode-min-fringe-width) + (set-window-fringes window fringe-w fringe-w t) + (spacemacs-centered-buffer-mode -1) + (when spacemacs--centered-buffer-mode-indirect-buffers + (spacemacs//centered-buffer-prune-indirect-buffer-list)))))) + +(defun spacemacs//centered-buffer-buffer-list-update-fringes () + "Update fringe width of all `centered-buffer-mode' fringes." + (dolist (frame (frame-list)) + (when (frame-live-p frame) + (dolist (window (window-list frame 2)) + (spacemacs//centered-buffer-buffer-update-window-fringes window))))) + +(defun spacemacs//centered-buffer-after-change-function (begin end length) + "Reduce `centered-buffer-mode' fringe width in case of buffer content overflow." + (dolist (window (get-buffer-window-list (current-buffer) 2 t)) + (save-excursion + (let* ((min-pos (progn (goto-char begin) + (point-at-bol))) + (max-pos (progn (goto-char end) + (point-at-eol))) + (updated-segment-max-width (car (window-text-pixel-size window min-pos max-pos)))) + (when (> updated-segment-max-width + spacemacs--centered-buffer-mode-text-pixel-size) + (setq spacemacs--centered-buffer-mode-text-pixel-size updated-segment-max-width) + (spacemacs//centered-buffer-buffer-update-window-fringes window)))))) + +(defun spacemacs//centered-buffer-prune-indirect-buffer-list () + "Remove indirect buffer from the `spacemacs--centered-buffer-mode-indirect-buffers' +if the buffer hasn't at least one live window. Disables `centered-buffer-mode' hooks +and advices if `spacemacs--centered-buffer-mode-indirect-buffers' has no elements left to +minimize the performance hit when the mode isn't used." + (dolist (buffer spacemacs--centered-buffer-mode-indirect-buffers) + (unless (or (and (buffer-live-p buffer) + (window-live-p (get-buffer-window buffer t))) + (not spacemacs--centered-buffer-mode-indirect-buffers)) + (let ((origin-buffer (buffer-local-value + 'spacemacs--centered-buffer-mode-origin-buffer + buffer))) + (when (ignore-errors (kill-buffer buffer)) + (setq spacemacs--centered-buffer-mode-indirect-buffers + (delete buffer spacemacs--centered-buffer-mode-indirect-buffers)) + (when (buffer-live-p origin-buffer) + (spacemacs//centered-buffer-mode-buffer-fringr-color-toggle origin-buffer nil) + (with-current-buffer origin-buffer + (setq spacemacs--centered-buffer-mode-indirect-buffers nil))))))) + ;; Remove hooks and advices when they are not needed anymore. + (unless spacemacs--centered-buffer-mode-indirect-buffers + (advice-remove 'previous-buffer + #'spacemacs//centered-buffer-mode-prev-next-buffer-advice) + (advice-remove 'next-buffer + #'spacemacs//centered-buffer-mode-prev-next-buffer-advice) + (remove-hook 'after-change-functions + #'spacemacs//centered-buffer-after-change-function) + (remove-hook 'buffer-list-update-hook + 'spacemacs//centered-buffer-buffer-list-update-fringes) + (remove-hook 'window-configuration-change-hook + 'spacemacs//centered-buffer-buffer-list-update-fringes))) + +(defmacro with-mode-disabled (mode &rest body) + "Evaluate BODY with MODE disabled." + (declare (indent 1) (debug t)) + `(if (not (bound-and-true-p ,mode)) + (progn ,@body) + (,mode -1) + ,@body + (,mode +1))) + +(provide 'centered-buffer-mode) + +;;; centered-buffer-mode.el ends here diff --git a/layers/+distributions/spacemacs-base/local/evil-evilified-state/evil-evilified-state.el b/layers/+distributions/spacemacs-base/local/evil-evilified-state/evil-evilified-state.el new file mode 100644 index 0000000..2e1d127 --- /dev/null +++ b/layers/+distributions/spacemacs-base/local/evil-evilified-state/evil-evilified-state.el @@ -0,0 +1,339 @@ +;;; evil-evilified-state.el --- A minimalistic evil state +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; Keywords: convenience editing evil spacemacs +;; Created: 22 Mar 2015 +;; Version: 1.0 +;; Package-Requires: ((evil "1.0.9")) + +;; 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 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 this program. If not, see . + +;;; Commentary: + +;; Define a `evilified' evil state inheriting from `emacs' state and +;; setting a minimalist list of Vim key bindings (like navigation, search, ...) + +;; The shadowed original mode key bindings are automatically reassigned +;; following a set of rules: +;; Keys such as +;; /,:,h,j,k,l,n,N,v,V,gg,G,C-f,C-b,C-d,C-e,C-u,C-y and C-z +;; are working as in Evil. +;; Other keys will be moved according to this pattern: +;; a -> A -> C-a -> C-A +;; The first unreserved key will be used. +;; There is an exception for g, which will be directly +;; bound to C-G, since G and C-g (latest being an important escape key in Emacs) +;; are already being used. + +;;; Code: + +(require 'evil) +(require 'bind-map) + +(defvar evilified-state--evil-surround nil + "Evil surround mode variable backup.") +(make-variable-buffer-local 'evilified-state--evil-surround) + +(defvar evilified-state--normal-state-map nil + "Local backup of normal state keymap.") +(make-variable-buffer-local 'evilified-state--normal-state-map) + +(evil-define-state evilified + "Evilified state. + Hybrid `emacs state' with carrefully selected Vim key bindings. + See spacemacs conventions for more info." + :tag " " + :enable (emacs) + :message "-- EVILIFIED BUFFER --" + :cursor box) + +(bind-map spacemacs-default-map + :prefix-cmd spacemacs-cmds + :evil-keys (dotspacemacs-leader-key) + :evil-states (evilified) + :override-minor-modes t + :override-mode-name spacemacs-leader-override-mode) + +(evil-define-command evil-force-evilified-state () + "Switch to evilified state without recording current command." + :repeat abort + :suppress-operator t + (evil-evilified-state)) + +(defun evilified-state--pre-command-hook () + "Redirect key bindings to `evilified-state'. +Needed to bypass keymaps set as text properties." + (unless (bound-and-true-p isearch-mode) + (when (memq evil-state '(evilified visual)) + (let* ((map (get-char-property (point) 'keymap)) + (evilified-map (when map (cdr (assq 'evilified-state map)))) + (command (when (and evilified-map + (eq 1 (length (this-command-keys)))) + (lookup-key evilified-map (this-command-keys))))) + (when command (setq this-command command)))))) + +(defun evilified-state--setup-normal-state-keymap () + "Setup the normal state keymap." + (unless evilified-state--normal-state-map + (setq-local evilified-state--normal-state-map + (copy-keymap evil-normal-state-map))) + (setq-local evil-normal-state-map + (copy-keymap evilified-state--normal-state-map)) + (define-key evil-normal-state-map [escape] 'evil-evilified-state)) + +(defun evilified-state--restore-normal-state-keymap () + "Restore the normal state keymap." + (setq-local evil-normal-state-map evilified-state--normal-state-map)) + +(defun evilified-state--clear-normal-state-keymap () + "Clear the normal state keymap." + (setq-local evil-normal-state-map (cons 'keymap nil)) + (evil-normalize-keymaps)) + +(defun evilified-state--setup-visual-state-keymap () + "Setup the normal state keymap." + (setq-local evil-visual-state-map + (cons 'keymap (list (cons ?y 'evil-yank) + (cons 'escape 'evil-exit-visual-state))))) + +(defun evilified-state--evilified-state-on-entry () + "Setup evilified state." + (when (derived-mode-p 'magit-mode) + ;; Courtesy of evil-magit package + ;; without this set-mark-command activates visual-state which is just + ;; annoying ;; and introduces possible bugs + (remove-hook 'activate-mark-hook 'evil-visual-activate-hook t)) + (when (bound-and-true-p evil-surround-mode) + (make-local-variable 'evil-surround-mode) + (evil-surround-mode -1)) + (evilified-state--setup-normal-state-keymap) + (evilified-state--setup-visual-state-keymap) + (add-hook 'pre-command-hook 'evilified-state--pre-command-hook nil 'local) + (add-hook 'evil-visual-state-entry-hook + 'evilified-state--visual-state-on-entry nil 'local) + (add-hook 'evil-visual-state-exit-hook + 'evilified-state--visual-state-on-exit nil 'local)) + +(defun evilified-state--visual-state-on-entry () + "Setup visual state." + ;; we need to clear temporarily the normal state keymap in order to reach + ;; the mode keymap + (when (eq 'evilified evil-previous-state) + (evilified-state--clear-normal-state-keymap))) + +(defun evilified-state--visual-state-on-exit () + "Clean visual state" + (evilified-state--restore-normal-state-keymap)) + +(add-hook 'evil-evilified-state-entry-hook + 'evilified-state--evilified-state-on-entry) + +;; default key bindings for all evilified buffers +(define-key evil-evilified-state-map "/" 'evil-search-forward) +(define-key evil-evilified-state-map ":" 'evil-ex) +(define-key evil-evilified-state-map "h" 'evil-backward-char) +(define-key evil-evilified-state-map "j" 'evil-next-visual-line) +(define-key evil-evilified-state-map "k" 'evil-previous-visual-line) +(define-key evil-evilified-state-map "l" 'evil-forward-char) +(define-key evil-evilified-state-map "n" 'evil-search-next) +(define-key evil-evilified-state-map "N" 'evil-search-previous) +(define-key evil-evilified-state-map "v" 'evil-visual-char) +(define-key evil-evilified-state-map "V" 'evil-visual-line) +(define-key evil-evilified-state-map "gg" 'evil-goto-first-line) +(define-key evil-evilified-state-map "G" 'evil-goto-line) +(define-key evil-evilified-state-map (kbd "C-f") 'evil-scroll-page-down) +(define-key evil-evilified-state-map (kbd "C-b") 'evil-scroll-page-up) +(define-key evil-evilified-state-map (kbd "C-e") 'evil-scroll-line-down) +(define-key evil-evilified-state-map (kbd "C-y") 'evil-scroll-line-up) +(define-key evil-evilified-state-map (kbd "C-d") 'evil-scroll-down) +(define-key evil-evilified-state-map (kbd "C-u") 'evil-scroll-up) +(define-key evil-evilified-state-map (kbd "C-z") 'evil-emacs-state) +(setq evil-evilified-state-map-original (copy-keymap evil-evilified-state-map)) + +;; old macro +;;;###autoload +(defmacro evilified-state-evilify (mode map &rest body) + "Set `evilified state' as default for MODE. + +BODY is a list of additional key bindings to apply for the given MAP in +`evilified state'." + (let ((defkey (when body `(evil-define-key 'evilified ,map ,@body)))) + `(progn (unless ,(null mode) + (unless (or (bound-and-true-p holy-mode) + (eq 'evilified (evil-initial-state ',mode))) + (evil-set-initial-state ',mode 'evilified))) + (unless ,(null defkey) (,@defkey))))) +(put 'evilified-state-evilify 'lisp-indent-function 'defun) + +;; new macro +;;;###autoload +(defmacro evilified-state-evilify-map (map &rest props) + "Evilify MAP. + +Avaiblabe PROPS: + +`:mode SYMBOL' +A mode SYMBOL associated with MAP. Used to add SYMBOL to the list of modes +defaulting to `evilified-state'. + +`:evilified-map SYMBOL' +A map SYMBOL of an alternate evilified map, if nil then +`evil-evilified-state-map' is used. + +`:eval-after-load SYMBOL' +If specified the evilification of MAP is deferred to the loading of the feature +bound to SYMBOL. May be required for some lazy-loaded maps. + +`:pre-bindings EXPRESSIONS' +One or several EXPRESSIONS with the form `KEY FUNCTION': + KEY1 FUNCTION1 + KEY2 FUNCTION2 +These bindings are set in MAP before the evilification happens. + +`:bindings EXPRESSIONS' +One or several EXPRESSIONS with the form `KEY FUNCTION': + KEY1 FUNCTION1 + KEY2 FUNCTION2 +These bindings are set directly in evil-evilified-state-map submap. + ... +Each pair KEYn FUNCTIONn is defined in MAP after the evilification of it." + (declare (indent 1)) + (let* ((mode (plist-get props :mode)) + (evilified-map (or (plist-get props :evilified-map) + 'evil-evilified-state-map-original)) + (eval-after-load (plist-get props :eval-after-load)) + (pre-bindings (evilified-state--mplist-get props :pre-bindings)) + (bindings (evilified-state--mplist-get props :bindings)) + (defkey (when bindings `(evil-define-key 'evilified ,map ,@bindings))) + (body + (progn + (evilified-state--define-pre-bindings map pre-bindings) + `( + ;; we need to work on a local copy of the evilified keymap to + ;; prevent the original keymap from being mutated. + (setq evil-evilified-state-map (copy-keymap ,evilified-map)) + (let* ((sorted-map (evilified-state--sort-keymap + evil-evilified-state-map)) + processed) + (mapc (lambda (map-entry) + (unless (member (car map-entry) processed) + (setq processed (evilified-state--evilify-event + ,map ',map evil-evilified-state-map + (car map-entry) (cdr map-entry))))) + sorted-map) + (unless ,(null defkey) + (,@defkey))) + (unless ,(null mode) + (evilified-state--configure-default-state ',mode)))))) + (if (null eval-after-load) + `(progn ,@body) + `(with-eval-after-load ',eval-after-load (progn ,@body))))) +(put 'evilified-state-evilify-map 'lisp-indent-function 'defun) + +(defun evilified-state--define-pre-bindings (map pre-bindings) + "Define PRE-BINDINGS in MAP." + (while pre-bindings + (let ((key (pop pre-bindings)) + (func (pop pre-bindings))) + (eval `(define-key ,map key ,func))))) + +(defun evilified-state--configure-default-state (mode) + "Configure default state for the passed mode." + (evil-set-initial-state mode 'evilified)) + +(defun evilified-state--evilify-event (map map-symbol evil-map event evil-value + &optional processed pending-funcs) + "Evilify EVENT in MAP and return a list of PROCESSED events." + (if (and event (or evil-value pending-funcs)) + (let* ((kbd-event (kbd (single-key-description event))) + (map-value (lookup-key map kbd-event)) + (evil-value (or evil-value + (lookup-key evil-map kbd-event) + (car (pop pending-funcs))))) + (when evil-value + (evil-define-key 'evilified map kbd-event evil-value)) + (when map-value + (add-to-list 'pending-funcs (cons map-value event) 'append)) + (push event processed) + (setq processed (evilified-state--evilify-event + map map-symbol evil-map + (evilified-state--find-new-event event) nil + processed pending-funcs))) + (when pending-funcs + (spacemacs-buffer/warning + (concat (format (concat "Auto-evilication could not remap these " + "functions in map `%s':\n") + map-symbol) + (mapconcat (lambda (x) + (format " - `%s' originally mapped on `%s'" + (car x) (single-key-description (cdr x)))) + pending-funcs "\n"))))) + processed) + +(defun evilified-state--find-new-event (event) + "Return a new event for the evilified EVENT." + (when event + (cond + ((equal event ?\a) nil) ; C-g (cannot remap C-g) + ((equal event 32) ?') ; space + ((equal event ?/) ?\\) + ((equal event ?:) ?|) + ((and (numberp event) (<= ?a event) (<= event ?z)) (- event 32)) + ((equal event ?G) (+ (expt 2 25) ?\a)) ; G is mapped directly to C-S-g + ((and (numberp event) (<= ?A event) (<= event ?Z)) (- event 64)) + ((and (numberp event) (<= 1 event) (<= event 26)) (+ (expt 2 25) event))))) + +(defun evilified-state--sort-keymap (map) + "Sort MAP following the order: `s' > `S' > `C-s' > `C-S-s'" + (let (list) + (map-keymap (lambda (a b) (push (cons a b) list)) map) + (sort list + (lambda (a b) + (setq a (car a) b (car b)) + (if (integerp a) + (if (integerp b) + (if (and (< a 256) (< b 256)) + (> a b) + (< a b)) + t) + (if (integerp b) nil + (string< a b))))))) + +(defun evilified-state--mplist-get (plist prop) + "Get the values associated to PROP in PLIST, a modified plist. + +A modified plist is one where keys are keywords and values are +all non-keywords elements that follow it. + +If there are multiple properties with the same keyword, only the first property +and its values is returned. + +Currently this function infloops when the list is circular." + (let ((tail plist) + result) + (while (and (consp tail) (not (eq prop (car tail)))) + (pop tail)) + ;; pop the found keyword + (pop tail) + (while (and (consp tail) (not (keywordp (car tail)))) + (push (pop tail) result)) + (nreverse result))) + +(provide 'evil-evilified-state) + +;;; core-evilified-state.el ends here diff --git a/layers/+distributions/spacemacs-base/local/holy-mode/holy-mode.el b/layers/+distributions/spacemacs-base/local/holy-mode/holy-mode.el new file mode 100644 index 0000000..c5ece18 --- /dev/null +++ b/layers/+distributions/spacemacs-base/local/holy-mode/holy-mode.el @@ -0,0 +1,104 @@ +;;; holy-mode.el --- Enter the church of Emacs + +;; Copyright (C) 2014-2015 syl20bnr +;; +;; Author: Sylvain Benner +;; Keywords: convenience editing +;; Created: 18 Mar 2015 +;; Version: 1.00 +;; Package-Requires: ((emacs "24") (evil "1.0.9")) +;; URL: https://github.com/syl20bnr/spacemacs + +;; 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 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 this program. If not, see . + +;;; Commentary: + +;;; Code: + +(defadvice evil-insert-state (around holy-insert-to-emacs-state disable) + "Forces Emacs state." + (if (equal -1 (ad-get-arg 0)) + ad-do-it + (evil-emacs-state))) + +(defadvice evil-motion-state (around holy-motion-to-emacs-state disable) + "Forces Emacs state." + (if (equal -1 (ad-get-arg 0)) + ad-do-it + (evil-emacs-state))) + +(defadvice evil-normal-state (around holy-normal-to-emacs-state disable) + "Forces Emacs state." + (if (equal -1 (ad-get-arg 0)) + ad-do-it + (evil-emacs-state))) + +;;;###autoload +(define-minor-mode holy-mode + "Global minor mode to repulse the evil from spacemacs. + +The `insert state' is replaced by the `emacs state'." + :global t + :lighter " holy" + :group 'spacemacs + (if holy-mode + (in-nominus-patris-et-filii-et-sipritus-sancti) + (amen))) + +(defun in-nominus-patris-et-filii-et-sipritus-sancti () + "Enter the church of Emacs (wash your hands)." + ;; make all buffers' initial state emacs + (push '("." . emacs) evil-buffer-regexps) + ;; replace evil states by `emacs state' + (ad-enable-advice 'evil-insert-state 'around 'holy-insert-to-emacs-state) + (ad-enable-advice 'evil-motion-state 'around 'holy-motion-to-emacs-state) + (ad-enable-advice 'evil-normal-state 'around 'holy-normal-to-emacs-state) + (ad-activate 'evil-insert-state) + (ad-activate 'evil-motion-state) + (ad-activate 'evil-normal-state) + ;; key bindings hooks for dynamic switching of editing styles + (run-hook-with-args 'spacemacs-editing-style-hook 'emacs) + ;; initiate `emacs state' and enter the church + (holy-mode//update-states-for-current-buffers 'emacs)) + +(defun amen () + "May the force be with you my son (or not)." + ;; restore defaults + (setq evil-buffer-regexps (delete '("." . emacs) evil-buffer-regexps)) + ;; restore evil states + (ad-disable-advice 'evil-insert-state 'around 'holy-insert-to-emacs-state) + (ad-disable-advice 'evil-motion-state 'around 'holy-motion-to-emacs-state) + (ad-disable-advice 'evil-normal-state 'around 'holy-normal-to-emacs-state) + (ad-activate 'evil-insert-state) + (ad-activate 'evil-motion-state) + (ad-activate 'evil-normal-state) + ;; restore key bindings + (run-hook-with-args 'spacemacs-editing-style-hook 'vim) + ;; restore the states + (holy-mode//update-states-for-current-buffers 'vim)) + +(defun holy-mode//update-states-for-current-buffers (style) + "Update the active state in all current buffers given current STYLE." + (dolist (buffer (buffer-list)) + (with-current-buffer buffer + (cond + ((eq 'emacs style) (evil-emacs-state)) + ((and (eq 'vim style) + (eq 'emacs evil-state)) + (cond + ((memq major-mode evil-evilified-state-modes) (evil-evilified-state)) + ((memq major-mode evil-motion-state-modes) (evil-motion-state)) + (t (evil-normal-state)))))))) diff --git a/layers/+distributions/spacemacs-base/local/hybrid-mode/hybrid-mode.el b/layers/+distributions/spacemacs-base/local/hybrid-mode/hybrid-mode.el new file mode 100644 index 0000000..4d61798 --- /dev/null +++ b/layers/+distributions/spacemacs-base/local/hybrid-mode/hybrid-mode.el @@ -0,0 +1,165 @@ +;;; hybrid-mode.el --- Put one foot in the church of Emacs + +;; Copyright (C) 2012-2016 Sylvain Benner & Contributors +;; +;; Authors: Justin Burkett +;; Chris Ewald +;; Keywords: convenience editing +;; Created: 12 Aug 2015 +;; Version: 1.00 +;; Package-Requires: ((emacs "24") (evil "1.0.9")) +;; URL: https://github.com/syl20bnr/spacemacs + +;; 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 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 this program. If not, see . + +;;; Commentary: + +;;; Code: + +(require 'evil) + +(defvar hybrid-mode-enable-hjkl-bindings) + +(defcustom hybrid-mode-default-state 'normal + "Value of `evil-default-state' for hybrid-mode." + :group 'spacemacs + :type 'symbol) + +(defcustom hybrid-mode-enable-hjkl-bindings nil + "If non nil then packages configuration should enable hjkl navigation." + :group 'spacemacs + :type 'boolean) + +(defcustom hybrid-mode-enable-evilified-state t + "If non nil then evilified states is enabled in buffer supporting it." + :group 'spacemacs + :type 'boolean) + +(defvar hybrid-mode-default-state-backup evil-default-state + "Backup of `evil-default-state'.") + +(defadvice evil-insert-state (around hybrid-insert-to-hybrid-state disable) + "Forces Hybrid state." + (evil-hybrid-state)) + +(defadvice evil-evilified-state (around hybrid-evilified-to-hybrid-state disable) + "Forces Hybrid state." + (if (equal -1 (ad-get-arg 0)) + ad-do-it + (if hybrid-mode-enable-evilified-state + ad-do-it + ;; seems better to set the emacs state instead of hybrid for evilified + ;; buffers + (evil-emacs-state)))) + +;;;###autoload +(define-minor-mode hybrid-mode + "Global minor mode to replace insert state by hybrid state." + :global t + :lighter " hybrid" + :group 'spacemacs + (if hybrid-mode + (enable-hybrid-editing-style) + (disable-hybrid-editing-style))) + +(defun enable-hybrid-editing-style () + "Enable the hybrid editing style." + (setq hybrid-mode-default-state-backup evil-default-state + evil-default-state hybrid-mode-default-state) + ;; replace evil states by `hybrid state' + (ad-enable-advice 'evil-insert-state + 'around 'hybrid-insert-to-hybrid-state) + (ad-enable-advice 'evil-evilified-state + 'around 'hybrid-evilified-to-hybrid-state) + (ad-activate 'evil-insert-state) + (ad-activate 'evil-evilified-state) + ;; key bindings hooks for dynamic switching of editing styles + (run-hook-with-args 'spacemacs-editing-style-hook 'hybrid) + ;; initiate `hybrid state' + (hybrid-mode//update-states-for-current-buffers 'hybrid)) + +(defun disable-hybrid-editing-style () + "Disable the hybrid editing style (reverting to 'vim style)." + (setq evil-default-state hybrid-mode-default-state-backup) + ;; restore evil states + (ad-disable-advice 'evil-insert-state + 'around 'hybrid-insert-to-hybrid-state) + (ad-disable-advice 'evil-evilified-state + 'around 'hybrid-evilified-to-hybrid-state) + (ad-activate 'evil-insert-state) + (ad-activate 'evil-evilified-state) + ;; restore key bindings + (run-hook-with-args 'spacemacs-editing-style-hook 'vim) + ;; restore the states + (hybrid-mode//update-states-for-current-buffers 'vim)) + +;; This code is from evil insert state definition, any change upstream +;; should be reflected here +;; see https://bitbucket.org/lyro/evil/src/a25b848c90c7942fe89d9ec283c6bb44fb7b3cf4/evil-states.el?fileviewer=file-view-default#evil-states.el-74 +(evil-define-state hybrid + "Hybrid state for hybrid mode." + :tag " " + :cursor (bar . 2) + :message "-- HYBRID --" + :entry-hook (evil-start-track-last-insertion) + :exit-hook (evil-cleanup-insert-state evil-stop-track-last-insertion) + :input-method t + (cond + ((evil-hybrid-state-p) + (add-hook 'post-command-hook #'evil-maybe-remove-spaces) + (add-hook 'pre-command-hook #'evil-insert-repeat-hook) + (setq evil-maybe-remove-spaces t) + (unless (eq evil-want-fine-undo t) + (evil-start-undo-step))) + (t + (remove-hook 'post-command-hook #'evil-maybe-remove-spaces) + (remove-hook 'pre-command-hook #'evil-insert-repeat-hook) + (evil-maybe-remove-spaces t) + (setq evil-insert-repeat-info evil-repeat-info) + (evil-set-marker ?^ nil t) + (unless (eq evil-want-fine-undo t) + (evil-end-undo-step)) + (when evil-move-cursor-back + (when (or (evil-normal-state-p evil-next-state) + (evil-motion-state-p evil-next-state)) + (evil-move-cursor-back)))))) + +(define-key evil-hybrid-state-map [escape] 'evil-normal-state) + +;; Override stock evil function `evil-insert-state-p' +(defun evil-insert-state-p (&optional state) + "Whether the current state is insert." + (and evil-local-mode + (memq (or state evil-state) '(insert hybrid)))) + +(defun hybrid-mode//update-states-for-current-buffers (style) + "Update the active state in all current buffers given current STYLE." + (dolist (buffer (buffer-list)) + (with-current-buffer buffer + (cond + ((eq 'hybrid style) + (if (memq major-mode evil-evilified-state-modes) + (evil-evilified-state) + (funcall (intern (format "evil-%S-state" + hybrid-mode-default-state))))) + ((and (eq 'vim style) + (memq evil-state '(hybrid emacs))) + (cond + ((memq major-mode evil-evilified-state-modes) (evil-evilified-state)) + ((memq major-mode evil-motion-state-modes) (evil-motion-state)) + (t (evil-normal-state)))))))) + +(provide 'hybrid-mode) diff --git a/layers/+distributions/spacemacs-base/packages.el b/layers/+distributions/spacemacs-base/packages.el new file mode 100644 index 0000000..af212ec --- /dev/null +++ b/layers/+distributions/spacemacs-base/packages.el @@ -0,0 +1,531 @@ +;;; packages.el --- Spacemacs Base Layer packages File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq spacemacs-base-packages + '( + (abbrev :location built-in) + ace-window + (archive-mode :location built-in) + (bookmark :location built-in) + (centered-buffer-mode :location local) + (conf-mode :location built-in) + (dired :location built-in) + (dired-x :location built-in) + (electric-indent-mode :location built-in) + (ediff :location built-in) + (eldoc :location built-in) + evil-escape + (evil-evilified-state :location local :step pre :protected t) + evil-visualstar + ;; some packages need to look for binaries, + ;; which means the path must be ready by then + (exec-path-from-shell :step pre) + help-fns+ + (hi-lock :location built-in) + (holy-mode :location local :step pre) + (hybrid-mode :location local :step pre) + (image-mode :location built-in) + (imenu :location built-in) + (linum :location built-in) + (occur-mode :location built-in) + (package-menu :location built-in) + ;; page-break-lines is shipped with spacemacs core + (page-break-lines :location built-in) + pcre2el + (process-menu :location built-in) + projectile + (recentf :location built-in) + (savehist :location built-in) + (saveplace :location built-in) + spacemacs-theme + (subword :location built-in) + (tar-mode :location built-in) + (uniquify :location built-in) + (url :location built-in) + (visual-line-mode :location built-in) + (whitespace :location built-in) + (winner :location built-in) + )) + +;; Initialization of packages + +(defun spacemacs-base/init-abbrev () + (spacemacs|hide-lighter abbrev-mode)) + +(defun spacemacs-base/init-ace-window () + (use-package ace-window + :defer t + :init + (progn + (spacemacs/set-leader-keys + "bD" 'spacemacs/ace-kill-this-buffer + ;; FIXME: Needs new binding. + ;; "wC" 'spacemacs/ace-center-window + "wD" 'spacemacs/ace-delete-window + "wM" 'ace-swap-window + "wW" 'ace-window) + ;; set ace-window keys to home-row + (setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l))))) + +(defun spacemacs-base/init-archive-mode () + (evilified-state-evilify-map archive-mode-map + :mode archive-mode + :eval-after-load archive-mode)) + +(defun spacemacs-base/init-bookmark () + (use-package bookmark + :defer t + :init + (progn + (setq bookmark-default-file (concat spacemacs-cache-directory "bookmarks") + ;; autosave each change + bookmark-save-flag 1) + (spacemacs/set-leader-keys "fb" 'bookmark-jump)))) + +(defun spacemacs-base/init-conf-mode () + :init + ;; explicitly derive conf-mode from text-mode major-mode + (add-hook 'conf-mode-hook 'spacemacs/run-text-mode-hooks)) + +(defun spacemacs-base/init-dired () + (spacemacs/set-leader-keys + "ad" 'dired + "fj" 'dired-jump + "jd" 'dired-jump + "jD" 'dired-jump-other-window)) + +(defun spacemacs-base/init-dired-x () + (use-package dired-x + :commands (dired-jump + dired-jump-other-window + dired-omit-mode))) + +(defun spacemacs-base/init-electric-indent-mode () + (electric-indent-mode)) + +(defun spacemacs-base/init-visual-line-mode () + (spacemacs|diminish visual-line-mode " Ⓛ" " L")) + +;; notes from mijoharas +;; We currently just set a few variables to make it look nicer. +;; Here is my first attempt at evilifying the buffer, does not work correctly, help is very much welcome. + +;; ``` +;; (defun ediff/setup-ediff-keymaps () +;; "setup the evil ediff keymap" +;; (progn +;; (add-to-list 'evil-emacs-state-modes 'Ediff) +;; (evilified-state-evilify ediff-mode-map) +;; (spacemacs/activate-evil-leader-for-map 'ediff-mode-map) +;; ) +;; ) + +;; ;; inside the use-package function +;; (add-hook 'ediff-keymap-setup-hook 'ediff/setup-ediff-keymaps) +;; ``` +(defun spacemacs-base/init-ediff () + (use-package ediff + :defer t + :init + (progn + ;; first we set some sane defaults + (setq-default + ediff-window-setup-function 'ediff-setup-windows-plain + ;; emacs is evil and decrees that vertical shall henceforth be horizontal + ediff-split-window-function 'split-window-horizontally + ediff-merge-split-window-function 'split-window-horizontally) + ;; show org ediffs unfolded + (require 'outline) + (add-hook 'ediff-prepare-buffer-hook #'show-all) + ;; restore window layout when done + (add-hook 'ediff-quit-hook #'winner-undo)))) + +(defun spacemacs-base/init-eldoc () + (use-package eldoc + :defer t + :config + (progn + ;; enable eldoc in `eval-expression' + (add-hook 'eval-expression-minibuffer-setup-hook #'eldoc-mode) + ;; enable eldoc in IELM + (add-hook 'ielm-mode-hook #'eldoc-mode) + ;; don't display eldoc on modeline + (spacemacs|hide-lighter eldoc-mode)))) + +(defun spacemacs-base/init-evil-escape () + (use-package evil-escape + :init (evil-escape-mode) + :config (spacemacs|hide-lighter evil-escape-mode))) + +(defun spacemacs-base/init-evil-evilified-state () + (use-package evil-evilified-state) + (define-key evil-evilified-state-map (kbd dotspacemacs-leader-key) + spacemacs-default-map)) + +(defun spacemacs-base/init-evil-visualstar () + (use-package evil-visualstar + :commands (evil-visualstar/begin-search-forward + evil-visualstar/begin-search-backward) + :init + (progn + (define-key evil-visual-state-map (kbd "*") + 'evil-visualstar/begin-search-forward) + (define-key evil-visual-state-map (kbd "#") + 'evil-visualstar/begin-search-backward)))) + +(defun spacemacs-base/init-exec-path-from-shell () + (use-package exec-path-from-shell + :init (when (or (spacemacs/system-is-mac) + (spacemacs/system-is-linux) + (memq window-system '(x))) + (exec-path-from-shell-initialize)))) + +(defun spacemacs-base/init-help-fns+ () + (use-package help-fns+ + :commands (describe-keymap) + :init (spacemacs/set-leader-keys "hdK" 'describe-keymap))) + +(defun spacemacs-base/init-hi-lock () + (with-eval-after-load 'hi-lock + (spacemacs|hide-lighter hi-lock-mode))) + +(defun spacemacs-base/init-holy-mode () + (use-package holy-mode + :commands holy-mode + :init + (progn + (when (eq 'emacs dotspacemacs-editing-style) + (holy-mode)) + (spacemacs|add-toggle holy-mode + :status holy-mode + :on (progn (when (bound-and-true-p hybrid-mode) + (hybrid-mode -1)) + (holy-mode)) + :off (holy-mode -1) + :documentation "Globally toggle holy mode." + :evil-leader "tEe") + (spacemacs|diminish holy-mode " Ⓔe" " Ee")))) + +(defun spacemacs-base/init-hybrid-mode () + (use-package hybrid-mode + :config + (progn + (when (eq 'hybrid dotspacemacs-editing-style) (hybrid-mode)) + (spacemacs|add-toggle hybrid-mode + :status hybrid-mode + :on (progn (when (bound-and-true-p holy-mode) + (holy-mode -1)) + (hybrid-mode)) + :off (hybrid-mode -1) + :documentation "Globally toggle hybrid mode." + :evil-leader "tEh") + (spacemacs|diminish hybrid-mode " Ⓔh" " Eh")))) + +(defun spacemacs-base/init-image-mode () + (use-package image-mode + :config (evilified-state-evilify-map image-mode-map + :mode image-mode))) + +(defun spacemacs-base/init-imenu () + (use-package imenu + :defer t + :init (spacemacs/set-leader-keys "ji" 'imenu))) + +(defun spacemacs-base/init-linum () + (when dotspacemacs-line-numbers + (add-hook 'prog-mode-hook 'linum-mode) + (add-hook 'text-mode-hook 'linum-mode)) + (setq linum-format "%4d") + (spacemacs|add-toggle line-numbers + :mode linum-mode + :documentation "Show the line numbers." + :evil-leader "tn") + (advice-add #'linum-update-window + :after #'spacemacs/linum-update-window-scale-fix)) + +(defun spacemacs-base/init-occur-mode () + (evilified-state-evilify-map occur-mode-map + :mode occur-mode)) + +(defun spacemacs-base/init-package-menu () + (evilified-state-evilify-map package-menu-mode-map + :mode package-menu-mode)) + +(defun spacemacs-base/init-page-break-lines () + (require 'page-break-lines) + (global-page-break-lines-mode t) + (spacemacs|hide-lighter page-break-lines-mode)) + +(defun spacemacs-base/init-pcre2el () + (use-package pcre2el + :defer t + :init + (progn + (spacemacs/declare-prefix "xr" "regular expressions") + (spacemacs/declare-prefix "xre" "elisp") + (spacemacs/declare-prefix "xrp" "pcre") + (spacemacs/set-leader-keys + "xr/" 'rxt-explain + "xr'" 'rxt-convert-to-strings + "xrt" 'rxt-toggle-elisp-rx + "xrx" 'rxt-convert-to-rx + "xrc" 'rxt-convert-syntax + "xre/" 'rxt-explain-elisp + "xre'" 'rxt-elisp-to-strings + "xrep" 'rxt-elisp-to-pcre + "xret" 'rxt-toggle-elisp-rx + "xrex" 'rxt-elisp-to-rx + "xrp/" 'rxt-explain-pcre + "xrp'" 'rxt-pcre-to-strings + "xrpe" 'rxt-pcre-to-elisp + "xrpx" 'rxt-pcre-to-rx)))) + +(defun spacemacs-base/init-process-menu () + (evilified-state-evilify process-menu-mode process-menu-mode-map)) + +(defun spacemacs-base/init-projectile () + (use-package projectile + :commands (projectile-ack + projectile-ag + projectile-compile-project + projectile-dired + projectile-find-dir + projectile-find-file + projectile-find-tag + projectile-test-project + projectile-grep + projectile-invalidate-cache + projectile-kill-buffers + projectile-multi-occur + projectile-project-p + projectile-project-root + projectile-recentf + projectile-regenerate-tags + projectile-replace + projectile-replace-regexp + projectile-run-async-shell-command-in-root + projectile-run-shell-command-in-root + projectile-switch-project + projectile-switch-to-buffer + projectile-vc) + :init + (progn + ;; note for Windows: GNU find or Cygwin find must be in path to enable + ;; fast indexing + (when (and (spacemacs/system-is-mswindows) (executable-find "find")) + (setq projectile-indexing-method 'alien + projectile-generic-command "find . -type f")) + (setq projectile-sort-order 'recentf + projectile-cache-file (concat spacemacs-cache-directory + "projectile.cache") + projectile-known-projects-file (concat spacemacs-cache-directory + "projectile-bookmarks.eld")) + (spacemacs/set-leader-keys + "pb" 'projectile-switch-to-buffer + "pd" 'projectile-find-dir + "pf" 'projectile-find-file + "pF" 'projectile-find-file-dwim + "ph" 'helm-projectile + "pr" 'projectile-recentf + "pp" 'projectile-switch-project + "pv" 'projectile-vc) + (spacemacs/set-leader-keys + "p!" 'projectile-run-shell-command-in-root + "p&" 'projectile-run-async-shell-command-in-root + "p%" 'projectile-replace-regexp + "pa" 'projectile-toggle-between-implementation-and-test + "pc" 'projectile-compile-project + "pD" 'projectile-dired + "pg" 'projectile-find-tag + "p C-g" 'projectile-regenerate-tags + "pI" 'projectile-invalidate-cache + "pk" 'projectile-kill-buffers + "pR" 'projectile-replace + "pT" 'projectile-test-project)) + :config + (progn + (projectile-global-mode) + (spacemacs|hide-lighter projectile-mode)))) + +(defun spacemacs-base/init-recentf () + (use-package recentf + :defer t + :init + (progn + ;; lazy load recentf + (add-hook 'find-file-hook (lambda () (unless recentf-mode + (recentf-mode) + (recentf-track-opened-file)))) + (setq recentf-save-file (concat spacemacs-cache-directory "recentf") + recentf-max-saved-items 1000 + recentf-auto-cleanup 'never + recentf-auto-save-timer (run-with-idle-timer 600 t + 'recentf-save-list))) + :config + (progn + (add-to-list 'recentf-exclude + (expand-file-name spacemacs-cache-directory)) + (add-to-list 'recentf-exclude (expand-file-name package-user-dir)) + (add-to-list 'recentf-exclude "COMMIT_EDITMSG\\'")))) + +(defun spacemacs-base/init-savehist () + (use-package savehist + :init + (progn + ;; Minibuffer history + (setq savehist-file (concat spacemacs-cache-directory "savehist") + enable-recursive-minibuffers t ; Allow commands in minibuffers + history-length 1000 + savehist-additional-variables '(mark-ring + global-mark-ring + search-ring + regexp-search-ring + extended-command-history) + savehist-autosave-interval 60) + (savehist-mode t)))) + +(defun spacemacs-base/init-saveplace () + (use-package saveplace + :init + (progn + (if (fboundp 'save-place-mode) + ;; Emacs 25 has a proper mode for `save-place' + (save-place-mode) + (setq save-place t)) + ;; Save point position between sessions + (setq save-place-file (concat spacemacs-cache-directory "places"))))) + +(defun spacemacs-base/init-spacemacs-theme () + (use-package spacemacs-theme + :defer t + :init + (progn + (setq spacemacs-theme-comment-bg t) + (setq spacemacs-theme-org-height t)))) + +(defun spacemacs-base/init-subword () + (use-package subword + :defer t + :init + (progn + (unless (category-docstring ?U) + (define-category ?U "Uppercase") + (define-category ?u "Lowercase")) + (modify-category-entry (cons ?A ?Z) ?U) + (modify-category-entry (cons ?a ?z) ?u) + (make-variable-buffer-local 'evil-cjk-word-separating-categories) + (defun spacemacs//subword-enable-camel-case () + "Add support for camel case to subword." + (if subword-mode + (push '(?u . ?U) evil-cjk-word-separating-categories) + (setq evil-cjk-word-separating-categories + (default-value 'evil-cjk-word-separating-categories)))) + (add-hook 'subword-mode-hook 'spacemacs//subword-enable-camel-case) + (spacemacs|add-toggle camel-case-motion + :mode subword-mode + :documentation "Toggle CamelCase motions." + :evil-leader "tc") + (spacemacs|add-toggle camel-case-motion-globally + :mode global-subword-mode + :documentation "Globally toggle CamelCase motions." + :evil-leader "t C-c")) + :config + (spacemacs|diminish subword-mode " ⓒ" " c"))) + +(defun spacemacs-base/init-tar-mode () + (evilified-state-evilify-map tar-mode-map + :mode tar-mode + :eval-after-load tar-mode)) + +(defun spacemacs-base/init-uniquify () + (require 'uniquify) + ;; When having windows with repeated filenames, uniquify them + ;; by the folder they are in rather those annoying <2>,<3>,.. etc + (setq uniquify-buffer-name-style 'post-forward-angle-brackets + ;; don't screw special buffers + uniquify-ignore-buffers-re "^\\*")) + +(defun spacemacs-base/init-url () + ;; gravatars from magit use this to store their cache + (setq url-configuration-directory (concat spacemacs-cache-directory "url/"))) + +(defun spacemacs-base/init-whitespace () + (use-package whitespace + :defer t + :init + (progn + (setq spacemacs-show-trailing-whitespace t) + (defun spacemacs//show-trailing-whitespace () + (when spacemacs-show-trailing-whitespace + (set-face-attribute 'trailing-whitespace nil + :background + (face-attribute 'font-lock-comment-face + :foreground)) + (setq show-trailing-whitespace 1))) + (add-hook 'prog-mode-hook 'spacemacs//show-trailing-whitespace) + + (spacemacs|add-toggle whitespace + :mode whitespace-mode + :documentation "Display whitespace." + :evil-leader "tw") + (spacemacs|add-toggle whitespace-globally + :mode global-whitespace-mode + :documentation "Display whitespace globally." + :evil-leader "t C-w") + + (defun spacemacs//set-whitespace-style-for-diff () + "Whitespace configuration for `diff-mode'" + (setq-local whitespace-style '(face + tabs + tab-mark + spaces + space-mark + trailing + indentation::space + indentation::tab + newline + newline-mark))) + (add-hook 'diff-mode-hook 'whitespace-mode) + (add-hook 'diff-mode-hook 'spacemacs//set-whitespace-style-for-diff)) + :config + (progn + (set-face-attribute 'whitespace-space nil + :background nil + :foreground (face-attribute 'font-lock-warning-face + :foreground)) + (set-face-attribute 'whitespace-tab nil + :background nil) + (set-face-attribute 'whitespace-indentation nil + :background nil) + (spacemacs|diminish whitespace-mode " ⓦ" " w") + (spacemacs|diminish global-whitespace-mode " ⓦ" " w")))) + +(defun spacemacs-base/init-winner () + (use-package winner + :init + (progn + (winner-mode t) + (setq spacemacs/winner-boring-buffers '("*Completions*" + "*Compile-Log*" + "*inferior-lisp*" + "*Fuzzy Completions*" + "*Apropos*" + "*Help*" + "*cvs*" + "*Buffer List*" + "*Ibuffer*" + "*esh command on file*" + )) + (setq winner-boring-buffers + (append winner-boring-buffers spacemacs/winner-boring-buffers)) + (winner-mode t)))) + +(defun spacemacs-base/init-centered-buffer-mode ()) diff --git a/layers/+distributions/spacemacs-bootstrap/config.el b/layers/+distributions/spacemacs-bootstrap/config.el new file mode 100644 index 0000000..c18890a --- /dev/null +++ b/layers/+distributions/spacemacs-bootstrap/config.el @@ -0,0 +1,46 @@ +;;; config.el --- Spacemacs Bootstrap Layer configuration File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Thanks to `editorconfig-emacs' for many of these +(defvar spacemacs--indent-variable-alist + ;; Note that derived modes must come before their sources + '(((awk-mode c-mode c++-mode java-mode groovy-mode + idl-mode java-mode objc-mode pike-mode) . c-basic-offset) + (python-mode . python-indent-offset) + (cmake-mode . cmake-tab-width) + (coffee-mode . coffee-tab-width) + (cperl-mode . cperl-indent-level) + (css-mode . css-indent-offset) + (elixir-mode . elixir-smie-indent-basic) + ((emacs-lisp-mode lisp-mode) . lisp-indent-offset) + (enh-ruby-mode . enh-ruby-indent-level) + (erlang-mode . erlang-indent-level) + (js2-mode . js2-basic-offset) + (js3-mode . js3-indent-level) + ((js-mode json-mode) . js-indent-level) + (latex-mode . (LaTeX-indent-level tex-indent-basic)) + (livescript-mode . livescript-tab-width) + (mustache-mode . mustache-basic-offset) + (nxml-mode . nxml-child-indent) + (perl-mode . perl-indent-level) + (puppet-mode . puppet-indent-level) + (ruby-mode . ruby-indent-level) + (rust-mode . rust-indent-offset) + (scala-mode . scala-indent:step) + (sgml-mode . sgml-basic-offset) + (sh-mode . sh-basic-offset) + (typescript-mode . typescript-indent-level) + (web-mode . web-mode-markup-indent-offset) + (yaml-mode . yaml-indent-offset)) + "An alist where each key is either a symbol corresponding +to a major mode, a list of such symbols, or the symbol t, +acting as default. The values are either integers, symbols +or lists of these.") diff --git a/layers/+distributions/spacemacs-bootstrap/funcs.el b/layers/+distributions/spacemacs-bootstrap/funcs.el new file mode 100644 index 0000000..f186f77 --- /dev/null +++ b/layers/+distributions/spacemacs-bootstrap/funcs.el @@ -0,0 +1,138 @@ +;;; funcs.el --- Spacemacs Bootstrap Layer functions File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + + +(defun spacemacs/state-color-face (state) + "Return the symbol of the face for the given STATE." + (intern (format "spacemacs-%s-face" (symbol-name state)))) + +(defun spacemacs/state-color (state) + "Return the color string associated to STATE." + (face-background (spacemacs/state-color-face state))) + +(defun spacemacs/current-state-color () + "Return the color string associated to the current state." + (face-background (spacemacs/state-color-face evil-state))) + +(defun spacemacs/state-face (state) + "Return the face associated to the STATE." + (spacemacs/state-color-face state)) + +(defun spacemacs/current-state-face () + "Return the face associated to the current state." + (let ((state (if (eq evil-state 'operator) + evil-previous-state + evil-state))) + (spacemacs/state-color-face state))) + +(defun spacemacs/set-state-faces () + (cl-loop for (state color cursor) in spacemacs-evil-cursors + do + (set-face-attribute (intern (format "spacemacs-%s-face" state)) + nil + :foreground (face-background 'mode-line)))) + +(defun evil-insert-state-cursor-hide () + (setq evil-insert-state-cursor '((hbar . 0)))) + +(defun spacemacs/evil-smart-doc-lookup () + "Version of `evil-lookup' that attempts to use + the mode specific goto-definition binding, + i.e. `SPC m h h`, to lookup the source of the definition, + while falling back to `evil-lookup'" + (interactive) + (let ((binding (key-binding (kbd (concat dotspacemacs-leader-key " mhh"))))) + (if (commandp binding) + (call-interactively binding) + (evil-lookup)))) + +(defun spacemacs//set-evil-shift-width () + "Set the value of `evil-shift-width' based on the indentation settings of the +current major mode." + (let ((shift-width + (catch 'break + (dolist (test spacemacs--indent-variable-alist) + (let ((mode (car test)) + (val (cdr test))) + (when (or (and (symbolp mode) (derived-mode-p mode)) + (and (listp mode) (apply 'derived-mode-p mode)) + (eq 't mode)) + (when (not (listp val)) + (setq val (list val))) + (dolist (v val) + (cond + ((integerp v) (throw 'break v)) + ((and (symbolp v) (boundp v)) + (throw 'break (symbol-value v)))))))) + (throw 'break (default-value 'evil-shift-width))))) + (when (and (integerp shift-width) + (< 0 shift-width)) + (setq-local evil-shift-width shift-width)))) + +(defmacro spacemacs|define-text-object (key name start end) + "Define a text object and a surround pair. +START and END are strings (not regular expressions) that define +the boundaries of the text object." + `(progn + (spacemacs|define-text-object-regexp ,key ,name + ,(regexp-quote start) + ,(regexp-quote end)) + (with-eval-after-load 'evil-surround + (push (cons (string-to-char ,key) + (if ,end + (cons ,start ,end) + ,start)) + evil-surround-pairs-alist)))) + +(defmacro spacemacs|define-text-object-regexp (key name start-regexp end-regexp) + "Define a text object. +START-REGEXP and END-REGEXP are the boundaries of the text object." + (let ((inner-name (make-symbol (concat "evil-inner-" name))) + (outer-name (make-symbol (concat "evil-outer-" name)))) + `(progn + (evil-define-text-object ,inner-name (count &optional beg end type) + (evil-select-paren ,start-regexp ,end-regexp beg end type count nil)) + (evil-define-text-object ,outer-name (count &optional beg end type) + (evil-select-paren ,start-regexp ,end-regexp beg end type count t)) + (define-key evil-inner-text-objects-map ,key (quote ,inner-name)) + (define-key evil-outer-text-objects-map ,key (quote ,outer-name))))) + +;; need to delay this macro since it relies on evil key maps to be defined +(with-eval-after-load 'evil + (defmacro evil-map (state key seq) + "Map for a given STATE a KEY to a sequence SEQ of keys. + +Can handle recursive definition only if KEY is the first key of SEQ. +Example: (evil-map visual \"<\" \" +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq spacemacs-bootstrap-packages + '( + (async :step bootstrap) + (bind-map :step bootstrap) + (bind-key :step bootstrap) + (diminish :step bootstrap) + (evil :step bootstrap) + (hydra :step bootstrap) + (use-package :step bootstrap) + (which-key :step bootstrap) + )) + +;; Note: `use-package' cannot be used for bootstrap packages configuration + +(defun spacemacs-bootstrap/init-async ()) + +(defun spacemacs-bootstrap/init-bind-key ()) + +(defun spacemacs-bootstrap/init-diminish () + (when (not (configuration-layer/package-usedp 'spaceline)) + (add-hook 'after-load-functions 'spacemacs/diminish-hook))) + +(defun spacemacs-bootstrap/init-bind-map () + (require 'bind-map) + (bind-map spacemacs-default-map + :prefix-cmd spacemacs-cmds + :keys (dotspacemacs-emacs-leader-key) + :evil-keys (dotspacemacs-leader-key) + :override-minor-modes t + :override-mode-name spacemacs-leader-override-mode)) + +(defun spacemacs-bootstrap/init-evil () + ;; evil-mode is mandatory for Spacemacs to work properly + ;; evil must be require explicitly, the autoload seems to not + ;; work properly sometimes. + (require 'evil) + (evil-mode 1) + + ;; Use evil as a default jump handler + (push 'evil-goto-definition spacemacs-default-jump-handlers) + + (require 'cl) + ;; State cursors + (defvar spacemacs-evil-cursors '(("normal" "DarkGoldenrod2" box) + ("insert" "chartreuse3" (bar . 2)) + ("emacs" "SkyBlue2" box) + ("hybrid" "SkyBlue2" (bar . 2)) + ("replace" "chocolate" (hbar . 2)) + ("evilified" "LightGoldenrod3" box) + ("visual" "gray" (hbar . 2)) + ("motion" "plum3" box) + ("lisp" "HotPink1" box) + ("iedit" "firebrick1" box) + ("iedit-insert" "firebrick1" (bar . 2))) + "Colors assigned to evil states with cursor definitions.") + + (cl-loop for (state color cursor) in spacemacs-evil-cursors + do + (eval `(defface ,(intern (format "spacemacs-%s-face" state)) + `((t (:background ,color + :foreground ,(face-background 'mode-line) + :inherit 'mode-line))) + (format "%s state face." state) + :group 'spacemacs)) + (set (intern (format "evil-%s-state-cursor" state)) + (list (when dotspacemacs-colorize-cursor-according-to-state color) + cursor))) + + (add-hook 'spacemacs-post-theme-change-hook 'spacemacs/set-state-faces) + + ;; put back refresh of the cursor on post-command-hook see status of: + ;; https://bitbucket.org/lyro/evil/issue/502/cursor-is-not-refreshed-in-some-cases + ;; (add-hook 'post-command-hook 'evil-refresh-cursor) + + ;; evil ex-command + (define-key evil-normal-state-map (kbd dotspacemacs-ex-command-key) 'evil-ex) + (define-key evil-visual-state-map (kbd dotspacemacs-ex-command-key) 'evil-ex) + (define-key evil-motion-state-map (kbd dotspacemacs-ex-command-key) 'evil-ex) + (setq evil-ex-substitute-global dotspacemacs-ex-substitute-global) + + ;; evil-want-Y-yank-to-eol must be set via customize to have an effect + (customize-set-variable 'evil-want-Y-yank-to-eol dotspacemacs-remap-Y-to-y$) + + ;; bind evil-jump-forward for GUI only. + (define-key evil-motion-state-map [C-i] 'evil-jump-forward) + + ;; Make the current definition and/or comment visible. + (define-key evil-normal-state-map "zf" 'reposition-window) + ;; toggle maximize buffer + (define-key evil-window-map (kbd "o") 'spacemacs/toggle-maximize-buffer) + (define-key evil-window-map (kbd "C-o") 'spacemacs/toggle-maximize-buffer) + ;; make cursor keys work + (define-key evil-window-map (kbd "") 'evil-window-left) + (define-key evil-window-map (kbd "") 'evil-window-right) + (define-key evil-window-map (kbd "") 'evil-window-up) + (define-key evil-window-map (kbd "") 'evil-window-down) + (spacemacs/set-leader-keys "re" 'evil-show-registers) + ;; motions keys for help buffers + (evil-define-key 'motion help-mode-map (kbd "") 'quit-window) + (evil-define-key 'motion help-mode-map (kbd "") 'forward-button) + (evil-define-key 'motion help-mode-map (kbd "S-") 'backward-button) + (evil-define-key 'motion help-mode-map (kbd "]") 'help-go-forward) + (evil-define-key 'motion help-mode-map (kbd "gf") 'help-go-forward) + (evil-define-key 'motion help-mode-map (kbd "[") 'help-go-back) + (evil-define-key 'motion help-mode-map (kbd "gb") 'help-go-back) + (evil-define-key 'motion help-mode-map (kbd "gh") 'help-follow-symbol) + + ;; It's better that the default value is too small than too big + (setq-default evil-shift-width 2) + ;; After major mode has changed, reset evil-shift-width + (add-hook 'after-change-major-mode-hook 'spacemacs//set-evil-shift-width 'append) + + ;; Keep the region active when shifting + (when dotspacemacs-retain-visual-state-on-shift + (evil-map visual "<" "" ">gv")) + + ;; move selection up and down + (when dotspacemacs-visual-line-move-text + (define-key evil-visual-state-map "J" (concat ":m '>+1" (kbd "RET") "gv=gv")) + (define-key evil-visual-state-map "K" (concat ":m '<-2" (kbd "RET") "gv=gv"))) + + (evil-ex-define-cmd "enew" 'spacemacs/new-empty-buffer) + + (define-key evil-normal-state-map (kbd "K") 'spacemacs/evil-smart-doc-lookup) + (define-key evil-normal-state-map (kbd "gd") 'spacemacs/jump-to-definition) + + ;; scrolling transient state + (spacemacs|define-transient-state scroll + :title "Scrolling Transient State" + :bindings + ("," evil-scroll-page-up "page up") + ("." evil-scroll-page-down "page down") + ;; half page + ("<" evil-scroll-up "half page up") + (">" evil-scroll-down "half page down")) + (spacemacs/set-leader-keys + "n," 'spacemacs/scroll-transient-state/evil-scroll-page-up + "n." 'spacemacs/scroll-transient-state/evil-scroll-page-down + "n<" 'spacemacs/scroll-transient-state/evil-scroll-up + "n>" 'spacemacs/scroll-transient-state/evil-scroll-down) + + ;; pasting transient-state + (evil-define-command spacemacs//transient-state-0 () + :keep-visual t + :repeat nil + (interactive) + (if current-prefix-arg + (progn + (setq this-command #'digit-argument) + (call-interactively #'digit-argument)) + (setq this-command #'evil-beginning-of-line + hydra-deactivate t) + (call-interactively #'evil-beginning-of-line))) + + (spacemacs|define-transient-state paste + :title "Pasting Transient State" + :doc "\n[%s(length kill-ring-yank-pointer)/%s(length kill-ring)] \ + [_C-j_/_C-k_] cycles through yanked text, [_p_/_P_] pastes the same text \ + above or below. Anything else exits." + :bindings + ("C-j" evil-paste-pop) + ("C-k" evil-paste-pop-next) + ("p" evil-paste-after) + ("P" evil-paste-before) + ("0" spacemacs//transient-state-0)) + + (when dotspacemacs-enable-paste-transient-state + (define-key evil-normal-state-map + "p" 'spacemacs/paste-transient-state/evil-paste-after) + (define-key evil-normal-state-map + "P" 'spacemacs/paste-transient-state/evil-paste-before)) + ;; fold transient state + (when (eq 'evil dotspacemacs-folding-method) + (spacemacs|define-transient-state fold + :title "Code Fold Transient State" + :doc " + Close^^ Open^^ Toggle^^ Other^^ + ───────^^────── ─────^^─────────── ─────^^──────────── ─────^^─── + [_c_] at point [_o_] at point [_a_] around point [_q_] quit + ^^ [_O_] recursively ^^ + [_m_] all [_r_] all" + :foreign-keys run + :bindings + ("a" evil-toggle-fold) + ("c" evil-close-fold) + ("o" evil-open-fold) + ("O" evil-open-fold-rec) + ("r" evil-open-folds) + ("m" evil-close-folds) + ("q" nil :exit t) + ("C-g" nil :exit t) + ("" nil :exit t))) + (spacemacs/set-leader-keys "z." 'spacemacs/fold-transient-state/body) + + ;; define text objects + (spacemacs|define-text-object "$" "dollar" "$" "$") + (spacemacs|define-text-object "*" "star" "*" "*") + (spacemacs|define-text-object "8" "block-star" "/*" "*/") + (spacemacs|define-text-object "|" "bar" "|" "|") + (spacemacs|define-text-object "%" "percent" "%" "%") + (spacemacs|define-text-object "/" "slash" "/" "/") + (spacemacs|define-text-object "_" "underscore" "_" "_") + (spacemacs|define-text-object "-" "hyphen" "-" "-") + (spacemacs|define-text-object "~" "tilde" "~" "~") + (spacemacs|define-text-object "=" "equal" "=" "=") + (evil-define-text-object evil-pasted (count &rest args) + (list (save-excursion (evil-goto-mark ?\[) (point)) + (save-excursion (evil-goto-mark ?\]) (point)))) + (define-key evil-inner-text-objects-map "P" 'evil-pasted) + ;; define text-object for entire buffer + (evil-define-text-object evil-inner-buffer (count &optional beg end type) + (list (point-min) (point-max))) + (define-key evil-inner-text-objects-map "g" 'evil-inner-buffer) + + ;; turn off evil in corelv buffers + (push '("\\*LV\\*") evil-buffer-regexps) + + ;; replace `dired-goto-file' with `helm-find-files', since `helm-find-files' + ;; can do the same thing and with fuzzy matching and other features. + (with-eval-after-load 'dired + (evil-define-key 'normal dired-mode-map "J" 'spacemacs/helm-find-files) + (define-key dired-mode-map "j" 'spacemacs/helm-find-files) + (evil-define-key 'normal dired-mode-map (kbd dotspacemacs-leader-key) + spacemacs-default-map)) + + ;; support smart 1parens-strict-mode + (when (configuration-layer/package-usedp 'smartparens) + (defadvice evil-delete-backward-char-and-join + (around spacemacs/evil-delete-backward-char-and-join activate) + (if (bound-and-true-p smartparens-strict-mode) + (call-interactively 'sp-backward-delete-char) + ad-do-it))) + + ;; Define history commands for comint + (when (eq dotspacemacs-editing-style 'vim) + (evil-define-key 'insert comint-mode-map + (kbd "C-k") 'comint-previous-input + (kbd "C-j") 'comint-next-input)) + (evil-define-key 'normal comint-mode-map + (kbd "C-k") 'comint-previous-input + (kbd "C-j") 'comint-next-input)) + +(defun spacemacs-bootstrap/init-hydra () + (require 'hydra) + (setq hydra-key-doc-function 'spacemacs//hydra-key-doc-function + hydra-head-format "[%s] ")) + +(defun spacemacs-bootstrap/init-use-package () + (require 'use-package) + (setq use-package-verbose init-file-debug + ;; inject use-package hooks for easy customization of stock package + ;; configuration + use-package-inject-hooks t)) + +(defun spacemacs-bootstrap/init-which-key () + (require 'which-key) + + (spacemacs|add-toggle which-key + :mode which-key-mode + :documentation + "Display a buffer with available key bindings." + :evil-leader "tK") + + (spacemacs/set-leader-keys "hk" 'which-key-show-top-level) + + ;; Replace rules for better naming of functions + (let ((new-descriptions + ;; being higher in this list means the replacement is applied later + '( + ("spacemacs/\\(.+\\)" . "\\1") + ("spacemacs/toggle-\\(.+\\)" . "\\1") + ("select-window-\\([0-9]\\)" . "window \\1") + ("spacemacs/alternate-buffer" . "last buffer") + ("spacemacs/toggle-mode-line-\\(.+\\)" . "\\1") + ("avy-goto-word-or-subword-1" . "avy word") + ("shell-command" . "shell cmd") + ("spacemacs/default-pop-shell" . "open shell") + ("spacemacs/helm-project-smart-do-search-region-or-symbol" . "smart search w/input") + ("spacemacs/helm-project-smart-do-search" . "smart search") + ("spacemacs/search-project-auto-region-or-symbol" . "search project w/input") + ("spacemacs/search-project-auto" . "search project") + ("helm-descbinds" . "show keybindings") + ("sp-split-sexp" . "split sexp") + ("avy-goto-line" . "avy line") + ("universal-argument" . "universal arg") + ("er/expand-region" . "expand region") + ("helm-apropos" . "apropos") + ("spacemacs/toggle-hybrid-mode" . "hybrid (hybrid-mode)") + ("spacemacs/toggle-holy-mode" . "emacs (holy-mode)") + ("evil-lisp-state-\\(.+\\)" . "\\1") + ("\\(.+\\)-transient-state/\\(.+\\)" . "\\2") + ("\\(.+\\)-transient-state/body" . "\\1-transient-state")))) + (dolist (nd new-descriptions) + ;; ensure the target matches the whole string + (push (cons (concat "\\`" (car nd) "\\'") (cdr nd)) + which-key-description-replacement-alist))) + + (dolist (leader-key `(,dotspacemacs-leader-key ,dotspacemacs-emacs-leader-key)) + (which-key-add-key-based-replacements + (concat leader-key " m") "major mode commands" + (concat leader-key " " dotspacemacs-emacs-command-key) "M-x")) + + (which-key-declare-prefixes + dotspacemacs-leader-key '("root" . "Spacemacs root") + dotspacemacs-emacs-leader-key '("root" . "Spacemacs root") + (concat dotspacemacs-leader-key " m") + '("major-mode-cmd" . "Major mode commands") + (concat dotspacemacs-emacs-leader-key " m") + '("major-mode-cmd" . "Major mode commands")) + + ;; disable special key handling for spacemacs, since it can be + ;; disorienting if you don't understand it + (pcase dotspacemacs-which-key-position + (`right (which-key-setup-side-window-right)) + (`bottom (which-key-setup-side-window-bottom)) + (`right-then-bottom (which-key-setup-side-window-right-bottom))) + + (setq which-key-special-keys nil + which-key-use-C-h-for-paging t + which-key-prevent-C-h-from-cycling t + which-key-echo-keystrokes 0.02 + which-key-max-description-length 32 + which-key-sort-order 'which-key-key-order-alpha + which-key-idle-delay dotspacemacs-which-key-delay + which-key-allow-evil-operators t) + + (which-key-mode) + (spacemacs|diminish which-key-mode " Ⓚ" " K")) diff --git a/layers/+distributions/spacemacs/layers.el b/layers/+distributions/spacemacs/layers.el new file mode 100644 index 0000000..eb652d8 --- /dev/null +++ b/layers/+distributions/spacemacs/layers.el @@ -0,0 +1,28 @@ +;;; layers.el --- Spacemacs Layer layers File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(configuration-layer/declare-layers '(spacemacs-base + spacemacs-completion + spacemacs-layouts + spacemacs-editing + spacemacs-editing-visual + spacemacs-evil + spacemacs-language + spacemacs-misc + spacemacs-ui + spacemacs-ui-visual + spacemacs-org)) +;; If the user has not explicitly declared `helm' or `ivy' +;; and they are using the standard distribution, assume they +;; want `helm' completion. +(unless (or (configuration-layer/layer-usedp 'ivy) + (configuration-layer/layer-usedp 'helm)) + (configuration-layer/declare-layers '(helm))) diff --git a/layers/+emacs/better-defaults/README.org b/layers/+emacs/better-defaults/README.org new file mode 100644 index 0000000..fb7f9a4 --- /dev/null +++ b/layers/+emacs/better-defaults/README.org @@ -0,0 +1,75 @@ +#+TITLE: Better Defaults layer + +[[file:img/emacs.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#smart-line-navigation][Smart line navigation]] + - [[#spacemacsbackward-kill-word-or-region][=spacemacs/backward-kill-word-or-region=]] + - [[#fill-or-unfill-paragraph][Fill or unfill paragraph]] + - [[#install][Install]] + - [[#configuration][Configuration]] + - [[#key-bindings][Key bindings]] + +* Description +This layer enhances the default commands of Emacs and is primarily intended to +be used with the =emacs= editing style as it does not change anything in the Vim +key bindings. + +However the =emacs= editing style is not required, you can still use this layer +while you are using the =vim= editing style if you have some kind of mixed +style. + +The commands defined in this layer are taken from various sources like [[https://github.com/bbatsov/prelude][Prelude]]. + +* Features +** Smart line navigation +Subsequent presses of ~C-a~ toggles between the beginning of the line and the +first non-whitespace character. + +Similarly, subsequent presses of ~C-e~ will toggle between the end of the code +and the end of the comments. + +** =spacemacs/backward-kill-word-or-region= +A combination of =kill-region= and =backward-kill-word=, depending on whether +there is an active region. If there's an active region kill that. If not kill +the preceding word. + +** Fill or unfill paragraph +Pressing ~M-q~ for the first time fills current paragraph and pressing ~M-q~ for +the second time unfills it. Note that some modes override this key binding so +it's not available everywhere. Due to implementation details unfilling doesn't +work when called twice via ~M-x~. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =better-defaults= to the existing =dotspacemacs-configuration-layers= list in +this file. + +* Configuration +Choose if ~C-a~ first brings you to the beginning of the line or the beginning of +the code (first non-whitespace character). + +#+BEGIN_SRC emacs-lisp + (better-defaults :variables + better-defaults-move-to-beginning-of-code-first t) +#+END_SRC + +Choose if ~C-e~ first brings you to the end of the line or the end of the code +(before or after comments). + +#+BEGIN_SRC emacs-lisp + (better-defaults :variables + better-defaults-move-to-end-of-code-first nil) +#+END_SRC + +* Key bindings + +| Key Binding | Description | +|-------------+----------------------------------------------------------------------------------| +| ~C-a~ | move to beginning of line or code | +| ~C-e~ | move to end of line or code | +| ~C-w~ | backward kill word or region | +| ~C-y~ | Automatically indenting after pasting. With prefix argument, paste text as it is | +| ~M-q~ | fill or unfill current paragraph | diff --git a/layers/+emacs/better-defaults/config.el b/layers/+emacs/better-defaults/config.el new file mode 100644 index 0000000..8741cc8 --- /dev/null +++ b/layers/+emacs/better-defaults/config.el @@ -0,0 +1,20 @@ +;;; config.el --- Better Emacs Defaults Layer configuration variables File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Thomas de Beauchêne +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar better-defaults-move-to-beginning-of-code-first t + "when t, first stroke of C-a will move the cursor to the beginning of code. +When nil, first stroke will go to the beginning of line. +Subsequent strokes will toggle between beginning of line and beginning of code.") + +(defvar better-defaults-move-to-end-of-code-first nil + "when t, first stroke of C-e will move the cursor to the end of code (before comments). +When nil, first stroke will go to the end of line (after comments). +Subsequent strokes will toggle between end of line and end of code.") diff --git a/layers/+emacs/better-defaults/funcs.el b/layers/+emacs/better-defaults/funcs.el new file mode 100644 index 0000000..b46ae55 --- /dev/null +++ b/layers/+emacs/better-defaults/funcs.el @@ -0,0 +1,32 @@ +;;; funcs.el --- Better Emacs Defaults Layer functions File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spacemacs/backward-kill-word-or-region (&optional arg) + "Calls `kill-region' when a region is active and +`backward-kill-word' otherwise. ARG is passed to +`backward-kill-word' if no region is active." + (interactive "p") + (if (region-active-p) + ;; call interactively so kill-region handles rectangular selection + ;; correctly (see https://github.com/syl20bnr/spacemacs/issues/3278) + (call-interactively #'kill-region) + (backward-kill-word arg))) + +;; http://endlessparentheses.com/fill-and-unfill-paragraphs-with-a-single-key.html +(defun spacemacs/fill-or-unfill () + "Like `fill-paragraph', but unfill if used twice." + (interactive) + (let ((fill-column + (if (eq last-command 'spacemacs/fill-or-unfill) + (progn (setq this-command nil) + (point-max)) + fill-column))) + (call-interactively #'fill-paragraph))) diff --git a/layers/+emacs/better-defaults/img/emacs.png b/layers/+emacs/better-defaults/img/emacs.png new file mode 100644 index 0000000..9ab43d7 Binary files /dev/null and b/layers/+emacs/better-defaults/img/emacs.png differ diff --git a/layers/+emacs/better-defaults/keybindings.el b/layers/+emacs/better-defaults/keybindings.el new file mode 100644 index 0000000..68c6862 --- /dev/null +++ b/layers/+emacs/better-defaults/keybindings.el @@ -0,0 +1,13 @@ +;;; keybindings.el --- Better Emacs Defaults Layer key bindings File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(global-set-key (kbd "C-w") 'spacemacs/backward-kill-word-or-region) +(global-set-key [remap fill-paragraph] #'spacemacs/fill-or-unfill) diff --git a/layers/+emacs/better-defaults/packages.el b/layers/+emacs/better-defaults/packages.el new file mode 100644 index 0000000..ef7fb2b --- /dev/null +++ b/layers/+emacs/better-defaults/packages.el @@ -0,0 +1,27 @@ +;;; packages.el --- Better Emacs Defaults Layer functions File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Thomas de Beauchêne +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defconst better-defaults-packages + '(mwim) + "The list of Lisp packages required by the mwim layer.") + +(defun better-defaults/init-mwim () + (use-package mwim + :defer t + :init + (progn + (if better-defaults-move-to-beginning-of-code-first + (global-set-key (kbd "C-a") 'mwim-beginning-of-code-or-line) + (global-set-key (kbd "C-a") 'mwim-beginning-of-line-or-code)) + + (if better-defaults-move-to-end-of-code-first + (global-set-key (kbd "C-e") 'mwim-end-of-code-or-line) + (global-set-key (kbd "C-e") 'mwim-end-of-line-or-code))))) diff --git a/layers/+emacs/ibuffer/README.org b/layers/+emacs/ibuffer/README.org new file mode 100644 index 0000000..b351f37 --- /dev/null +++ b/layers/+emacs/ibuffer/README.org @@ -0,0 +1,44 @@ +#+TITLE: IBuffer layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#grouping-buffers][Grouping buffers]] + - [[#key-bindings][Key bindings]] + +* Description + +This layer configures Emacs ibuffer for Spacemacs. + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =ibuffer= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Grouping buffers + +Buffers can be grouped by major-modes or projectile projects. +By default buffers are grouped by major-modes. + +To change how buffers are grouped set the layer variable +=ibuffer-group-buffers-by= to one of the following supported values: +- =modes= to group buffers by major-modes (default) +- =projects= to group buffers by projectile projects +- =nil= to not group buffers + +Example: + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '( + (ibuffer :variables ibuffer-group-buffers-by 'projects))) +#+END_SRC + +* Key bindings + +| Key Binding | Description | +|-------------+-------------------| +| ~SPC b B~ | open ibuffer menu | + +*Note:* The layer will also replace regular ~C-x C-b~ by ibuffer. diff --git a/layers/+emacs/ibuffer/config.el b/layers/+emacs/ibuffer/config.el new file mode 100644 index 0000000..ec0a67f --- /dev/null +++ b/layers/+emacs/ibuffer/config.el @@ -0,0 +1,15 @@ +;;; config.el --- ibuffer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Aleksandr Guljajev +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar ibuffer-group-buffers-by 'modes + "If non nil ibuffer will group the buffers according to the passed symbol. +The supported values are `modes' to group by major-modes and `projects' to +group by projectile projects.") diff --git a/layers/+emacs/ibuffer/funcs.el b/layers/+emacs/ibuffer/funcs.el new file mode 100644 index 0000000..0ded243 --- /dev/null +++ b/layers/+emacs/ibuffer/funcs.el @@ -0,0 +1,46 @@ +;;; funcs.el --- ibuffer Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Aleksandr Guljajev +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spacemacs//ibuffer-get-major-modes-ibuff-rules-list (mm-list result-list) + (if mm-list + (let* ((cur-mm (car mm-list)) + (next-res-list-el `(,(symbol-name cur-mm) (mode . ,cur-mm)))) + (spacemacs//ibuffer-get-major-modes-ibuff-rules-list + (cdr mm-list) (cons next-res-list-el result-list))) + result-list)) + +(defun spacemacs//ibuffer-get-major-modes-list () + (mapcar + (function (lambda (buffer) + (buffer-local-value 'major-mode (get-buffer buffer)))) + (buffer-list (selected-frame)))) + +(defun spacemacs//ibuffer-create-buffs-group () + (interactive) + (let* ((ignore-modes '(Buffer-menu-mode + compilation-mode + minibuffer-inactive-mode + ibuffer-mode + magit-process-mode + messages-buffer-mode + fundamental-mode + completion-list-mode + help-mode + Info-mode)) + (cur-bufs + (list (cons "Home" + (spacemacs//ibuffer-get-major-modes-ibuff-rules-list + (cl-set-difference + (remove-duplicates + (spacemacs//ibuffer-get-major-modes-list)) + ignore-modes) '()))))) + (setq ibuffer-saved-filter-groups cur-bufs) + (ibuffer-switch-to-saved-filter-groups "Home"))) diff --git a/layers/+emacs/ibuffer/packages.el b/layers/+emacs/ibuffer/packages.el new file mode 100644 index 0000000..944f229 --- /dev/null +++ b/layers/+emacs/ibuffer/packages.el @@ -0,0 +1,48 @@ +;;; packages.el --- ibuffer Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Aleksandr Guljajev +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq ibuffer-packages + '( + ibuffer + ibuffer-projectile + )) + +(defun ibuffer/init-ibuffer() + (use-package ibuffer + :defer t + :init + (progn + (spacemacs/set-leader-keys "bB" 'ibuffer) + (global-set-key (kbd "C-x C-b") 'ibuffer) + (defun spacemacs//ibuffer-group-by-modes () + "Group buffers by modes." + (when (eq 'modes ibuffer-group-buffers-by) + (spacemacs//ibuffer-create-buffs-group))) + (add-hook 'ibuffer-hook 'spacemacs//ibuffer-group-by-modes) + + ;; Use ibuffer to provide :ls + (evil-ex-define-cmd "buffers" 'ibuffer)) + :config + (evilified-state-evilify-map ibuffer-mode-map + :mode ibuffer-mode))) + +(defun ibuffer/init-ibuffer-projectile() + (use-package ibuffer-projectile + :defer t + :init + (progn + (defun spacemacs//ibuffer-group-by-projects () + "Group buffers by projects." + (when (eq 'projects ibuffer-group-buffers-by) + (ibuffer-projectile-set-filter-groups) + (unless (eq ibuffer-sorting-mode 'alphabetic) + (ibuffer-do-sort-by-alphabetic)))) + (add-hook 'ibuffer-hook 'spacemacs//ibuffer-group-by-projects)))) diff --git a/layers/+emacs/org/README.org b/layers/+emacs/org/README.org new file mode 100644 index 0000000..0b64c02 --- /dev/null +++ b/layers/+emacs/org/README.org @@ -0,0 +1,493 @@ +#+TITLE: Org layer + +[[file:img/org.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features:]] + - [[#bibtex][BibTeX]] + - [[#important-note][Important Note]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#github-support][Github support]] + - [[#twitter-bootstrap-support][Twitter Bootstrap support]] + - [[#gnuplot-support][Gnuplot support]] + - [[#revealjs-support][Reveal.js support]] + - [[#different-bullets][Different bullets]] + - [[#project-support][Project support]] + - [[#mode-line-support][Mode line support]] + - [[#key-bindings][Key bindings]] + - [[#org][Org]] + - [[#org-with-evil-org-mode][Org with evil-org-mode]] + - [[#tables][Tables]] + - [[#tree][Tree]] + - [[#element-insertion][Element insertion]] + - [[#links][Links]] + - [[#emphasis][Emphasis]] + - [[#tagging][Tagging]] + - [[#navigating-in-calendar][Navigating in calendar]] + - [[#capture-buffers-and-src-blocks][Capture buffers and src blocks]] + - [[#org-agenda][Org agenda]] + - [[#keybindings][Keybindings]] + - [[#org-agenda-transient-state][Org agenda transient state]] + - [[#pomodoro][Pomodoro]] + - [[#presentation][Presentation]] + - [[#org-mime][Org-MIME]] + - [[#org-download][Org-download]] + - [[#org-projectile][Org-projectile]] + +* Description +This layer enables [[http://orgmode.org/][org mode]] for Spacemacs. + +** Features: +- Vim inspired key bindings are provided by [[https://github.com/edwtjo/evil-org-mode][evil-org-mode]] +- Nicer bullet via [[https://github.com/sabof/org-bullets][org-bullets]] +- A [[http://pomodorotechnique.com/][pomodoro method]] integration via [[https://github.com/lolownia/org-pomodoro][org-pomodoro]] +- Presentation mode via [[https://github.com/rlister/org-present][org-present]] +- Insertion of images via [[https://github.com/abo-abo/org-download][org-download]] +- Project-specific TODOs via [[https://github.com/IvanMalison/org-projectile][org-projectile]] + +** BibTeX +For more extensive support of references through BibTeX files, have a look at +the [[../+lang/bibtex][BibTeX layer]]. + +** Important Note +Since version 0.104, spacemacs uses the =org= version from the org ELPA +repository instead of the one shipped with emacs. Then, any =org= related code +should not be loaded before =dotspacemacs/user-config=, otherwise both versions +will be loaded and will conflict. + +Because of autoloading, calling to =org= functions will trigger the loading up +of the =org= shipped with emacs which will induce conflicts. +One way to avoid conflict is to wrap your =org= config code in a +=with-eval-after-load= block like this: + +#+BEGIN_SRC emacs-lisp + (with-eval-after-load 'org + ;; here goes your Org config :) + ;; .... + ) +#+END_SRC + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =org= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Github support +To install Github related extensions like [[https://github.com/larstvei/ox-gfm][ox-gfm]] to export to Github +flavored markdown set the variable =org-enable-github-support= to =t=. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '( + (org :variables org-enable-github-support t))) +#+END_SRC + +** Twitter Bootstrap support +To install the Twitter Boostrap extension (from [[https://github.com/marsmining/ox-twbs][ox-twbs]]), which enables twitter +bootstrap formatted html, then set the variable =org-enable-bootstrap-support= +to =t=. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '( + (org :variables + org-enable-bootstrap-support t))) +#+END_SRC + +** Gnuplot support +Org-mode support the plotting of data within tables through [[http://www.gnuplot.info/][Gnuplot]] as +demonstrated [[http://orgmode.org/worg/org-tutorials/org-plot.html][here]]; unfortunately, this is [[https://github.com/bruceravel/gnuplot-mode/issues/15][not terribly well supported]] on Windows +at this stage. It is possible to disable the configuration of gnuplot support +as usual by adding the package =gnuplot= to your =dotspacemacs-excluded-packages= +variable. + +** Reveal.js support +To enable the export of your org file as a [[http://lab.hakim.se/reveal-js/][reveal.js]] presentation, set the +variable =org-enable-reveal-js-support= to =t=. This will install the [[https://github.com/yjwen/org-reveal/][org-reveal]] +extension. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers + '((org :variables org-enable-reveal-js-support t))) +#+END_SRC + +In order to be able to use org-reveal, download =reveal.js= from its +[[http://lab.hakim.se/reveal-js/#/][homepage]] and set =org-reveal-js= to the +download path, as described in the [[https://github.com/yjwen/org-reveal#obtain-revealjs][manual]]. Alternatively, add the following line +to each =.org= file you want to process: + +#+BEGIN_EXAMPLE +#+REVEAL_ROOT: http://cdn.jsdelivr.net/reveal.js/3.0.0/ +#+END_EXAMPLE + +** Different bullets +You can tweak the bullets displayed in the org buffer in the function +=dotspacemacs/user-config= of your dotfile by setting the variable +=org-bullets-bullet-list=. By default the list is set to =("◉" "○" "✸" "✿")=. + +#+BEGIN_SRC emacs-lisp + (setq org-bullets-bullet-list '("■" "◆" "▲" "▶")) +#+END_SRC + +** Project support +Set the layer variable =org-projectile-file= to the filename where you want to +store project-specific TODOs. If this is an absolute path, all todos will be +stored in the same file (organized by project), whereas if it is just a single +filename, todos will be stored in each project root. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers + '((org :variables org-projectile-file "TODOs.org"))) +#+END_SRC + +The TODO files are not added to the agenda automatically. You can do this with +the following snippet. Note that this may have unintended consequences until +[[https://github.com/IvanMalison/org-projectile/issues/10][this bug]] is fixed. + +#+BEGIN_SRC emacs-lisp + (with-eval-after-load 'org-agenda + (require 'org-projectile) + (push (org-projectile:todo-files) org-agenda-files)) +#+END_SRC + +** Mode line support +To temporarily enable mode line display of org clock, press ~SPC t m c~. + +To permanently enable mode line display of org clock, add this snippet to your +=dotspacemacs/user-config= function: + +#+BEGIN_SRC elisp + (setq spaceline-org-clock-p t) +#+END_SRC + +* Key bindings +** Org + +| Key Binding | Description | +|-------------+--------------------------------| +| ~SPC a o #~ | org agenda list stuck projects | +| ~SPC a o /~ | org occur in agenda files | +| ~SPC a o a~ | org agenda list | +| ~SPC a o c~ | org capture | +| ~SPC a o e~ | org store agenda views | +| ~SPC a o l~ | org store link | +| ~SPC a o m~ | org tags view | +| ~SPC a o o~ | org agenda | +| ~SPC a o O~ | org clock out | +| ~SPC a o s~ | org search view | +| ~SPC a o t~ | org todo list | +| ~SPC C c~ | org-capture | + +** Org with evil-org-mode + +| Key Binding | Description | +|----------------------------------------------+----------------------------------------------| +| ~SPC m ~ | org-ctrl-c-ctrl-c | +| ~SPC m *~ | org-ctrl-c-star | +| ~SPC m RET~ | org-ctrl-c-ret | +| ~SPC m -~ | org-ctrl-c-minus | +| ~SPC m '​~ | org-edit-special | +| ~SPC m ^~ | org-sort | +| ~SPC m /~ | org-sparse-tree | +| ~SPC m .~ | org-time-stamp | +| ~SPC m !~ | org-time-stamp-inactive | +| ~SPC m a~ | org-agenda | +| ~SPC m b~ | org-tree-to-indirect-buffer | +| ~SPC m A~ | org-archive-subtree | +| ~SPC m c~ | org-capture | +| ~SPC m C~ | evil-org-recompute-clocks | +| ~SPC m d~ | org-deadline | +| ~SPC m D~ | org-insert-drawer | +| ~SPC m e~ | org-export-dispatch | +| ~SPC m f~ | org-set-effort | +| ~SPC m I~ | org-clock-in | +| ~SPC m l~ | org-open-at-point | +| ~SPC m n~ | org-narrow-to-subtree | +| ~SPC m N~ | widen | +| ~SPC m O~ | org-clock-out | +| ~SPC m P~ | org-set-property | +| ~SPC m q~ | org-clock-cancel | +| ~SPC m R~ | org-refile | +| ~SPC m s~ | org-schedule | +| ~SPC m T~ | org-show-todo-tree | +| ~SPC m L~ | org-shiftright | +| ~SPC m H~ | org-shiftleft | +| ~SPC m K~ | org-shiftup | +| ~SPC m J~ | org-shiftdown | +| ~SPC m C-S-l~ | org-shiftcontrolright | +| ~SPC m C-S-h~ | org-shiftcontrolleft | +| ~SPC m C-S-j~ | org-shiftcontroldown | +| ~SPC m C-S-k~ | org-shiftcontrolup | +| ~SPC s j~ | spacemacs/jump-in-buffer (jump to a heading) | + +*** Tables + +| Key Binding | Description | +|---------------+----------------------------------------------------------------------------| +| ~SPC m t a~ | Align the table at point by aligning all vertical bars | +| ~SPC m t b~ | Blank the current table field or active region | +| ~SPC m t c~ | Convert from =org-mode= table to table.el and back | +| ~SPC m t d c~ | Delete a column from the table | +| ~SPC m t d r~ | Delete the current row or horizontal line from the table | +| ~SPC m t e~ | Replace the table field value at the cursor by the result of a calculation | +| ~SPC m t E~ | Export table to a file, with configurable format | +| ~SPC m t h~ | Go to the previous field in the table | +| ~SPC m t H~ | Move column to the left | +| ~SPC m t i c~ | Insert a new column into the table | +| ~SPC m t i h~ | Insert a horizontal-line below the current line into the table | +| ~SPC m t i H~ | Insert a hline and move to the row below that line | +| ~SPC m t i r~ | Insert a new row above the current line into the table | +| ~SPC m t I~ | Import a file as a table | +| ~SPC m t j~ | Go to the next row (same column) in the current table | +| ~SPC m t J~ | Move table row down | +| ~SPC m t K~ | Move table row up | +| ~SPC m t l~ | Go to the next field in the current table, creating new lines as needed | +| ~SPC m t L~ | Move column to the right | +| ~SPC m t n~ | Query for a size and insert a table skeleton | +| ~SPC m t N~ | Use the table.el package to insert a new table | +| ~SPC m t p~ | Plot the table using org-plot/gnuplot | +| ~SPC m t r~ | Recalculate the current table line by applying all stored formulas | +| ~SPC m t s~ | Sort table lines according to the column at point | +| ~SPC m t t f~ | Toggle the formula debugger in tables | +| ~SPC m t t o~ | Toggle the display of Row/Column numbers in tables | +| ~SPC m t w~ | Wrap several fields in a column like a paragraph | + +*** Tree + +| Key Binding | Description | +|-------------+-----------------------| +| ~SPC m S l~ | org-demote-subtree | +| ~SPC m S h~ | org-promote-subtree | +| ~SPC m S k~ | org-move-subtree-up | +| ~SPC m S j~ | org-move-subtree-down | + +| Key Binding | Description | +|-------------+---------------------------------| +| ~TAB~ | org-cycle | +| ~$~ | org-end-of-line | +| ~^~ | org-beginning-of-line | +| ~<~ | org-metaleft | +| ~>~ | org-metaright | +| ~gh~ | outline-up-heading | +| ~gj~ | org-forward-heading-same-level | +| ~gk~ | org-backward-heading-same-level | +| ~gl~ | outline-next-visible-heading | +| ~t~ | org-todo | +| ~T~ | org-insert-todo-heading nil | +| ~H~ | org-beginning-of-line | +| ~L~ | org-end-of-line | +| ~o~ | always-insert-item | +| ~O~ | org-open-above | + +| Key Binding | Description | +|-------------+--------------------------------------------| +| ~M-l~ | org-metaright | +| ~M-h~ | org-metaleft | +| ~M-k~ | org-metaup | +| ~M-j~ | org-metadown | +| ~M-L~ | org-shiftmetaright | +| ~M-H~ | org-shiftmetaleft | +| ~M-K~ | org-shiftmetaup | +| ~M-J~ | org-shiftmetadown | +| ~M-o~ | org-insert-heading+org-metaright | +| ~M-t~ | org-insert-todo-heading nil+ org-metaright | + +*** Element insertion + +| Key Binding | Description | +|-------------+----------------------------------| +| ~SPC m h i~ | org-insert-heading-after-current | +| ~SPC m h I~ | org-insert-heading | +| ~SPC m h s~ | org-insert-subheading | +| ~SPC m i f~ | org-insert-footnote | +| ~SPC m i l~ | org-insert-link | + +*** Links + +| Key Binding | Description | +|-------------+-------------------| +| ~RET~ | org-open-at-point | + +*** Emphasis + +| Key Binding | Description | +|-------------+----------------------------| +| ~SPC m x b~ | make region bold | +| ~SPC m x c~ | make region code | +| ~SPC m x i~ | make region italic | +| ~SPC m x r~ | clear region emphasis | +| ~SPC m x s~ | make region strike-through | +| ~SPC m x u~ | make region underline | +| ~SPC m x v~ | make region verbose | + +*** Tagging + +| Key Binding | Description | +|-------------+--------------| +| ~SPC m :~ | org-set-tags | + +*** Navigating in calendar + +| Key Binding | Description | +|-------------+--------------------| +| ~M-l~ | One day forward | +| ~M-h~ | One day backward | +| ~M-j~ | One week forward | +| ~M-k~ | One week backward | +| ~M-L~ | One month forward | +| ~M-H~ | One month backward | +| ~M-J~ | One year forward | +| ~M-K~ | One year backward | + +** Capture buffers and src blocks +=org-capture-mode= and =org-src-mode= both support the confirm and abort +conventions. + +| Key Binding | Description | +|----------------------------------------------+----------------------------------------| +| ~SPC m ~ | confirm in =org-capture-mode= | +| ~SPC m '​~ | confirm in =org-src-mode= | +| ~SPC m c~ | confirm | +| ~SPC m a~ | abort | +| ~SPC m k~ | abort | +| ~SPC m r~ | org-capture-refile in org-capture-mode | + +** Org agenda + +*** Keybindings +The evilified org agenda supports the following bindings: + +| Key Binding | Description | +|----------------------+-----------------------------------| +| ~M-SPC~ or ~s-M-SPC~ | org-agenda transient state | +| ~SPC m :~ | org-agenda-set-tags | +| ~SPC m a~ | org-agenda | +| ~SPC m d~ | org-agenda-deadline | +| ~SPC m f~ | org-agenda-set-effort | +| ~SPC m I~ | org-agenda-clock-in | +| ~SPC m O~ | org-agenda-clock-out | +| ~SPC m p~ | org-pomodoro (if package is used) | +| ~SPC m P~ | org-agenda-set-property | +| ~SPC m q~ | org-agenda-refile | +| ~SPC m Q~ | org-agenda-clock-cancel | +| ~SPC m s~ | org-agenda-schedule | +| ~M-j~ | next item | +| ~M-k~ | previous item | +| ~M-h~ | earlier view | +| ~M-l~ | later view | +| ~gr~ | refresh | +| ~gd~ | toggle grid | +| ~C-v~ | change view | +| ~RET~ | org-agenda-goto | +| ~M-RET~ | org-agenda-show-and-scroll-up | + +*** Org agenda transient state +Use ~M-SPC~ or ~s-M-SPC~ in an org agenda buffer to activate its transient state. +The transient state aims to list the most useful org agenda commands and +visually organize them by category. The commands associated with each binding +are listed bellow. + +| Keybinding | Description | Command | +|-------------+---------------------+-----------------------------------| +| Entry | | | +|-------------+---------------------+-----------------------------------| +| ~ht~ | set status | org-agenda-todo | +| ~hk~ | kill | org-agenda-kill | +| ~hr~ | refile | org-agenda-refile | +| ~hA~ | archive | org-agenda-archive-default | +| ~hT~ | set tags | org-agenda-set-tags | +| ~hp~ | set priority | org-agenda-priority | +|-------------+---------------------+-----------------------------------| +| Visit entry | | | +|-------------+---------------------+-----------------------------------| +| ~SPC~ | in other window | org-agenda-show-and-scroll-up | +| ~TAB~ | & go to location | org-agenda-goto | +| ~RET~ | & del other windows | org-agenda-switch-to | +| ~o~ | link | link-hint-open-link | +|-------------+---------------------+-----------------------------------| +| Filter | | | +|-------------+---------------------+-----------------------------------| +| ~ft~ | by tag | org-agenda-filter-by-tag | +| ~fr~ | refine by tag | org-agenda-filter-by-tag-refine | +| ~fc~ | by category | org-agenda-filter-by-category | +| ~fh~ | by top headline | org-agenda-filter-by-top-headline | +| ~fx~ | by regexp | org-agenda-filter-by-regexp | +| ~fd~ | delete all filters | org-agenda-filter-remove-all | +|-------------+---------------------+-----------------------------------| +| Date | | | +|-------------+---------------------+-----------------------------------| +| ~ds~ | schedule | org-agenda-schedule | +| ~dd~ | set deadline | org-agenda-deadline | +| ~dt~ | timestamp | org-agenda-date-prompt | +| ~+~ | do later | org-agenda-do-date-later | +| ~-~ | do earlier | org-agenda-do-date-earlier | +|-------------+---------------------+-----------------------------------| +| Toggle | | | +|-------------+---------------------+-----------------------------------| +| ~tf~ | follow | org-agenda-follow-mode | +| ~tl~ | log | org-agenda-log-mode | +| ~ta~ | archive | org-agenda-archives-mode | +| ~tr~ | clock report | org-agenda-clockreport-mode | +| ~td~ | diaries | org-agenda-toggle-diary | +|-------------+---------------------+-----------------------------------| +| View | | | +|-------------+---------------------+-----------------------------------| +| ~vd~ | day | org-agenda-day-view | +| ~vw~ | week | org-agenda-week-view | +| ~vt~ | fortnight | org-agenda-fortnight-view | +| ~vm~ | month | org-agenda-month-view | +| ~vy~ | year | org-agenda-year-view | +| ~vn~ | next span | org-agenda-later | +| ~vp~ | prev span | org-agenda-earlier | +| ~vr~ | reset | org-agenda-reset-view | +|-------------+---------------------+-----------------------------------| +| Clock | | | +|-------------+---------------------+-----------------------------------| +| ~ci~ | in | org-agenda-clock-in | +| ~co~ | out | org-agenda-clock-out | +| ~ck~ | cancel | org-agenda-clock-cancel | +| ~cj~ | jump | org-agenda-clock-goto | +|-------------+---------------------+-----------------------------------| +| Other | | | +|-------------+---------------------+-----------------------------------| +| ~gr~ | reload | org-agenda-redo | +| ~.~ | go to today | org-agenda-goto-today | +| ~gd~ | go to date | org-agenda-goto-date | + +** Pomodoro + +| Key Binding | Description | +|-------------+-------------------| +| ~SPC m p~ | starts a pomodoro | + +** Presentation +org-present must be activated explicitly by typing: ~SPC SPC org-present~ + +| Key Binding | Description | +|-------------+----------------| +| ~h~ | previous slide | +| ~l~ | next slide | +| ~q~ | quit | + +** Org-MIME + +| Key Binding | Description | +|-------------+---------------------------------------------------| +| ~SPC m M~ | in =message-mode= buffers convert into html email | +| ~SPC m m~ | send current buffer as HTML email message | + +** Org-download + +| Key Binding | Description | +|-------------+-----------------| +| ~SPC m i s~ | Take screenshot | +| ~SPC m i y~ | Yank image url | + +** Org-projectile + +| Key Binding | Description | +|-------------------+---------------------------------------------------------| +| ~SPC a o p~ | Capture a TODO for the current project | +| ~SPC u SPC a o p~ | Capture a TODO for any given project (choose from list) | +| ~SPC p o~ | Go to the TODOs for the current project | diff --git a/layers/+emacs/org/config.el b/layers/+emacs/org/config.el new file mode 100644 index 0000000..72dfc32 --- /dev/null +++ b/layers/+emacs/org/config.el @@ -0,0 +1,29 @@ +;;; config.el --- Org configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(defvar org-enable-bootstrap-support nil + "If non-nil Twitter Bootstrap related packages are configured.") + +(defvar org-enable-github-support nil + "If non-nil Github related packages are configured.") + +(defvar org-enable-reveal-js-support nil + "If non-nil, enable export to reveal.js.") + +(defvar org-projectile-file "TODOs.org" + "The file to store project TODOs in. If this is a relative +path, one file per project is used (and the path is relative to +the project root). If it an absolute path, one global file is +used.") + +(spacemacs|defvar-company-backends org-mode) diff --git a/layers/+emacs/org/funcs.el b/layers/+emacs/org/funcs.el new file mode 100644 index 0000000..38669ea --- /dev/null +++ b/layers/+emacs/org/funcs.el @@ -0,0 +1,37 @@ +;;; funcs.el --- Org Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun org-projectile/capture (&optional arg) + (interactive "P") + (if arg + (org-projectile:project-todo-completing-read nil :empty-lines 1) + (org-projectile:capture-for-current-project nil :empty-lines 1))) + +(defun org-projectile/goto-todos () + (interactive) + (org-projectile:location-for-project (projectile-project-name))) + + + +(defun spacemacs/ob-fix-inline-images () + "Fix redisplay of inline images after a code block evaluation." + (when org-inline-image-overlays + (org-redisplay-inline-images))) + + + +(defun spacemacs//surround-drawer () + (let ((dname (read-from-minibuffer "" ""))) + (cons (format ":%s:" (upcase (or dname ""))) ":END:"))) + +(defun spacemacs//surround-code () + (let ((dname (read-from-minibuffer "" ""))) + (cons (format "#+BEGIN_SRC %s" (or dname "")) "#+END_SRC"))) diff --git a/layers/+emacs/org/img/org.png b/layers/+emacs/org/img/org.png new file mode 100644 index 0000000..059212a Binary files /dev/null and b/layers/+emacs/org/img/org.png differ diff --git a/layers/+emacs/org/local/evil-org/evil-org.el b/layers/+emacs/org/local/evil-org/evil-org.el new file mode 100644 index 0000000..ea8e419 --- /dev/null +++ b/layers/+emacs/org/local/evil-org/evil-org.el @@ -0,0 +1,182 @@ +;;; evil-org.el --- evil keybindings for org-mode + +;; Copyright (C) 2012-2014 by Edward Tjörnhammar +;; Author: Edward Tjörnhammar +;; URL: https://github.com/edwtjo/evil-org-mode.git +;; Package-Version: 20150513.1610 +;; Git-Repository; git://github.com/edwtjo/evil-org-mode.git +;; Created: 2012-06-14 +;; Version: 0.1.1 +;; Package-Requires: ((evil "0") (org "0")) +;; Keywords: evil vim-emulation org-mode key-bindings presets + +;; 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 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 this program. If not, see . + +;;; Commentary: +;; +;; Known Bugs: +;; See, https://github.com/edwtjo/evil-org-mode/issues +;; +;;; Code: +(require 'evil) +(require 'org) + +(define-minor-mode evil-org-mode + "Buffer local minor mode for evil-org" + :init-value nil + :lighter " EvilOrg" + :keymap (make-sparse-keymap) ; defines evil-org-mode-map + :group 'evil-org) + +(add-hook 'org-mode-hook 'evil-org-mode) ;; only load with org-mode + +(defun clever-insert-item () + "Clever insertion of org item." + (if (not (org-in-item-p)) + (insert "\n") + (org-insert-item)) + ) + +(defun evil-org-eol-call (fun) + "Go to end of line and call provided function. +FUN function callback" + (end-of-line) + (funcall fun) + (evil-append nil) + ) + +;; recompute clocks in visual selection +(evil-define-operator evil-org-recompute-clocks (beg end type register yank-handler) + :keep-visual t + :move-point nil + (interactive "") + (progn + (message "start!" ) + (save-excursion + (while (< (point) end) + (org-evaluate-time-range) + (next-line) + (message "at position %S" (point)) + )))) + +;; open org-mode links in visual selection +(defun evil-org-generic-open-links (beg end type register yank-handler incog) + (progn + (save-excursion + (goto-char beg) + (catch 'break + (while t + (org-next-link) + ;;; break from outer loop when there are no more + ;;; org links + (when (or + (not (< (point) end)) + (not (null org-link-search-failed))) + (throw 'break 0)) + + (if (not (null incog)) + (let* ((new-arg + ;;; if incog is true, decide which incognito settings to + ;;; use dependening on the browser + (cond ((not (null (string-match "^.*\\(iceweasel\\|firefox\\).*$" browse-url-generic-program))) "--private-window") + ((not (null (string-match "^.*\\(chrome\\|chromium\\).*$" browse-url-generic-program))) "--incognito" ) + (t "") + )) + (old-b (list browse-url-generic-args " " )) + (browse-url-generic-args (add-to-ordered-list 'old-b new-arg 0))) + (progn + (org-open-at-point))) + (let ((browse-url-generic-args '(""))) + (org-open-at-point))) + ))))) + + +;;; open links in visual selection +(evil-define-operator evil-org-open-links (beg end type register yank-handler) + :keep-visual t + :move-point nil + (interactive "") + (evil-org-generic-open-links beg end type register yank-handler nil) +) + +;;; open links in visual selection in incognito mode +(evil-define-operator evil-org-open-links-incognito (beg end type register yank-handler) + :keep-visual t + :move-point nil + (interactive "") + (evil-org-generic-open-links beg end type register yank-handler t) +) + +;; normal state shortcuts +(evil-define-key 'normal evil-org-mode-map + "gh" 'outline-up-heading + "gp" 'outline-previous-heading + "gj" (if (fboundp 'org-forward-same-level) ;to be backward compatible with older org version + 'org-forward-same-level + 'org-forward-heading-same-level) + "gk" (if (fboundp 'org-backward-same-level) + 'org-backward-same-level + 'org-backward-heading-same-level) + "gl" 'outline-next-visible-heading + "t" 'org-todo + "T" '(lambda () (interactive) (evil-org-eol-call (lambda() (org-insert-todo-heading nil)))) + "o" '(lambda () (interactive) (evil-org-eol-call 'clever-insert-item)) + "O" '(lambda () (interactive) (evil-org-eol-call 'org-insert-heading)) + "$" 'org-end-of-line + "^" 'org-beginning-of-line + "<" 'org-metaleft + ">" 'org-metaright + "-" 'org-cycle-list-bullet + (kbd "TAB") 'org-cycle) + +;; normal & insert state shortcuts. +(mapc (lambda (state) + (evil-define-key state evil-org-mode-map + (kbd "M-l") 'org-metaright + (kbd "M-h") 'org-metaleft + (kbd "M-k") 'org-metaup + (kbd "M-j") 'org-metadown + (kbd "M-L") 'org-shiftmetaright + (kbd "M-H") 'org-shiftmetaleft + (kbd "M-K") 'org-shiftmetaup + (kbd "M-J") 'org-shiftmetadown + (kbd "M-o") '(lambda () (interactive) + (evil-org-eol-call + '(lambda() + (org-insert-heading) + (org-metaright)))) + (kbd "M-t") '(lambda () (interactive) + (evil-org-eol-call + '(lambda() + (org-insert-todo-heading nil) + (org-metaright)))) + )) + '(normal insert)) + +;; vim-like confirm/abort for capture and src +(with-eval-after-load 'org-capture + (define-key org-capture-mode-map [remap evil-save-and-close] 'org-capture-finalize) + (define-key org-capture-mode-map [remap evil-save-modified-and-close] 'org-capture-finalize) + (define-key org-capture-mode-map [remap evil-quit] 'org-capture-kill)) + +(with-eval-after-load 'org-src + (define-key org-src-mode-map [remap evil-save-and-close] 'org-edit-src-exit) + (define-key org-src-mode-map [remap evil-save-modified-and-close] 'org-edit-src-exit) + (define-key org-src-mode-map [remap evil-quit] 'org-edit-src-abort)) + + +(provide 'evil-org) +;;; evil-org.el ends here diff --git a/layers/+emacs/org/local/org-async-init.el b/layers/+emacs/org/local/org-async-init.el new file mode 100644 index 0000000..1f70489 --- /dev/null +++ b/layers/+emacs/org/local/org-async-init.el @@ -0,0 +1,10 @@ +(require 'package) +(setq package-enable-at-startup nil) +(package-initialize) + +(require 'org) +(require 'ox) +(require 'ox-beamer) +(require 'ox-latex) +(require 'cl) +(setq org-export-async-debug nil) diff --git a/layers/+emacs/org/local/ox-gfm/ox-gfm.el b/layers/+emacs/org/local/ox-gfm/ox-gfm.el new file mode 100644 index 0000000..408166a --- /dev/null +++ b/layers/+emacs/org/local/ox-gfm/ox-gfm.el @@ -0,0 +1,191 @@ +;;; ox-gfm.el --- Github Flavored Markdown Back-End for Org Export Engine + +;; Copyright (C) 2014 Lars Tveito + +;; Author: Lars Tveito +;; Keywords: org, wp, markdown, github +;; Package-Version: 20141211.240 + +;; This file is not part of GNU Emacs. + +;; GNU Emacs 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. + +;; GNU Emacs 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 . + +;;; Commentary: + +;; This library implements a Markdown back-end (github flavor) for Org +;; exporter, based on the `md' back-end. + +;;; Code: + +(require 'ox-md) + + + +;;; User-Configurable Variables + +(defgroup org-export-gfm nil + "Options specific to Markdown export back-end." + :tag "Org Github Flavored Markdown" + :group 'org-export + :version "24.4" + :package-version '(Org . "8.0")) + + +;;; Define Back-End + +(org-export-define-derived-backend 'gfm 'md + :export-block '("GFM" "GITHUB FLAVORED MARKDOWN") + :filters-alist '((:filter-parse-tree . org-md-separate-elements)) + :menu-entry + '(?g "Export to Github Flavored Markdown" + ((?G "To temporary buffer" + (lambda (a s v b) (org-gfm-export-as-markdown a s v))) + (?g "To file" (lambda (a s v b) (org-gfm-export-to-markdown a s v))) + (?o "To file and open" + (lambda (a s v b) + (if a (org-gfm-export-to-markdown t s v) + (org-open-file (org-gfm-export-to-markdown nil s v))))))) + :translate-alist '((inner-template . org-gfm-inner-template) + (strike-through . org-gfm-strike-through) + (src-block . org-gfm-src-block))) + + + +;;; Transcode Functions + +;;;; Src Block + +(defun org-gfm-src-block (src-block contents info) + "Transcode SRC-BLOCK element into Github Flavored Markdown +format. CONTENTS is nil. INFO is a plist used as a communication +channel." + (let* ((lang (org-element-property :language src-block)) + (code (org-export-format-code-default src-block info)) + (prefix (concat "```" lang "\n")) + (suffix "```")) + (concat prefix code suffix))) + + +;;;; Strike-Through + +(defun org-gfm-strike-through (strike-through contents info) + "Transcode STRIKE-THROUGH from Org to Markdown (GFM). +CONTENTS is the text with strike-through markup. INFO is a plist +holding contextual information." + (format "~~%s~~" contents)) + +;;;; Table of contents + +(defun org-gfm-format-toc (headline) + "Return an appropriate table of contents entry for HEADLINE. INFO is a +plist used as a communication channel." + (let* ((title (org-export-data + (org-export-get-alt-title headline info) info)) + (level (1- (org-element-property :level headline))) + (indent (concat (make-string (* level 2) ? ))) + (anchor (or (org-element-property :custom_id headline) + (concat "sec-" (mapconcat 'number-to-string + (org-export-get-headline-number + headline info) "-"))))) + (concat indent "- [" title "]" "(#" anchor ")"))) + + + + +;;;; Template + +(defun org-gfm-inner-template (contents info) + "Return body of document after converting it to Markdown syntax. +CONTENTS is the transcoded contents string. INFO is a plist +holding export options." + (let* ((depth (plist-get info :with-toc)) + (headlines (and depth (org-export-collect-headlines info depth))) + (toc-string (or (mapconcat 'org-gfm-format-toc headlines "\n") "")) + (toc-tail (if headlines "\n\n" ""))) + (concat toc-string toc-tail contents))) + + + +;;; Interactive function + +;;;###autoload +(defun org-gfm-export-as-markdown (&optional async subtreep visible-only) + "Export current buffer to a Github Flavored Markdown buffer. + +If narrowing is active in the current buffer, only export its +narrowed part. + +If a region is active, export that region. + +A non-nil optional argument ASYNC means the process should happen +asynchronously. The resulting buffer should be accessible +through the `org-export-stack' interface. + +When optional argument SUBTREEP is non-nil, export the sub-tree +at point, extracting information from the headline properties +first. + +When optional argument VISIBLE-ONLY is non-nil, don't export +contents of hidden elements. + +Export is done in a buffer named \"*Org GFM Export*\", which will +be displayed when `org-export-show-temporary-export-buffer' is +non-nil." + (interactive) + (org-export-to-buffer 'gfm "*Org GFM Export*" + async subtreep visible-only nil nil (lambda () (text-mode)))) + + +;;;###autoload +(defun org-gfm-convert-region-to-md () + "Assume the current region has org-mode syntax, and convert it +to Github Flavored Markdown. This can be used in any buffer. +For example, you can write an itemized list in org-mode syntax in +a Markdown buffer and use this command to convert it." + (interactive) + (org-export-replace-region-by 'gfm)) + + +;;;###autoload +(defun org-gfm-export-to-markdown (&optional async subtreep visible-only) + "Export current buffer to a Github Flavored Markdown file. + +If narrowing is active in the current buffer, only export its +narrowed part. + +If a region is active, export that region. + +A non-nil optional argument ASYNC means the process should happen +asynchronously. The resulting file should be accessible through +the `org-export-stack' interface. + +When optional argument SUBTREEP is non-nil, export the sub-tree +at point, extracting information from the headline properties +first. + +When optional argument VISIBLE-ONLY is non-nil, don't export +contents of hidden elements. + +Return output file's name." + (interactive) + (let ((outfile (org-export-output-file-name ".md" subtreep))) + (org-export-to-file 'gfm outfile async subtreep visible-only))) + +(provide 'ox-gfm) + +;; Local variables: +;; generated-autoload-file: "org-loaddefs.el" +;; End: + +;;; ox-gfm.el ends here diff --git a/layers/+emacs/org/packages.el b/layers/+emacs/org/packages.el new file mode 100644 index 0000000..4963f4a --- /dev/null +++ b/layers/+emacs/org/packages.el @@ -0,0 +1,542 @@ +;;; packages.el --- Org Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq org-packages + '( + company + company-emoji + emoji-cheat-sheet-plus + (evil-org :location local) + evil-surround + gnuplot + htmlize + mu4e + ;; ob, org and org-agenda are installed by `org-plus-contrib' + (ob :location built-in) + (org :location built-in) + (org-agenda :location built-in) + org-download + ;; org-mime is installed by `org-plus-contrib' + (org-mime :location built-in) + org-pomodoro + org-present + (org-projectile :toggle (configuration-layer/package-usedp 'projectile)) + (ox-twbs :toggle org-enable-bootstrap-support) + ;; use a for of ox-gfm to fix index generation + (ox-gfm :location (recipe :fetcher github :repo "syl20bnr/ox-gfm") + :toggle org-enable-github-support) + (ox-reveal :toggle org-enable-reveal-js-support) + persp-mode + )) + +(defun org/post-init-company () + (spacemacs|add-company-hook org-mode) + (push 'company-capf company-backends-org-mode)) + +(defun org/post-init-company-emoji () + (push 'company-emoji company-backends-org-mode)) + +(defun org/post-init-emoji-cheat-sheet-plus () + (add-hook 'org-mode-hook 'spacemacs/delay-emoji-cheat-sheet-hook)) + +(defun org/init-evil-org () + (use-package evil-org + :commands (evil-org-mode evil-org-recompute-clocks) + :init (add-hook 'org-mode-hook 'evil-org-mode) + :config + (progn + (evil-define-key 'normal evil-org-mode-map + "O" 'evil-open-above) + (spacemacs/set-leader-keys-for-major-mode 'org-mode + "C" 'evil-org-recompute-clocks) + (spacemacs|diminish evil-org-mode " ⓔ" " e")))) + +(defun org/post-init-evil-surround () + (defun spacemacs/add-org-surrounds () + (push '(?: . spacemacs//surround-drawer) evil-surround-pairs-alist) + (push '(?# . spacemacs//surround-code) evil-surround-pairs-alist)) + (add-hook 'org-mode-hook 'spacemacs/add-org-surrounds)) + +(defun org/init-gnuplot () + (use-package gnuplot + :defer t + :init (spacemacs/set-leader-keys-for-major-mode 'org-mode + "tp" 'org-plot/gnuplot))) + +(defun org/init-htmlize () + (use-package htmlize + :defer t)) + +(defun org/pre-init-mu4e () + ;; Load org-mu4e when mu4e is actually loaded + (spacemacs|use-package-add-hook mu4e + :post-config (require 'org-mu4e nil 'noerror))) + +(defun org/init-ob () + (use-package ob + :defer t + :init + (progn + (defun spacemacs//org-babel-do-load-languages () + "Load all the languages declared in `org-babel-load-languages'." + (org-babel-do-load-languages 'org-babel-load-languages + org-babel-load-languages)) + (add-hook 'org-mode-hook 'spacemacs//org-babel-do-load-languages) + ;; Fix redisplay of inline images after a code block evaluation. + (add-hook 'org-babel-after-execute-hook 'spacemacs/ob-fix-inline-images)))) + +(defun org/init-org () + (use-package org + :defer t + :commands (orgtbl-mode) + :init + (progn + (setq org-clock-persist-file (concat spacemacs-cache-directory + "org-clock-save.el") + org-id-locations-file (concat spacemacs-cache-directory + ".org-id-locations") + org-publish-timestamp-directory (concat spacemacs-cache-directory + ".org-timestamps/") + org-log-done t + org-startup-with-inline-images t + org-image-actual-width nil + org-src-fontify-natively t + ;; this is consistent with the value of + ;; `helm-org-headings-max-depth'. + org-imenu-depth 8) + + (with-eval-after-load 'org-indent + (spacemacs|hide-lighter org-indent-mode)) + (let ((dir (configuration-layer/get-layer-local-dir 'org))) + (setq org-export-async-init-file (concat dir "org-async-init.el"))) + (defmacro spacemacs|org-emphasize (fname char) + "Make function for setting the emphasis in org mode" + `(defun ,fname () (interactive) + (org-emphasize ,char))) + + ;; Follow the confirm and abort conventions + (with-eval-after-load 'org-capture + (spacemacs/set-leader-keys-for-minor-mode 'org-capture-mode + dotspacemacs-major-mode-leader-key 'org-capture-finalize + "c" 'org-capture-finalize + "k" 'org-capture-kill + "a" 'org-capture-kill + "r" 'org-capture-refile)) + + (with-eval-after-load 'org-src + (spacemacs/set-leader-keys-for-minor-mode 'org-src-mode + "'" 'org-edit-src-exit + "c" 'org-edit-src-exit + "a" 'org-edit-src-abort + "k" 'org-edit-src-abort)) + + (let ((dir (configuration-layer/get-layer-local-dir 'org))) + (setq org-export-async-init-file (concat dir "org-async-init.el"))) + (defmacro spacemacs|org-emphasize (fname char) + "Make function for setting the emphasis in org mode" + `(defun ,fname () (interactive) + (org-emphasize ,char))) + + ;; Insert key for org-mode and markdown a la C-h k + ;; from SE endless http://emacs.stackexchange.com/questions/2206/i-want-to-have-the-kbd-tags-for-my-blog-written-in-org-mode/2208#2208 + (defun spacemacs/insert-keybinding-org (key) + "Ask for a key then insert its description. +Will work on both org-mode and any mode that accepts plain html." + (interactive "kType key sequence: ") + (let* ((tag "@@html:@@ %s @@html:@@")) + (if (null (equal key "\r")) + (insert + (format tag (help-key-description key nil))) + (insert (format tag "")) + (forward-char -8)))) + + (dolist (prefix '(("mx" . "text") + ("mh" . "headings") + ("mi" . "insert") + ("mS" . "subtrees") + ("mt" . "tables") + ("mtd" . "delete") + ("mti" . "insert") + ("mtt" . "toggle"))) + (spacemacs/declare-prefix-for-mode 'org-mode (car prefix) (cdr prefix))) + (spacemacs/set-leader-keys-for-major-mode 'org-mode + "'" 'org-edit-special + "c" 'org-capture + "d" 'org-deadline + "D" 'org-insert-drawer + "e" 'org-export-dispatch + "f" 'org-set-effort + "P" 'org-set-property + ":" 'org-set-tags + + "a" 'org-agenda + "b" 'org-tree-to-indirect-buffer + "A" 'org-archive-subtree + "l" 'org-open-at-point + "T" 'org-show-todo-tree + + "." 'org-time-stamp + "!" 'org-time-stamp-inactive + + ;; headings + "hi" 'org-insert-heading-after-current + "hI" 'org-insert-heading + "hs" 'org-insert-subheading + + ;; More cycling options (timestamps, headlines, items, properties) + "L" 'org-shiftright + "H" 'org-shiftleft + "J" 'org-shiftdown + "K" 'org-shiftup + + ;; Change between TODO sets + "C-S-l" 'org-shiftcontrolright + "C-S-h" 'org-shiftcontrolleft + "C-S-j" 'org-shiftcontroldown + "C-S-k" 'org-shiftcontrolup + + ;; Subtree editing + "Sl" 'org-demote-subtree + "Sh" 'org-promote-subtree + "Sj" 'org-move-subtree-down + "Sk" 'org-move-subtree-up + + ;; tables + "ta" 'org-table-align + "tb" 'org-table-blank-field + "tc" 'org-table-convert + "tdc" 'org-table-delete-column + "tdr" 'org-table-kill-row + "te" 'org-table-eval-formula + "tE" 'org-table-export + "th" 'org-table-previous-field + "tH" 'org-table-move-column-left + "tic" 'org-table-insert-column + "tih" 'org-table-insert-hline + "tiH" 'org-table-hline-and-move + "tir" 'org-table-insert-row + "tI" 'org-table-import + "tj" 'org-table-next-row + "tJ" 'org-table-move-row-down + "tK" 'org-table-move-row-up + "tl" 'org-table-next-field + "tL" 'org-table-move-column-right + "tn" 'org-table-create + "tN" 'org-table-create-with-table.el + "tr" 'org-table-recalculate + "ts" 'org-table-sort-lines + "ttf" 'org-table-toggle-formula-debugger + "tto" 'org-table-toggle-coordinate-overlays + "tw" 'org-table-wrap-region + + ;; Multi-purpose keys + (or dotspacemacs-major-mode-leader-key ",") 'org-ctrl-c-ctrl-c + "*" 'org-ctrl-c-star + "RET" 'org-ctrl-c-ret + "-" 'org-ctrl-c-minus + "^" 'org-sort + "/" 'org-sparse-tree + + "I" 'org-clock-in + "n" 'org-narrow-to-subtree + "N" 'widen + "O" 'org-clock-out + "q" 'org-clock-cancel + "R" 'org-refile + "s" 'org-schedule + + ;; insertion of common elements + "il" 'org-insert-link + "if" 'org-footnote-new + "ik" 'spacemacs/insert-keybinding-org + + ;; images and other link types have no commands in org mode-line + ;; could be inserted using yasnippet? + ;; region manipulation + "xb" (spacemacs|org-emphasize spacemacs/org-bold ?*) + "xc" (spacemacs|org-emphasize spacemacs/org-code ?~) + "xi" (spacemacs|org-emphasize spacemacs/org-italic ?/) + "xr" (spacemacs|org-emphasize spacemacs/org-clear ? ) + "xs" (spacemacs|org-emphasize spacemacs/org-strike-through ?+) + "xu" (spacemacs|org-emphasize spacemacs/org-underline ?_) + "xv" (spacemacs|org-emphasize spacemacs/org-verbose ?=)) + + ;; Add global evil-leader mappings. Used to access org-agenda + ;; functionalities – and a few others commands – from any other mode. + (spacemacs/declare-prefix "ao" "org") + (spacemacs/set-leader-keys + ;; org-agenda + "ao#" 'org-agenda-list-stuck-projects + "ao/" 'org-occur-in-agenda-files + "aoa" 'org-agenda-list + "aoe" 'org-store-agenda-views + "aom" 'org-tags-view + "aoo" 'org-agenda + "aos" 'org-search-view + "aot" 'org-todo-list + ;; other + "aoO" 'org-clock-out + "aoc" 'org-capture + "aol" 'org-store-link) + + (define-key global-map "\C-cl" 'org-store-link) + (define-key global-map "\C-ca" 'org-agenda) + (define-key global-map "\C-cc" 'org-capture)) + :config + (progn + (setq org-default-notes-file "notes.org") + + ;; We add this key mapping because an Emacs user can change + ;; `dotspacemacs-major-mode-emacs-leader-key' to `C-c' and the key binding + ;; C-c ' is shadowed by `spacemacs/default-pop-shell', effectively making + ;; the Emacs user unable to exit src block editing. + (define-key org-src-mode-map + (kbd (concat dotspacemacs-major-mode-emacs-leader-key " '")) + 'org-edit-src-exit) + + (spacemacs/set-leader-keys "Cc" 'org-capture) + + ;; Evilify the calendar tool on C-c . + (unless (eq 'emacs dotspacemacs-editing-style) + (define-key org-read-date-minibuffer-local-map (kbd "M-h") + (lambda () (interactive) + (org-eval-in-calendar '(calendar-backward-day 1)))) + (define-key org-read-date-minibuffer-local-map (kbd "M-l") + (lambda () (interactive) + (org-eval-in-calendar '(calendar-forward-day 1)))) + (define-key org-read-date-minibuffer-local-map (kbd "M-k") + (lambda () (interactive) + (org-eval-in-calendar '(calendar-backward-week 1)))) + (define-key org-read-date-minibuffer-local-map (kbd "M-j") + (lambda () (interactive) + (org-eval-in-calendar '(calendar-forward-week 1)))) + (define-key org-read-date-minibuffer-local-map (kbd "M-H") + (lambda () (interactive) + (org-eval-in-calendar '(calendar-backward-month 1)))) + (define-key org-read-date-minibuffer-local-map (kbd "M-L") + (lambda () (interactive) + (org-eval-in-calendar '(calendar-forward-month 1)))) + (define-key org-read-date-minibuffer-local-map (kbd "M-K") + (lambda () (interactive) + (org-eval-in-calendar '(calendar-backward-year 1)))) + (define-key org-read-date-minibuffer-local-map (kbd "M-J") + (lambda () (interactive) + (org-eval-in-calendar '(calendar-forward-year 1)))))))) + +(defun org/init-org-agenda () + (use-package org-agenda + :defer t + :init + (progn + (setq org-agenda-restore-windows-after-quit t) + (spacemacs/set-leader-keys-for-major-mode 'org-agenda-mode + ":" 'org-agenda-set-tags + "a" 'org-agenda + "d" 'org-agenda-deadline + "f" 'org-agenda-set-effort + "I" 'org-agenda-clock-in + "O" 'org-agenda-clock-out + "P" 'org-agenda-set-property + "q" 'org-agenda-refile + "Q" 'org-agenda-clock-cancel + "s" 'org-agenda-schedule) + (spacemacs|define-transient-state org-agenda + :title "Org-agenda transient state" + :on-enter (setq which-key-inhibit t) + :on-exit (setq which-key-inhibit nil) + :foreign-keys run + :doc + " +Headline^^ Visit entry^^ Filter^^ Date^^ Toggle mode^^ View^^ Clock^^ Other^^ +--------^^--------- -----------^^------------ ------^^----------------- ----^^------------- -----------^^------ ----^^--------- -----^^------ -----^^----------- +[_ht_] set status [_SPC_] in other window [_ft_] by tag [_ds_] schedule [_tf_] follow [_vd_] day [_ci_] in [_gr_] reload +[_hk_] kill [_TAB_] & go to location [_fr_] refine by tag [_dd_] set deadline [_tl_] log [_vw_] week [_co_] out [_._] go to today +[_hr_] refile [_RET_] & del other windows [_fc_] by category [_dt_] timestamp [_ta_] archive [_vt_] fortnight [_ck_] cancel [_gd_] go to date +[_hA_] archive [_o_] link [_fh_] by top headline [_+_] do later [_tr_] clock report [_vm_] month [_cj_] jump ^^ +[_hT_] set tags ^^ [_fx_] by regexp [_-_] do earlier [_td_] diaries [_vy_] year ^^ ^^ +[_hp_] set priority ^^ [_fd_] delete all filters ^^ ^^ [_vn_] next span ^^ ^^ +^^ ^^ ^^ ^^ ^^ [_vp_] prev span ^^ ^^ +^^ ^^ ^^ ^^ ^^ [_vr_] reset ^^ ^^ +[_q_] quit +" + :bindings + ;; Entry + ("ht" org-agenda-todo) + ("hk" org-agenda-kill) + ("hr" org-agenda-refile) + ("hA" org-agenda-archive-default) + ("hT" org-agenda-set-tags) + ("hp" org-agenda-priority) + + ;; Visit entry + ("SPC" org-agenda-show-and-scroll-up) + ("" org-agenda-goto :exit t) + ("TAB" org-agenda-goto :exit t) + ("RET" org-agenda-switch-to :exit t) + ("o" link-hint-open-link :exit t) + + ;; Date + ("ds" org-agenda-schedule) + ("dd" org-agenda-deadline) + ("dt" org-agenda-date-prompt) + ("+" org-agenda-do-date-later) + ("-" org-agenda-do-date-earlier) + + ;; View + ("vd" org-agenda-day-view) + ("vw" org-agenda-week-view) + ("vt" org-agenda-fortnight-view) + ("vm" org-agenda-month-view) + ("vy" org-agenda-year-view) + ("vn" org-agenda-later) + ("vp" org-agenda-earlier) + ("vr" org-agenda-reset-view) + + ;; Toggle mode + ("tf" org-agenda-follow-mode) + ("tl" org-agenda-log-mode) + ("ta" org-agenda-archives-mode) + ("tr" org-agenda-clockreport-mode) + ("td" org-agenda-toggle-diary) + + ;; Filter + ("ft" org-agenda-filter-by-tag) + ("fr" org-agenda-filter-by-tag-refine) + ("fc" org-agenda-filter-by-category) + ("fh" org-agenda-filter-by-top-headline) + ("fx" org-agenda-filter-by-regexp) + ("fd" org-agenda-filter-remove-all) + + ;; Clock + ("ci" org-agenda-clock-in :exit t) + ("co" org-agenda-clock-out) + ("ck" org-agenda-clock-cancel) + ("cj" org-agenda-clock-goto :exit t) + + ;; Other + ("q" nil :exit t) + ("gr" org-agenda-redo) + ("." org-agenda-goto-today) + ("gd" org-agenda-goto-date))) + :config + (evilified-state-evilify-map org-agenda-mode-map + :mode org-agenda-mode + :bindings + "j" 'org-agenda-next-line + "k" 'org-agenda-previous-line + (kbd "M-j") 'org-agenda-next-item + (kbd "M-k") 'org-agenda-previous-item + (kbd "M-h") 'org-agenda-earlier + (kbd "M-l") 'org-agenda-later + (kbd "gd") 'org-agenda-toggle-time-grid + (kbd "gr") 'org-agenda-redo + (kbd "M-RET") 'org-agenda-show-and-scroll-up + (kbd "M-SPC") 'spacemacs/org-agenda-transient-state/body + (kbd "s-M-SPC") 'spacemacs/org-agenda-transient-state/body))) + +(defun org/init-org-download () + (use-package org-download + :commands (org-download-enable + org-download-yank + org-download-screenshot) + :init + (progn + (add-hook 'org-mode-hook 'org-download-enable) + (spacemacs/set-leader-keys-for-major-mode 'org-mode + "iy" 'org-download-yank + "is" 'org-download-screenshot)))) + +(defun org/init-org-mime () + (use-package org-mime + :defer t + :commands (org-mime-htmlize org-mime-org-buffer-htmlize) + :init + (progn + (spacemacs/set-leader-keys-for-major-mode 'message-mode + "M" 'org-mime-htmlize) + (spacemacs/set-leader-keys-for-major-mode 'org-mode + "m" 'org-mime-org-buffer-htmlize)))) + +(defun org/init-org-pomodoro () + (use-package org-pomodoro + :defer t + :init + (progn + (when (spacemacs/system-is-mac) + (setq org-pomodoro-audio-player "/usr/bin/afplay")) + (spacemacs/set-leader-keys-for-major-mode 'org-mode + "p" 'org-pomodoro) + (spacemacs/set-leader-keys-for-major-mode 'org-agenda-mode + "p" 'org-pomodoro)))) + +(defun org/init-org-present () + (use-package org-present + :defer t + :init + (progn + (evilified-state-evilify nil org-present-mode-keymap + "h" 'org-present-prev + "l" 'org-present-next + "q" 'org-present-quit) + (defun spacemacs//org-present-start () + "Initiate `org-present' mode" + (org-present-big) + (org-display-inline-images) + (org-present-hide-cursor) + (org-present-read-only) + (evil-evilified-state)) + (defun spacemacs//org-present-end () + "Terminate `org-present' mode" + (org-present-small) + (org-remove-inline-images) + (org-present-show-cursor) + (org-present-read-write) + (evil-normal-state)) + (add-hook 'org-present-mode-hook 'spacemacs//org-present-start) + (add-hook 'org-present-mode-quit-hook 'spacemacs//org-present-end)))) + +(defun org/init-org-projectile () + (use-package org-projectile + :commands (org-projectile:location-for-project) + :init + (progn + (spacemacs/set-leader-keys + "aop" 'org-projectile/capture + "po" 'org-projectile/goto-todos) + (with-eval-after-load 'org-capture + (require 'org-projectile))) + :config + (if (file-name-absolute-p org-projectile-file) + (progn + (setq org-projectile:projects-file org-projectile-file) + (push (org-projectile:project-todo-entry + nil nil nil :empty-lines 1) + org-capture-templates)) + (org-projectile:per-repo) + (setq org-projectile:per-repo-filename org-projectile-file)))) + +(defun org/init-ox-twbs () + (spacemacs|use-package-add-hook org :post-config (require 'ox-twbs))) + +(defun org/init-ox-gfm () + (spacemacs|use-package-add-hook org :post-config (require 'ox-gfm))) + +(defun org/init-ox-reveal () + (spacemacs|use-package-add-hook org :post-config (require 'ox-reveal))) + +(defun org/post-init-persp-mode () + (spacemacs|define-custom-layout "@Org" + :binding "o" + :body + (let ((agenda-files (org-agenda-files))) + (if agenda-files + (find-file (first agenda-files)) + (user-error "Error: No agenda files configured, nothing to display."))))) diff --git a/layers/+emacs/semantic/README.org b/layers/+emacs/semantic/README.org new file mode 100644 index 0000000..c14b9fb --- /dev/null +++ b/layers/+emacs/semantic/README.org @@ -0,0 +1,45 @@ +#+TITLE: Semantic layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#install][Install]] + - [[#key-bindings][Key Bindings]] + +* Description + +CEDET is a *C*ollection of *E*macs *D*evelopment *E*nvironment *T*ools written +with the end goal of creating an advanced development environment in Emacs. +CEDET includes common features such as intelligent completion, source code +navigation, project management, code generation with templates. CEDET also +provides a framework for working with programming languages; support for new +programming languages can be added and use CEDET to provide IDE-like features. +This framework is called Semantic. + +Semantic is a package that provides a framework for writing parsers. Parsing is +a process of analyzing source code based on programming language syntax. The +packages relies on Semantic for analyzing source code and uses its results to +perform smart code refactoring that based on code structure of the analyzed +language, instead of plain text structure. Semantic is the core of CEDET. + +* Features + +- Display function or variable definition at the bottom. +- Display current function cursor is in at the top. See + [[https://github.com/tuhdo/semantic-stickyfunc-enhance][this page]] for demos in some programming languages. +- Support common C/C++ refactoring with [[https://github.com/tuhdo/semantic-refactor][semantic-refactor]]. See + [[https://github.com/tuhdo/semantic-refactor/blob/master/srefactor-demos/demos.org][this page]] for demonstration of refactoring features. +- Support Lisp source code formatting with [[https://github.com/tuhdo/semantic-refactor][semantic-refactor]].. See + [[https://github.com/tuhdo/semantic-refactor/blob/master/srefactor-demos/demos-elisp.org][this page]] for demonstration of Lisp formatting + features. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =semantic= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key Bindings + +| Key Binding | Description | +|-------------+-------------------------------------| +| ~SPC m r~ | srefactor: refactor thing at point. | diff --git a/layers/+emacs/semantic/config.el b/layers/+emacs/semantic/config.el new file mode 100644 index 0000000..f82430f --- /dev/null +++ b/layers/+emacs/semantic/config.el @@ -0,0 +1,17 @@ +;;; config.el --- semantic Layer configuration +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sebastian Wiesner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq semantic-packages + '( + (semantic :location built-in) + srefactor + stickyfunc-enhance + )) + +(defun semantic/init-semantic () + (use-package semantic + :defer t + :config + (progn + (add-to-list 'semantic-default-submodes + 'global-semantic-stickyfunc-mode) + (add-to-list 'semantic-default-submodes + 'global-semantic-idle-summary-mode)))) + +(defun semantic/init-srefactor () + (use-package srefactor + :defer t + :init + (progn + (defun spacemacs/lazy-load-srefactor () + "Lazy load the package." + (require 'srefactor) + ;; currently, evil-mode overrides key mapping of srefactor menu + ;; must expplicity enable evil-emacs-state. This is ok since + ;; srefactor supports j,k,/ and ? commands when Evil is + ;; available + (add-hook 'srefactor-ui-menu-mode-hook 'evil-emacs-state))))) + +(defun semantic/init-stickyfunc-enhance () + (use-package stickyfunc-enhance + :defer t + :init + (defun spacemacs/lazy-load-stickyfunc-enhance () + "Lazy load the package." + (require 'stickyfunc-enhance)))) diff --git a/layers/+emacs/smex/README.org b/layers/+emacs/smex/README.org new file mode 100644 index 0000000..db48b11 --- /dev/null +++ b/layers/+emacs/smex/README.org @@ -0,0 +1,25 @@ +#+TITLE: Smex layer + +[[file:img/smex.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + +* Description +This layer replaces =helm-M-x= by [[https://github.com/nonsequitur/smex][smex]] which is built on top of =ido=. +=ido= can perform flex matching with the [[https://github.com/lewang/flx][flx-ido]] mode which is already +activated in the Spacemacs layer. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =smex= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key bindings + +| Key Binding | Description | +|-------------+--------------------------------------------| +| ~SPC :~ | all Emacs commands (interactive functions) | +| ~SPC m :~ | current major mode commands | diff --git a/layers/+emacs/smex/funcs.el b/layers/+emacs/smex/funcs.el new file mode 100644 index 0000000..c46a801 --- /dev/null +++ b/layers/+emacs/smex/funcs.el @@ -0,0 +1,22 @@ +;;; funcs.el --- Smex Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spacemacs/smex () + "Execute smex with a better prompt." + (interactive) + (let ((smex-prompt-string "Emacs commands: ")) + (smex))) + +(defun spacemacs/smex-major-mode-commands () + "Reexecute smex with major mode commands only." + (interactive) + (let ((smex-prompt-string (format "%s commands: " major-mode))) + (smex-major-mode-commands))) diff --git a/layers/+emacs/smex/img/smex.png b/layers/+emacs/smex/img/smex.png new file mode 100644 index 0000000..6293dda Binary files /dev/null and b/layers/+emacs/smex/img/smex.png differ diff --git a/layers/+emacs/smex/packages.el b/layers/+emacs/smex/packages.el new file mode 100644 index 0000000..5ccf28b --- /dev/null +++ b/layers/+emacs/smex/packages.el @@ -0,0 +1,28 @@ +;;; packages.el --- smex Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq smex-packages '(smex)) + +(defun smex/init-smex () + (use-package smex + :defer t + :init + (progn + (setq-default smex-history-length 32 + smex-save-file (concat spacemacs-cache-directory + ".smex-items")) + ;; define the key binding at the very end in order to allow the user + ;; to overwrite any key binding + (add-hook 'emacs-startup-hook + (lambda () (spacemacs/set-leader-keys + dotspacemacs-emacs-command-key 'spacemacs/smex))) + (spacemacs/set-leader-keys ":" 'spacemacs/smex-major-mode-commands) + (global-set-key (kbd "M-x") 'spacemacs/smex)))) diff --git a/layers/+emacs/typography/README.org b/layers/+emacs/typography/README.org new file mode 100644 index 0000000..8256e95 --- /dev/null +++ b/layers/+emacs/typography/README.org @@ -0,0 +1,61 @@ +#+TITLE: Typography layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + - [[#typo-mode][Typo Mode]] + - [[#tildify-mode][Tildify Mode]] + +* Description +This layer provides support for typographic text editing in Spacemacs. It +provides modes to automatically insert and cycle among typographic characters: + +- [[https://github.com/jorgenschaefer/typoel][Typo Mode]] automatically inserts and cycles among typographic Unicode + characters on some keys. +- Tildify Mode automatically inserts non-breaking spaces where required. (Only + available on Emacs 25). + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =typography= to the existing =dotspacemacs-configuration-layers= list in this +file. + +Typographic editing however is disabled by default. To enable it by default set +=typography-enable-typographic-editing= to =t=: + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers + '(typography :variables typography-enable-typographic-editing t)) +#+END_SRC + +This setting enables automatic insertion of non-breaking spaces where required +and automatic insertion and cycling among of typographic quotes and dashes. + +* Key bindings + +| Key Bindings | Description | +|--------------+------------------------------------------------------------------| +| ~SPC t T~ | Toggle Typo Mode (automatic insertion of typographic characters) | +| ~SPC t ~~ | Toggle Tildify Mode (automatic insertion of non-breaking spaces) | +| ~SPC x ~~ | Insert non-breaking spaces in the current region | + +The following keybindings are available in insert state. + +** Typo Mode + +| Key Bindings | Description | +|--------------+------------------------------------------| +| ~​"​~ | Cycle among quotation marks | +| ~`~ | Cycle among left single quotation marks | +| ~​'​~ | Cycle among right single quotation marks | +| ~-~ | Cycle among dashes | +| ~.~ | Cycle among ellipsis | +| ~<~ | Cycle among left angle brackets | +| ~>~ | Cycle among right angle brackets | + +** Tildify Mode + +| Key bindings | Description | +|--------------+-----------------------------------------| +| ~SPC~ | Insert non-breaking space when required | diff --git a/layers/+emacs/typography/config.el b/layers/+emacs/typography/config.el new file mode 100644 index 0000000..2e57daf --- /dev/null +++ b/layers/+emacs/typography/config.el @@ -0,0 +1,13 @@ +;;; config.el --- typography Layer configuration +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sebastian Wiesner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq typography-packages + '( + (tildify :toggle (version<= "25" emacs-version)) + typo + )) + +(defun typography/init-typo () + (use-package typo + :defer t + :init + (progn + (when typography-enable-typographic-editing + (add-hook 'text-mode-hook 'typo-mode)) + + (spacemacs|add-toggle typographic-substitutions + :mode typo-mode + :documentation "Enable typographic substitutions" + :evil-leader "tT") + (spacemacs|diminish typo-mode " Ⓣ" " T")) + :config (setq-default typo-language "English"))) + +(defun typography/init-tildify () + (use-package tildify + :defer t + :init + (progn + (when typography-enable-typographic-editing + (add-hook 'text-mode-hook 'tildify-mode)) + + (spacemacs/set-leader-keys + "x~" 'tildify-region) + + ;; Use the symbolic non-breaking space for LaTeX + (defun typography/tildify-latex-space () + "Set tildify space for LaTeX" + (setq-local tildify-space-string "~")) + (add-hook 'LaTeX-mode-hook 'typography/tildify-latex-space) + + (spacemacs|add-toggle tildify-space + :mode tildify-mode + :documentation "Enable electric non-breaking space" + :evil-leader "t~") + (spacemacs|diminish tildify-mode " ~" " ~")))) diff --git a/layers/+email/gnus/README.org b/layers/+email/gnus/README.org new file mode 100644 index 0000000..30f798f --- /dev/null +++ b/layers/+email/gnus/README.org @@ -0,0 +1,119 @@ +#+TITLE: Gnus layer + +[[file:img/gnus.gif]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#install][Install]] + - [[#basic-concepts][Basic Concepts]] + - [[#adding-news-sources][Adding news sources]] + - [[#configuring-gmail][Configuring gmail]] + - [[#org-mime-in-org-layer][Org MIME in Org layer]] + - [[#keybindings][Keybindings]] + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =gnus= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Basic Concepts + +Gnus is a news reading application. The Gnus terminology can be confusing for +new users so the basics are listed here: + +- Group :: A Newsgroup but can also be a RSS Feed or a mail directory +- Topic :: Newsgroups can be assigned to topics which will be used to structure + the Group Buffer if Topic Mode is enabled(default). + +* Adding news sources + +Adding news sources can be done in your =.spacemacs= file by adding the +following: + +#+BEGIN_SRC emacs-lisp + ;; Get email, and store in nnml + (setq gnus-secondary-select-methods + '( + (nntp "gmane" + (nntp-address "news.gmane.org")) + (nntp "news.eternal-september.org") + (nntp "nntp.aioe.org") + (nntp "news.gwene.org") + )) +#+END_SRC + +For adding RSS Feeds please see the [[Keybindings][keybindings section]]. + +* Configuring gmail + +To configure Gnus with gmail support you can add the following to your +=.spacemacs= file. + +#+BEGIN_SRC emacs-lisp +;; Get email, and store in nnml +(setq gnus-secondary-select-methods +'( + (nnimap "gmail" + (nnimap-address + "imap.gmail.com") + (nnimap-server-port 993) + (nnimap-stream ssl)) + )) + +;; Send email via Gmail: +(setq message-send-mail-function 'smtpmail-send-it + smtpmail-default-smtp-server "smtp.gmail.com") + +;; Archive outgoing email in Sent folder on imap.gmail.com: +(setq gnus-message-archive-method '(nnimap "imap.gmail.com") + gnus-message-archive-group "[Gmail]/Sent Mail") + +;; set return email address based on incoming email address +(setq gnus-posting-styles + '(((header "to" "address@outlook.com") + (address "address@outlook.com")) + ((header "to" "address@gmail.com") + (address "address@gmail.com")))) + +;; store email in ~/gmail directory +(setq nnml-directory "~/gmail") +(setq message-directory "~/gmail") +#+END_SRC + +Authentication for your gmail account is best stored in an =authinfo= or +=authinfo.pgp= file. It must be of the form: + +#+BEGIN_EXAMPLE +machine smtp.gmail.com login name@gmail.com password SUPER_SECRET_PASS +machine imap.gmail.com login name@gmail.com port 993 password SUPER_SECRET_PASS +#+END_EXAMPLE + +If you use two-step verification the password has to be an [[https://support.google.com/accounts/answer/185833?hl=en][application specific +password]]. + +* Org MIME in Org layer + +It is possible to send beautiful HTML emails using org mode. + +Pressing ~SPC m M~ in a message buffer will convert the current message +from org mode to html. An org mode buffer can be sent via html email by pressing +~SPC m m~ in any org mode buffer. + +* Keybindings + +Gnus has very modal default keybindings. +Please see the [[http://www.gnus.org/manual.html][manual]] for a complete list. + +Basic and Spacemacs specific keybindings can be found in the following table. + +| Key Binding | Gnus mode - Description | +|-------------+-----------------------------------------------------| +| ~SPC a g~ | Starts Gnus | +| ~m~ | New Message | +| ~G R~ | Group Buffer - Add RSS feed | +| ~^~ | Open Server Buffer. Browse Newsgroups. | +| ~T n~ | Group Buffer - new Topic | +| ~T m~ | Group Buffer - Move Group to Topic | +| ~K~ | Article Buffer - Previous article | +| ~J~ | Article Buffer - Next article | +| ~RET~ | Summary Buffer(RSS) - Open article Link in browser | +| ~TAB~ | Summary Buffer(RSS) - Open article and switch to it | diff --git a/layers/+email/gnus/img/gnus.gif b/layers/+email/gnus/img/gnus.gif new file mode 100644 index 0000000..701a8fd Binary files /dev/null and b/layers/+email/gnus/img/gnus.gif differ diff --git a/layers/+email/gnus/packages.el b/layers/+email/gnus/packages.el new file mode 100644 index 0000000..2cb717f --- /dev/null +++ b/layers/+email/gnus/packages.el @@ -0,0 +1,83 @@ +;;; packages.el --- gnus Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq gnus-packages '(gnus)) + +(defun gnus/init-gnus () + "Initialize my package" + (use-package gnus + :defer t + :commands gnus + :init + (spacemacs/set-leader-keys "ag" 'gnus) + :config + (progn + ;; No primary server + (setq gnus-select-method '(nnnil "")) + + ;; Use topics per default + (add-hook 'gnus-group-mode-hook 'gnus-topic-mode) + + (setq gnus-visible-headers + "^From:\\|^Reply-To\\|^Organization:\\|^To:\\|^Cc:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^Gnus") + + ;; Show the article headers in this order. + (setq gnus-sorted-header-list + '("^From:" "^Reply-To" "^Organization:" "^To:" "^Cc:" "^Newsgroups:" + "^Subject:" "^Date:" "^Gnus")) + + (setq-default + gnus-summary-line-format "%U%R%z %(%&user-date; %-15,15f %B (%c) %s%)\n" + gnus-user-date-format-alist '((t . "%Y-%m-%d %H:%M")) + gnus-group-line-format "%M%S%p%P%5y:%B %G\n";;"%B%(%g%)" + gnus-summary-thread-gathering-function 'gnus-gather-threads-by-references + gnus-thread-sort-functions '(gnus-thread-sort-by-most-recent-date) + gnus-ignored-newsgroups "^to\\.\\|^[0-9. ]+\\( \\|$\\)\\|^[\”]\”[#’()]" + gnus-sum-thread-tree-false-root "" + gnus-sum-thread-tree-indent " " + gnus-sum-thread-tree-leaf-with-other "├► " + gnus-sum-thread-tree-root "" + gnus-sum-thread-tree-single-leaf "╰► " + gnus-sum-thread-tree-vertical "│" + gnus-article-browse-delete-temp t + gnus-treat-strip-trailing-blank-lines 'last + gnus-keep-backlog 'nil + gnus-summary-display-arrow nil ; Don't show that annoying arrow: + gnus-mime-display-multipart-related-as-mixed t ; Show more MIME-stuff: + gnus-auto-select-first nil ; Don't get the first article automatically: + smiley-style 'medium + gnus-keep-backlog '0) + + (require 'browse-url) + (require 'nnrss) + (defun spacemacs/browse-nnrss-url (arg) + "Open RSS Article directy in the browser" + (interactive "p") + (let ((url (assq nnrss-url-field + (mail-header-extra + (gnus-data-header + (assq (gnus-summary-article-number) + gnus-newsgroup-data)))))) + (if url + (progn + (browse-url (cdr url)) + (gnus-summary-mark-as-read-forward 1)) + (gnus-summary-scroll-up arg)))) + (add-to-list 'nnmail-extra-headers nnrss-url-field) + + (evilified-state-evilify gnus-group-mode gnus-group-mode-map) + (evilified-state-evilify gnus-server-mode gnus-server-mode-map) + (evilified-state-evilify gnus-browse-mode gnus-browse-mode-map) + (evilified-state-evilify gnus-article-mode gnus-article-mode-map) + (evilified-state-evilify gnus-summary-mode gnus-summary-mode-map + (kbd "J") 'gnus-summary-next-article + (kbd "K") 'gnus-summary-prev-article + (kbd "") 'spacemacs/browse-nnrss-url)))) diff --git a/layers/+email/mu4e/README.org b/layers/+email/mu4e/README.org new file mode 100644 index 0000000..40965d7 --- /dev/null +++ b/layers/+email/mu4e/README.org @@ -0,0 +1,210 @@ +#+TITLE: Mu4e layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#install][Install]] + - [[#commands][Commands]] + - [[#global-bindings][Global bindings]] + - [[#headers-mode][Headers mode]] + - [[#view-mode][View mode]] + - [[#configuration][Configuration]] + - [[#maildirs-extension][Maildirs extension]] + - [[#multiple-accounts][Multiple Accounts]] + - [[#example-configuration][Example configuration]] + - [[#notifications][Notifications]] + - [[#os-notifications][OS notifications]] + - [[#mode-line-notifications][Mode-line notifications]] + - [[#see-also][See also]] + +* Install +In order to use this layer you must install mu and mu4e separately. Typically +mu4e will be bundled with mu (this is the case on many Linux distributions). + +If you're on OS X and install mu using Homebrew, you must specify the +location of your Emacs binary at install time using the EMACS environment +variable, as well as passing the --with-emacs option: + +#+begin_src shell +brew install mu --with-emacs +#+end_src + +If the installation directory of mu4e is not in Emacs’ load path, you can set +the layer variable =mu4e-installation-path=, for example: + +#+begin_src emacs-lisp + (setq-default dotspacemacs-configuration-layers + '((mu4e :variables + mu4e-installation-path "/usr/share/emacs/site-lisp"))) +#+end_src + +Then add this layer to your =~/.spacemacs=. You will need to add =mu4e= to the +existing =dotspacemacs-configuration-layers= list in this file. + +* Commands + +** Global bindings + +| Keybinding | Command | +|------------+------------| +| SPC a M | Start mu4e | + +** Headers mode + +| Keybinding | Command | +|------------+-------------------------------------------------------------| +| J | Go to next unread thread marking other mail read on the way | +| C-j | Next header | +| C-k | Previous header | + +** View mode + +| Keybinding | Command | +|------------+-------------------------------------------------------------| +| J | Go to next unread thread marking other mail read on the way | +| C-j | Next header | +| C-k | Previous header | + +* Configuration +Configuration varies too much to give precise instructions. What follows is one +example configuration. Refer to mu4e's manual for more detailed configuration +instructions. + +** Maildirs extension +The maildirs extension adds a list of all your maildirs to the main mu4e view +that by default shows the unread and total mail counts for all your mail under +your base mail directory. + +This extension is enabled by default, you can deactivate (and uninstall) it by +adding the package == to your dotfile variable =dotspacemacs-excluded-packages=. + +** Multiple Accounts +This layer includes support for multiple sending accounts. +If you have only one account you do not need to define this variable. +If you have multiple accounts, configure the =mu4e-account-alist= variable: + +#+BEGIN_SRC emacs-lisp + (setq mu4e-account-alist + '(("gmail" + ;; Under each account, set the account-specific variables you want. + (mu4e-sent-messages-behavior delete) + (mu4e-sent-folder "/gmail/[Gmail]/.Sent Mail") + (mu4e-drafts-folder "/gmail/[Gmail]/.Drafts") + (user-mail-address "billy@gmail.com") + (user-full-name "Billy")) + ("college" + (mu4e-sent-messages-behavior sent) + (mu4e-sent-folder "/college/Sent Items") + (mu4e-drafts-folder "/college/Drafts") + (user-mail-address "bb15@college.edu") + (user-full-name "Billy Bob 15")))) + (mu4e/mail-account-reset) +#+END_SRC + +The first account listed will be the default account, so variables like +=user-full-name=, which is used by other parts of Emacs, will have their value +reset for the default account after sending each email. + +Note that the mu4e layer expects =mu4e-account-alist= to be defined before the +layer is loaded. For example, you can set =mu4e-account-alist= to a dummy +setting in =dotspacemacs/layers=: + +#+BEGIN_SRC emacs-lisp +(mu4e :variables mu4e-account-alist t) +#+END_SRC + +and then actually set =mu4e-account-alist= later in =dotspacemacs/user-config=. + +Make sure you call =mu4e/mail-account-reset= afterward, which will initialize +the given account variables. + +If you have mu 0.9.16 or later, you can use mu4e's built-in contexts feature +instead (see [[http://www.djcbsoftware.nl/code/mu/mu4e/Contexts.html#Contexts][mu4e's manual]]). + +** Example configuration +#+BEGIN_SRC emacs-lisp + ;;; Set up some common mu4e variables + (setq mu4e-maildir "~/.mail" + mu4e-trash-folder "/Trash" + mu4e-refile-folder "/Archive" + mu4e-get-mail-command "mbsync -a" + mu4e-update-interval nil + mu4e-compose-signature-auto-include nil + mu4e-view-show-images t + mu4e-view-show-addresses t) + + ;;; Mail directory shortcuts + (setq mu4e-maildir-shortcuts + '(("/gmail/INBOX" . ?g) + ("/college/INBOX" . ?c))) + + ;;; Bookmarks + (setq mu4e-bookmarks + `(("flag:unread AND NOT flag:trashed" "Unread messages" ?u) + ("date:today..now" "Today's messages" ?t) + ("date:7d..now" "Last 7 days" ?w) + ("mime:image/*" "Messages with images" ?p) + (,(mapconcat 'identity + (mapcar + (lambda (maildir) + (concat "maildir:" (car maildir))) + mu4e-maildir-shortcuts) " OR ") + "All inboxes" ?i))) +#+END_SRC + +** Notifications +~mu4e-alert~ is an extension that provides desktop notifications and adds the +count of unread messages to the modeline. + +[[https://raw.githubusercontent.com/iqbalansari/mu4e-alert/master/screenshots/mu4e-alert-in-action.png]] + +For an extended documentation of the available customizations please refer to +[[https://github.com/iqbalansari/mu4e-alert#customizations][mu4e-alert's documentation]] + +*** OS notifications +To enable notifications about new messages, add the following line to your +~dotspacemacs/user-config~: + +#+BEGIN_SRC emacs-lisp + (setq mu4e-enable-notifications t) +#+END_SRC + +or use layer variables when you add the layer to +=dotspacemacs-configuration-layers=: + +#+BEGIN_SRC emacs-lisp + (mu4e :variables mu4e-enable-notifications t) +#+END_SRC + +By default, notifications will be shown in the ~*Messages*~ buffer. To enable +desktop notifications about new messages, add the following lines to +your ~dotspacemacs/user-config~, according to your operating system and the +installed libraries: + +#+BEGIN_SRC emacs-lisp + (with-eval-after-load 'mu4e-alert + ;; Enable Desktop notifications + (mu4e-alert-set-default-style 'notifications)) ; For linux + ;; (mu4e-alert-set-default-style 'libnotify)) ; Alternative for linux + ;; (mu4e-alert-set-default-style 'notifier)) ; For Mac OSX (through the + ; terminal notifier app) + ;; (mu4e-alert-set-default-style 'growl)) ; Alternative for Mac OSX +#+END_SRC + +*** Mode-line notifications +To enable mode-line display about new messages, add the following line to +your ~dotspacemacs/user-config~: + +#+BEGIN_SRC emacs-lisp + (setq mu4e-enable-mode-line t) +#+END_SRC + +or use layer variables when you add the layer to +=dotspacemacs-configuration-layers=: + +#+BEGIN_SRC emacs-lisp + (mu4e :variables mu4e-enable-mode-line t) +#+END_SRC + +* See also +Refer to the official mu and mu4e documentation for additional info. + +- [[http://www.djcbsoftware.nl/code/mu/mu4e/index.html][mu4e Manual]] diff --git a/layers/+email/mu4e/config.el b/layers/+email/mu4e/config.el new file mode 100644 index 0000000..89fc8ac --- /dev/null +++ b/layers/+email/mu4e/config.el @@ -0,0 +1,25 @@ +;;; config.el --- mu4e Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar mu4e-installation-path nil + "Installation path for mu4e.") + +(defvar mu4e-account-alist nil + "Account alist for custom multi-account compose.") + +(defvar mu4e-enable-notifications nil + "If non-nil, enable desktop notifications for unread emails.") + +(defvar mu4e-enable-mode-line nil + "If non-nil, enable display of unread emails in mode-line.") + +(when mu4e-installation-path + (push mu4e-installation-path load-path)) diff --git a/layers/+email/mu4e/funcs.el b/layers/+email/mu4e/funcs.el new file mode 100644 index 0000000..b70da44 --- /dev/null +++ b/layers/+email/mu4e/funcs.el @@ -0,0 +1,53 @@ +;;; funcs.el --- mu4e Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun mu4e//search-account-by-mail-address (mailto) + "Return the account given an email address in MAILTO." + (car (rassoc-if (lambda (x) + (equal (cadr (assoc 'user-mail-address x)) (car mailto))) + mu4e-account-alist))) + +(defun mu4e/set-account () + "Set the account for composing a message. +This function tries to guess the correct account from the email address first +then fallback to the maildir." + (let* ((account + (if mu4e-compose-parent-message + (let* ((mailtos + (mu4e-message-field mu4e-compose-parent-message :to)) + (mailto-account + (car (cl-remove-if-not + 'identity + (mapcar 'mu4e//search-account-by-mail-address + mailtos)))) + (maildir + (mu4e-message-field mu4e-compose-parent-message :maildir)) + (maildir-account + (progn + (string-match "/\\(.*?\\)/" maildir) + (match-string 1 maildir)))) + (or mailto-account maildir-account)) + (funcall mu4e-completing-read-function + "Compose with account:" + (mapcar (lambda (var) (car var)) mu4e-account-alist)))) + (account-vars (cdr (assoc account mu4e-account-alist)))) + (if account-vars + (mu4e//map-set account-vars) + (error "No email account found")))) + +(defun mu4e//map-set (vars) + "Setq an alist VARS of variables and values." + (mapc (lambda (var) (set (car var) (cadr var))) + vars)) + +(defun mu4e/mail-account-reset () + "Reset mail account info to first." + (mu4e//map-set (cdar mu4e-account-alist))) diff --git a/layers/+email/mu4e/packages.el b/layers/+email/mu4e/packages.el new file mode 100644 index 0000000..86b5f34 --- /dev/null +++ b/layers/+email/mu4e/packages.el @@ -0,0 +1,81 @@ +;;; packages.el --- mu4e Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq mu4e-packages + '( + (mu4e :location site) + mu4e-alert + mu4e-maildirs-extension + org + )) + +(defun mu4e/init-mu4e () + (use-package mu4e + :commands (mu4e mu4e-compose-new) + :init + (progn + (spacemacs/set-leader-keys "a M" 'mu4e) + (global-set-key (kbd "C-x m") 'mu4e-compose-new)) + :config + (progn + (evilified-state-evilify-map mu4e-main-mode-map + :mode mu4e-main-mode + :bindings + (kbd "j") 'mu4e~headers-jump-to-maildir) + + (evilified-state-evilify-map + mu4e-headers-mode-map + :mode mu4e-headers-mode + :bindings + (kbd "C-j") 'mu4e-headers-next + (kbd "C-k") 'mu4e-headers-prev + (kbd "J") (lambda () + (interactive) + (mu4e-headers-mark-thread nil '(read)))) + + (evilified-state-evilify-map + mu4e-view-mode-map + :mode mu4e-view-mode + :bindings + (kbd "C-j") 'mu4e-view-headers-next + (kbd "C-k") 'mu4e-view-headers-prev + (kbd "J") (lambda () + (interactive) + (mu4e-view-mark-thread '(read)))) + + (setq mu4e-completing-read-function 'completing-read) + + (add-to-list 'mu4e-view-actions + '("View in browser" . mu4e-action-view-in-browser) t) + + (when mu4e-account-alist + (add-hook 'mu4e-compose-pre-hook 'mu4e/set-account) + (add-hook 'message-sent-hook 'mu4e/mail-account-reset))))) + +(defun mu4e/init-mu4e-alert () + (use-package mu4e-alert + :defer t + :init (with-eval-after-load 'mu4e + (when mu4e-enable-notifications + (mu4e-alert-enable-notifications)) + (when mu4e-enable-mode-line + (mu4e-alert-enable-mode-line-display))))) + +(defun mu4e/init-mu4e-maildirs-extension () + (use-package mu4e-maildirs-extension + :defer t + :init (with-eval-after-load 'mu4e (mu4e-maildirs-extension-load)))) + +(defun mu4e/post-init-org () + ;; load org-mu4e when org is actually loaded + (with-eval-after-load 'org (require 'org-mu4e nil 'noerror))) + + diff --git a/layers/+frameworks/django/README.org b/layers/+frameworks/django/README.org new file mode 100644 index 0000000..0cbcdda --- /dev/null +++ b/layers/+frameworks/django/README.org @@ -0,0 +1,83 @@ +#+TITLE: Django layer + +[[file:img/django.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key Bindings]] + - [[#fabric][Fabric]] + - [[#files][Files]] + - [[#interactive][Interactive]] + - [[#server][Server]] + - [[#southsyncdb][South/Syncdb]] + - [[#test][Test]] + +* Description +This layer adds support for the Python [[https://www.djangoproject.com/][Django]] framework via [[https://github.com/davidmiller/pony-mode][pony-mode]]. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =django= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key Bindings +Django related key bindings uses [[https://github.com/davidmiller/pony-mode][pony-mode]] and are behind the prefix ~SPC m j~. + +Configuration options for pony-mode are documented at +[[http://www.deadpansincerity.com/docs/pony/configuration.html][deadpansincerity.com]] + +Manage Django with ~SPC m j m~. + +** Fabric + +| Key Binding | Description | +|---------------+----------------------------------| +| ~SPC m j a f~ | Run a fabric command | +| ~SPC m j a d~ | Deploy project with =fab deploy= | + +** Files + +| Key Binding | Description | +|---------------+---------------------------------------------------------------| +| ~SPC m j f s~ | Open the =settings.py= for this project | +| ~SPC m j f c~ | Interactively display a setting value in the minibuffer | +| ~SPC m j f t~ | Jump to template at point | +| ~SPC m j f r~ | Jump to the view file that the URL resolves to (experimental) | + +** Interactive + +| Key Binding | Description | +|---------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| ~SPC m j i d~ | Run interpreter for this project's default database as an inferior process | +| ~SPC m j i s~ | Open a Python shell with the current pony project's context loaded. If the project has the django_extras package installed, then use the excellent =shell_plus= command. Otherwise, fall back to =manage.py shell= | + +** Server + +| Key Binding | Description | +|---------------+-------------------------------------------------------------------| +| ~SPC m j r d~ | Stop the dev server | +| ~SPC m j r o~ | Open a tab at the dev server | +| ~SPC m j r r~ | Restart the dev server (works better with django_extras/werkzeug) | +| ~SPC m j r u~ | Start or open the dev server | +| ~SPC m j r t~ | Open a second server with a "throwaway" host/port | + +** South/Syncdb + +| Key Binding | Description | +|---------------+--------------------------------------------| +| ~SPC m j s c~ | Convert an existing app to south | +| ~SPC m j s h~ | Create migration for modification | +| ~SPC m j s i~ | Run the initial south migration for an app | +| ~SPC m j s m~ | Migrate an app | +| ~SPC m j s s~ | Run syncdb on the current project | + +** Test + +| Key Binding | Description | +|---------------+------------------------------------------------------------------| +| ~SPC m j t d~ | Move down the traceback one level | +| ~SPC m j t e~ | Go to the file and line of the last stack trace in a test buffer | +| ~SPC m j t o~ | Open the file in a traceback at the line specified | +| ~SPC m j t t~ | Run the test(s) given by =command= | +| ~SPC m j t u~ | Move up the traceback one level | diff --git a/layers/+frameworks/django/img/django.png b/layers/+frameworks/django/img/django.png new file mode 100644 index 0000000..a716073 Binary files /dev/null and b/layers/+frameworks/django/img/django.png differ diff --git a/layers/+frameworks/django/layers.el b/layers/+frameworks/django/layers.el new file mode 100644 index 0000000..93b6323 --- /dev/null +++ b/layers/+frameworks/django/layers.el @@ -0,0 +1,14 @@ +;;; layers.el --- Django Layer layers File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Andrea Moretti +;; URL: https://github.com/axyz +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Prerequisites + +(configuration-layer/declare-layer 'python) diff --git a/layers/+frameworks/django/packages.el b/layers/+frameworks/django/packages.el new file mode 100644 index 0000000..6ddb736 --- /dev/null +++ b/layers/+frameworks/django/packages.el @@ -0,0 +1,55 @@ +;;; packages.el --- Django Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq django-packages + '( + pony-mode + )) + +(defun django/init-pony-mode () + (use-package pony-mode + :defer t + :init (progn + (spacemacs/set-leader-keys-for-major-mode 'python-mode + ; d*j*ango f*a*bric + "jaf" 'pony-fabric + "jad" 'pony-fabric-deploy + ; d*j*ango *f*iles + "jfs" 'pony-goto-settings + "jfc" 'pony-setting + "jft" 'pony-goto-template + "jfr" 'pony-resolve + ; d*j*ango *i*nteractive + "jid" 'pony-db-shell + "jis" 'pony-shell + ; d*j*ango *m*anage + ; not including one-off management commands like "flush" and + ; "startapp" even though they're implemented in pony-mode, + ; because this is much handier + "jm" 'pony-manage + ; d*j*ango *r*unserver + "jrd" 'pony-stopserver + "jro" 'pony-browser + "jrr" 'pony-restart-server + "jru" 'pony-runserver + "jrt" 'pony-temp-server + ; d*j*ango *s*outh/*s*yncdb + "jsc" 'pony-south-convert + "jsh" 'pony-south-schemamigration + "jsi" 'pony-south-initial + "jsm" 'pony-south-migrate + "jss" 'pony-syncdb + ; d*j*ango *t*est + "jtd" 'pony-test-down + "jte" 'pony-test-goto-err + "jto" 'pony-test-open + "jtt" 'pony-test + "jtu" 'pony-test-up)))) diff --git a/layers/+frameworks/react/README.org b/layers/+frameworks/react/README.org new file mode 100644 index 0000000..f71c764 --- /dev/null +++ b/layers/+frameworks/react/README.org @@ -0,0 +1,136 @@ +#+TITLE: React layer + +[[file:img/react.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#install][Install]] + - [[#optional-configuration][Optional Configuration]] + - [[#key-bindings][Key Bindings]] + - [[#formatting-web-beautify][Formatting (web-beautify)]] + - [[#documentation-js-doc][Documentation (js-doc)]] + - [[#auto-complete-and-documentation-tern][Auto-complete and documentation (tern)]] + +* Description + +ES6 and JSX ready configuration layer for React +It will automatically recognize =.jsx= and =.react.js= files + +It will also recognize =/** @jsx React.DOM */= if it is the first line. + +** Features +- on-the-fly syntax checking +- proper syntax highlight and indentation with jsx +- ternjs turbocharged autocompletion as in js2-mode +- jsfmt automatic formatting +- js2-refactor +- js-doc + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =react= to the existing =dotspacemacs-configuration-layers= list in this +file. + +You will also need to install =tern= to use the auto-completion and +documentation features: +#+BEGIN_SRC sh + $ npm install -g tern +#+END_SRC + +To use the on-the-fly syntax checking, install =eslint= with babel and react support: +#+BEGIN_SRC sh + $ npm install -g eslint babel-eslint eslint-plugin-react +#+END_SRC + +If your project do not use a custom =.eslintrc= file I strongly advice you to try out this one by Airbnb: +[[https://github.com/airbnb/javascript/blob/master/linters/.eslintrc][.eslintrc]] + +In order to use automatic code formatting you need to install ~js-beautify~ with: +#+BEGIN_SRC sh + $ npm install -g js-beautify +#+END_SRC + +Be sure to have the ~e4x~ option set to ~true~ on your ~.jsbeautifyrc~ here it is my configuration as an example: +#+BEGIN_SRC json + { + "indent_size": 2, + "indent_char": " ", + "eol": "\n", + "indent_level": 0, + "indent_with_tabs": false, + "preserve_newlines": true, + "max_preserve_newlines": 2, + "jslint_happy": false, + "space_after_anon_function": false, + "brace_style": "collapse", + "keep_array_indentation": false, + "keep_function_indentation": false, + "space_before_conditional": true, + "break_chained_methods": true, + "eval_code": false, + "unescape_strings": false, + "wrap_line_length": 80, + "wrap_attributes": "auto", + "wrap_attributes_indent_size": 2, + "e4x": true, + "end_with_newline": true + } +#+END_SRC + +* Optional Configuration + +You may refer to the =web-mode= configuration for fine tuning the indenting behaviour. + +For example to have a consistent 2 spaces indenting both on =js= and =jsx= you may use these settings: + +#+begin_src emacs-lisp + (setq-default + ;; js2-mode + js2-basic-offset 2 + ;; web-mode + css-indent-offset 2 + web-mode-markup-indent-offset 2 + web-mode-css-indent-offset 2 + web-mode-code-indent-offset 2 + web-mode-attr-indent-offset 2) +#+end_src + +And if you want to have 2 space indent also for element's attributes, concatenations and contiguous function calls: +#+begin_src emacs-lisp + (with-eval-after-load 'web-mode + (add-to-list 'web-mode-indentation-params '("lineup-args" . nil)) + (add-to-list 'web-mode-indentation-params '("lineup-concats" . nil)) + (add-to-list 'web-mode-indentation-params '("lineup-calls" . nil))) +#+end_src + +* Key Bindings + +** Formatting (web-beautify) + +| Key Binding | Description | +|-------------+--------------------------------------------------------------| +| ~SPC m =~ | beautify code in js2-mode, json-mode, web-mode, and css-mode | + +*** Documentation (js-doc) + +You can check more [[https://github.com/mooz/js-doc/][here]] + +| Key Binding | Description | +|---------------+---------------------------------------| +| ~SPC m r d b~ | insert JSDoc comment for current file | +| ~SPC m r d f~ | insert JSDoc comment for function | +| ~SPC m r d t~ | insert tag to comment | +| ~SPC m r d h~ | show list of available jsdoc tags | + +** Auto-complete and documentation (tern) + +| Key Binding | Description | +|---------------+------------------------------------------------------------------------------------------| +| ~SPC m C-g~ | brings you back to last place you were when you pressed M-.. | +| ~SPC m g g~ | jump to the definition of the thing under the cursor | +| ~SPC m g G~ | jump to definition for the given name | +| ~SPC m h d~ | find docs of the thing under the cursor. Press again to open the associated URL (if any) | +| ~SPC m h t~ | find the type of the thing under the cursor | +| ~SPC m r r V~ | rename variable under the cursor using tern | + diff --git a/layers/+frameworks/react/config.el b/layers/+frameworks/react/config.el new file mode 100644 index 0000000..f510019 --- /dev/null +++ b/layers/+frameworks/react/config.el @@ -0,0 +1,16 @@ +;;; config.el --- react Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Andrea Moretti +;; URL: https://github.com/axyz +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(spacemacs|defvar-company-backends react-mode) + +(spacemacs|define-jump-handlers react-mode) diff --git a/layers/+frameworks/react/img/react.png b/layers/+frameworks/react/img/react.png new file mode 100644 index 0000000..15ea421 Binary files /dev/null and b/layers/+frameworks/react/img/react.png differ diff --git a/layers/+frameworks/react/layers.el b/layers/+frameworks/react/layers.el new file mode 100644 index 0000000..e071ef2 --- /dev/null +++ b/layers/+frameworks/react/layers.el @@ -0,0 +1,12 @@ +;;; layers.el --- react Layer layers File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Andrea Moretti +;; URL: https://github.com/axyz +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(configuration-layer/declare-layers '(html javascript)) diff --git a/layers/+frameworks/react/packages.el b/layers/+frameworks/react/packages.el new file mode 100644 index 0000000..4dd354e --- /dev/null +++ b/layers/+frameworks/react/packages.el @@ -0,0 +1,96 @@ +;;; packages.el --- react Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Andrea Moretti +;; URL: https://github.com/axyz +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq react-packages + '( + company + company-tern + emmet-mode + evil-matchit + flycheck + js-doc + smartparens + tern + web-beautify + web-mode + )) + +(defun react/post-init-company () + (spacemacs|add-company-hook react-mode)) + +(defun react/post-init-company-tern () + (push 'company-tern company-backends-react-mode)) + +(defun react/post-init-emmet-mode () + (add-hook 'react-mode-hook 'emmet-mode)) + +(defun react/post-init-evil-matchit () + (with-eval-after-load 'evil-matchit + (plist-put evilmi-plugins 'react-mode '((evilmi-simple-get-tag evilmi-simple-jump) + (evilmi-javascript-get-tag evilmi-javascript-jump) + (evilmi-html-get-tag evilmi-html-jump))))) + +(defun react/post-init-flycheck () + (with-eval-after-load 'flycheck + (dolist (checker '(javascript-eslint javascript-standard)) + (flycheck-add-mode checker 'react-mode))) + (defun react/use-eslint-from-node-modules () + (let* ((root (locate-dominating-file + (or (buffer-file-name) default-directory) + "node_modules")) + (global-eslint (executable-find "eslint")) + (local-eslint (expand-file-name "node_modules/.bin/eslint" + root)) + (eslint (if (file-executable-p local-eslint) + local-eslint + global-eslint))) + (setq-local flycheck-javascript-eslint-executable eslint))) + + (add-hook 'react-mode-hook #'react/use-eslint-from-node-modules) + + (spacemacs/add-flycheck-hook 'react-mode)) + +(defun react/post-init-js-doc () + (add-hook 'react-mode-hook 'spacemacs/js-doc-require) + (spacemacs/js-doc-set-key-bindings 'react-mode)) + +(defun react/post-init-smartparens () + (if dotspacemacs-smartparens-strict-mode + (add-hook 'react-mode-hook #'smartparens-strict-mode) + (add-hook 'react-mode-hook #'smartparens-mode))) + +(defun react/post-init-tern () + (add-hook 'react-mode-hook 'tern-mode) + (spacemacs//set-tern-key-bindings 'react-mode)) + +(defun react/post-init-web-beautify () + (spacemacs/set-leader-keys-for-major-mode 'react-mode "=" 'web-beautify-js)) + +(defun react/post-init-web-mode () + (define-derived-mode react-mode web-mode "react") + (add-to-list 'auto-mode-alist '("\\.jsx\\'" . react-mode)) + (add-to-list 'auto-mode-alist '("\\.react.js\\'" . react-mode)) + (add-to-list 'auto-mode-alist '("\\index.android.js\\'" . react-mode)) + (add-to-list 'auto-mode-alist '("\\index.ios.js\\'" . react-mode)) + (add-to-list 'magic-mode-alist '("/\\*\\* @jsx React\\.DOM \\*/" . react-mode)) + (add-to-list 'magic-mode-alist '("^import React" . react-mode)) + (defun spacemacs//setup-react-mode () + "Adjust web-mode to accommodate react-mode" + (emmet-mode 0) + ;; See https://github.com/CestDiego/emmet-mode/commit/3f2904196e856d31b9c95794d2682c4c7365db23 + (setq-local emmet-expand-jsx-className? t) + ;; Enable js-mode snippets + (yas-activate-extra-mode 'js-mode) + ;; Force jsx content type + (web-mode-set-content-type "jsx") + ;; Don't auto-quote attribute values + (setq-local web-mode-enable-auto-quoting nil)) + (add-hook 'react-mode-hook 'spacemacs//setup-react-mode)) diff --git a/layers/+frameworks/ruby-on-rails/README.org b/layers/+frameworks/ruby-on-rails/README.org new file mode 100644 index 0000000..dbeec77 --- /dev/null +++ b/layers/+frameworks/ruby-on-rails/README.org @@ -0,0 +1,83 @@ +#+TITLE: Ruby on Rails layer + +[[file:img/ror.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + - [[#code-navigation][Code Navigation]] + - [[#refactoring][Refactoring]] + - [[#run-commands][RUN commands]] + - [[#ex-commands][Ex-commands]] + +* Description +This layer aims at providing support for the Ruby on Rails framework. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =ruby-on-rails= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key bindings +** Code Navigation + +| Key binding | Description | +|---------------+-----------------------------------------------------------------| +| ~SPC m r f a~ | find localization file | +| ~SPC m r f c~ | find controller | +| ~SPC m r f e~ | find environment file | +| ~SPC m r f f~ | find feature | +| ~SPC m r f h~ | find helper | +| ~SPC m r f i~ | find initializer | +| ~SPC m r f j~ | find javascript file | +| ~SPC m r f l~ | find library | +| ~SPC m r f m~ | find model | +| ~SPC m r f n~ | find migration | +| ~SPC m r f o~ | find log | +| ~SPC m r f p~ | find spec file | +| ~SPC m r f r~ | find rake task | +| ~SPC m r f s~ | find stylesheet file | +| ~SPC m r f t~ | find test | +| ~SPC m r f u~ | find fixture | +| ~SPC m r f v~ | find view | +| ~SPC m r f y~ | find layout | +| ~SPC m r f @~ | find mailer | +| ~SPC m r g c~ | go to current controller | +| ~SPC m r g d~ | go to DB schema | +| ~SPC m r g e~ | go to DB seeds | +| ~SPC m r g h~ | go to current helper | +| ~SPC m r g j~ | go to current javascript | +| ~SPC m r g g~ | go to Gemfile | +| ~SPC m r g m~ | go to current model | +| ~SPC m r g n~ | go to current migration | +| ~SPC m r g p~ | go to current spec | +| ~SPC m r g r~ | go to routes | +| ~SPC m r g s~ | go to current stylesheet | +| ~SPC m r g t~ | go to current test | +| ~SPC m r g u~ | go to current fixture | +| ~SPC m r g v~ | go to current view | +| ~SPC m r g z~ | go to spec helper | +| ~SPC m r g .~ | go to file at point (faster but less powerful than ~SPC m g g~) | + +** Refactoring + +| Key binding | Description | +|---------------+-----------------------------| +| ~SPC m r R x~ | extract region into partial | + +** RUN commands + +| Key binding | Description | +|---------------+----------------------| +| ~SPC m r :~ | run rake task | +| ~SPC m r c c~ | run rails generator | +| ~SPC m r i~ | start rails console | +| ~SPC m r s r~ | reload Rails project | +| ~SPC m r x s~ | start rails server | + +** Ex-commands + +| Key binding | Description | +|-------------+-----------------------------------------| +| ~:A~ | Switch between implementation and tests | diff --git a/layers/+frameworks/ruby-on-rails/img/ror.png b/layers/+frameworks/ruby-on-rails/img/ror.png new file mode 100644 index 0000000..b58beb4 Binary files /dev/null and b/layers/+frameworks/ruby-on-rails/img/ror.png differ diff --git a/layers/+frameworks/ruby-on-rails/layers.el b/layers/+frameworks/ruby-on-rails/layers.el new file mode 100644 index 0000000..0f04e4b --- /dev/null +++ b/layers/+frameworks/ruby-on-rails/layers.el @@ -0,0 +1,14 @@ +;;; layers.el --- Ruby on Rails Layer layers File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Andrea Moretti +;; URL: https://github.com/axyz +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Prerequisites + +(configuration-layer/declare-layer 'ruby) diff --git a/layers/+frameworks/ruby-on-rails/packages.el b/layers/+frameworks/ruby-on-rails/packages.el new file mode 100644 index 0000000..860c7f8 --- /dev/null +++ b/layers/+frameworks/ruby-on-rails/packages.el @@ -0,0 +1,89 @@ +;;; packages.el --- Ruby on Rails Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq ruby-on-rails-packages + '( + feature-mode + projectile-rails + which-key + )) + +(defun ruby-on-rails/init-projectile-rails () + (use-package projectile-rails + :defer t + :init + (progn + (add-hook 'projectile-mode-hook 'projectile-rails-on)) + :config + (progn + (spacemacs|diminish projectile-rails-mode " ⇋" " RoR") + + ;; Find files + (dolist (mode '(ruby-mode enh-ruby-mode)) + (spacemacs/set-leader-keys-for-major-mode mode + "rfa" 'projectile-rails-find-locale + "rfc" 'projectile-rails-find-controller + "rfe" 'projectile-rails-find-environment + "rff" 'projectile-rails-find-feature + "rfh" 'projectile-rails-find-helper + "rfi" 'projectile-rails-find-initializer + "rfj" 'projectile-rails-find-javascript + "rfl" 'projectile-rails-find-lib + "rfm" 'projectile-rails-find-model + "rfn" 'projectile-rails-find-migration + "rfo" 'projectile-rails-find-log + "rfp" 'projectile-rails-find-spec + "rfr" 'projectile-rails-find-rake-task + "rfs" 'projectile-rails-find-stylesheet + "rft" 'projectile-rails-find-test + "rfu" 'projectile-rails-find-fixture + "rfv" 'projectile-rails-find-view + "rfy" 'projectile-rails-find-layout + "rf@" 'projectile-rails-find-mailer + ;; Goto file + "rgc" 'projectile-rails-find-current-controller + "rgd" 'projectile-rails-goto-schema + "rge" 'projectile-rails-goto-seeds + "rgh" 'projectile-rails-find-current-helper + "rgj" 'projectile-rails-find-current-javascript + "rgg" 'projectile-rails-goto-gemfile + "rgm" 'projectile-rails-find-current-model + "rgn" 'projectile-rails-find-current-migration + "rgp" 'projectile-rails-find-current-spec + "rgr" 'projectile-rails-goto-routes + "rgs" 'projectile-rails-find-current-stylesheet + "rgt" 'projectile-rails-find-current-test + "rgu" 'projectile-rails-find-current-fixture + "rgv" 'projectile-rails-find-current-view + "rgz" 'projectile-rails-goto-spec-helper + "rg." 'projectile-rails-goto-file-at-point + ;; Rails external commands + "r:" 'projectile-rails-rake + "rcc" 'projectile-rails-generate + "ri" 'projectile-rails-console + "rxs" 'projectile-rails-server + ;; Refactoring 'projectile-rails-mode + "rRx" 'projectile-rails-extract-region) + (spacemacs/declare-prefix-for-mode mode "mr" "rails/rubocop") + (spacemacs/declare-prefix-for-mode mode "mrf" "file") + (spacemacs/declare-prefix-for-mode mode "mrg" "goto")) + + ;; Ex-commands + (evil-ex-define-cmd "A" 'projectile-toggle-between-implementation-and-test)))) + +(defun ruby-on-rails/init-feature-mode () + "Initialize Cucumber feature mode" + (use-package feature-mode + :mode (("\\.feature\\'" . feature-mode)))) + +(defun ruby-on-rails/post-init-which-key () + (push '("projectile-rails-\\(.+\\)" . "\\1") + which-key-description-replacement-alist)) diff --git a/layers/+fun/emoji/README.org b/layers/+fun/emoji/README.org new file mode 100644 index 0000000..2f02168 --- /dev/null +++ b/layers/+fun/emoji/README.org @@ -0,0 +1,38 @@ +#+TITLE: Emoji layer + +[[file:img/emojis.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + - [[#emoji-dedicated-buffer][Emoji dedicated buffer]] + +* Description +This layer adds support for Emoji emoticons from [[http://www.emoji-cheat-sheet.com/][emoji-cheat-sheet.com]]. + +** Features +- Browse Emoji in a dedicated buffer +- Display Emoji images in buffer +- Insert one or several Emoji with an helm front-end +- Completion of Emojis using [[https://github.com/dunn/company-emoji][company-emoji]] + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =emoji= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key bindings + +| Key Binding | Description | +|-------------+-----------------------------------------| +| ~SPC a E~ | open a dedicated buffer to browse Emoji | +| ~SPC i e~ | insert Emoji via an helm buffer | + +** Emoji dedicated buffer + +| Key Binding | Description | +|-------------+-------------------------| +| ~RET~ | copy current Emoji code | +| ~q~ | quit | diff --git a/layers/+fun/emoji/img/emojis.png b/layers/+fun/emoji/img/emojis.png new file mode 100644 index 0000000..fd58e1b Binary files /dev/null and b/layers/+fun/emoji/img/emojis.png differ diff --git a/layers/+fun/emoji/packages.el b/layers/+fun/emoji/packages.el new file mode 100644 index 0000000..50e584a --- /dev/null +++ b/layers/+fun/emoji/packages.el @@ -0,0 +1,42 @@ +;;; packages.el --- emoji Layer Packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq emoji-packages + '( + emoji-cheat-sheet-plus + (company-emoji :toggle (configuration-layer/package-usedp 'company)) + )) + +(defun emoji/init-emoji-cheat-sheet-plus () + (use-package emoji-cheat-sheet-plus + :commands (emoji-cheat-sheet-plus-insert + emoji-cheat-sheet-plus-buffer + emoji-cheat-sheet-plus-display-mode) + :init + (progn + (spacemacs/set-leader-keys "aE" 'emoji-cheat-sheet-plus-buffer) + (spacemacs/set-leader-keys "ie" 'emoji-cheat-sheet-plus-insert) + (evilified-state-evilify emoji-cheat-sheet-plus-buffer-mode + emoji-cheat-sheet-plus-buffer-mode-map + "" 'emoji-cheat-sheet-plus-echo-and-copy) + + (defun spacemacs/delay-emoji-cheat-sheet-hook () + "Work-around for org buffers." + ;; we need to wait for org buffer to be fully loaded before + ;; calling the emoji mode. + ;; If we directly call the emoji mode at hook runtime then some + ;; text properties are not applied correctly. + (run-at-time 0.1 nil 'emoji-cheat-sheet-plus-display-mode))))) + +(defun emoji/init-company-emoji () + (use-package company-emoji + :defer t + :init (setq company-emoji-insert-unicode nil))) diff --git a/layers/+fun/games/README.org b/layers/+fun/games/README.org new file mode 100644 index 0000000..efe8ba2 --- /dev/null +++ b/layers/+fun/games/README.org @@ -0,0 +1,96 @@ +#+TITLE: Games layer + +[[file:img/games.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#games-instructions][Games instructions]] + - [[#2048][2048]] + - [[#pacmacs][Pacmacs]] + - [[#tetris][Tetris]] + - [[#typit][Typit]] + - [[#create-a-new-dictionary][Create a new dictionary]] + +* Description +This layer allows you to play evilified games in spacemacs. + +The games available now are: +- 2048-game +- Pacmacs (Pacman for Emacs) +- Tetris +- Typit + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =games= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Games instructions +To run a game: + +| Key Binding | Description | +|-------------+----------------------------------------| +| ~SPC a G~ | Open an =helm= buffer to select a game | + +Possible helm actions: +- run (default) +- quit +- reset + +** 2048 + +| Key Binding | Description | +|-------------+----------------------| +| ~h~ | Move the tiles left | +| ~j~ | Move the tiles down | +| ~k~ | Move the tiles up | +| ~l~ | Move the tiles right | + +** Pacmacs + +| Key Binding | Description | +|-------------+-------------| +| ~h~ | Move left | +| ~j~ | Move down | +| ~k~ | Move up | +| ~l~ | Move right | +| | | + +** Tetris + +| Key Binding | Description | +|-------------+--------------------------------| +| ~h~ | Move block to the left | +| ~i~ | Rotate block counter-clockwise | +| ~j~ | Move block to the bottom | +| ~k~ | Rotate block clockwise | +| ~l~ | Move block to the right | +| ~n~ | Start a new game | +| ~p~ | Pause the game | +| ~q~ | Quit the game | + +** Typit +There is no specific key bindings for this game, just launch it and begin +typing. Use ~C-g~ to exit the game at any time. + +There are two difficulties: +- beginner: use 200 most common words +- expert: use 1000 most common words + +By default a game duration is one minute. + +The game can be customized with the following variables: + +| Vsariable | Description | +|---------------------+-------------------------------------------------------| +| =typit-dict= | Language dictionary to use (default is =english.txt=) | +| =typit-dict-dir= | A directory path where to find dictionaries | +| =typit-line-length= | Length of generated lines (default 80) | +| =typit-test-time= | Duration of a game in seconds (default 60) | + +*** Create a new dictionary +To add a new dictionary, you need to create a text file named your-language.txt +and put it under the dict directory. That file should contain 1000 most common +words from the language, a word per line. Please make sure that it uses +Unix-style (that is, LF) end-of-line sequence and the file ends with a newline. diff --git a/layers/+fun/games/config.el b/layers/+fun/games/config.el new file mode 100644 index 0000000..a78697c --- /dev/null +++ b/layers/+fun/games/config.el @@ -0,0 +1,22 @@ +;;; config.el --- Games Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variable + +(defvar spacemacs-games-cache-directory + (concat spacemacs-cache-directory "games/") + "Directory where to store games data.") + +;; create the game cache directory +(unless (file-exists-p spacemacs-games-cache-directory) + (make-directory spacemacs-games-cache-directory)) + +(setq helm-games-list nil) diff --git a/layers/+fun/games/funcs.el b/layers/+fun/games/funcs.el new file mode 100644 index 0000000..91faea6 --- /dev/null +++ b/layers/+fun/games/funcs.el @@ -0,0 +1,44 @@ +;;; funcs.el --- Games Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + + +(defun spacemacs/tetris-quit-game () + "Correctly quit tetris by killng the game buffer." + (interactive) + (tetris-pause-game) + (if (yes-or-no-p "Do you really want to quit ? ") + (progn + (tetris-end-game) + (kill-buffer "*Tetris*")) + (tetris-pause-game))) + + + +(defun spacemacs/games-start-typit-beginner () + "Start `typit' game in beginner difficulty." + (interactive) + (spacemacs//games-start-typit 'basic)) + +(defun spacemacs/games-start-typit-expert () + "Start `typit' game in expert difficulty." + (interactive) + (spacemacs//games-start-typit 'advanced)) + +(defun spacemacs//games-start-typit (type) + "Start a `typit' game with TYPE difficulty." + (with-current-buffer (get-buffer-create "*typit*") + (let ((evil-escape-inhibit t) + (golden-ratio-mode nil)) + (evil-insert-state) + (funcall (intern (format "typit-%S-test" type)))))) + + diff --git a/layers/+fun/games/img/games.png b/layers/+fun/games/img/games.png new file mode 100644 index 0000000..8e62caa Binary files /dev/null and b/layers/+fun/games/img/games.png differ diff --git a/layers/+fun/games/local/helm-games/helm-games.el b/layers/+fun/games/local/helm-games/helm-games.el new file mode 100644 index 0000000..9233d13 --- /dev/null +++ b/layers/+fun/games/local/helm-games/helm-games.el @@ -0,0 +1,82 @@ +;;; helm-games.el --- Games selection with `helm'. + +;; Author: Sylvain Benner +;; Keywords: helm, spacemacs, games +;; Version: 0.1 +;; Package-Requires: ((helm "1.5")) + +;; This file 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, or (at your option) +;; any later version. + +;; This file 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., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: +;; This package adds a convenient way to discover Spacemacs configuration +;; layers thanks to helm. + +;;; Code: + +(require 'helm) + +(defvar helm-games-list '() + "List of game candidates to pass to helm.") + +;;;###autoload +(defun helm-games () + "Games selection with helm interface." + (interactive) + (helm :buffer "*helm: games*" + :sources `(,(helm-games//games-source)))) + +(defun helm-games//games-source () + "Construct the helm source for the games." + `((name . "Games") + (candidates . ,(helm-games//game-candidates)) + (candidate-number-limit) + (action . (("Run" . helm-games//run-game) + ("Quit" . helm-games//quit-game) + ("Reset" . helm-games//reset-game))))) + +(defun helm-games//game-candidates () + "Return the list of game candidates." + (setq helm-games-list (sort helm-games-list + (lambda (x y) + (string< (car x) (car y))))) + helm-games-list) + +(defun helm-games//run-game (candidate) + "Run the selected game." + (message "%s" candidate) + (let ((func (car candidate))) + (when func + (call-interactively func)))) + +(defun helm-games//quit-game (candidate) + "Quit the selected game." + (let ((func (plist-get (cdr candidate) :quit))) + (when func + (if (listp func) + (eval func) + (funcall func))))) + +(defun helm-games//reset-game (candidate) + "Reset the selected game." + (let ((func (plist-get (cdr candidate) :reset))) + (when func + (if (listp func) + (eval func) + (funcall func))))) + +(provide 'helm-games) + +;;; helm-games.el ends here diff --git a/layers/+fun/games/packages.el b/layers/+fun/games/packages.el new file mode 100644 index 0000000..ee9fdb7 --- /dev/null +++ b/layers/+fun/games/packages.el @@ -0,0 +1,89 @@ +;;; packages.el --- games Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq games-packages + '( + 2048-game + (helm-games :location local + :toggle (configuration-layer/package-usedp 'helm)) + pacmacs + (tetris :location built-in) + typit + )) + +(defun games/init-2048-game () + (use-package 2048-mode + :defer t + :init + (progn + (push '("2048" . (2048-game :quit (kill-buffer-ask (get-buffer "2048")) + :reset 2048-init)) helm-games-list) + (evilified-state-evilify 2048-mode 2048-mode-map + "j" '2048-down + "k" '2048-up + "h" '2048-left + "l" '2048-right)))) + +(defun games/init-helm-games () + (use-package helm-games + :commands helm-games + :init + (progn + (spacemacs/declare-prefix "aG" "games") + (spacemacs/set-leader-keys "aG" 'helm-games)))) + +(defun games/init-pacmacs () + (use-package pacmacs + :defer t + :init + (push '("pacmacs" . (pacmacs-start + :quit (kill-buffer-ask (get-buffer "*Pacmacs*")) + :reset pacmacs-start)) helm-games-list) + (evilified-state-evilify pacmacs-mode pacmacs-mode-map + "h" 'pacmacs-left + "j" 'pacmacs-down + "k" 'pacmacs-up + "l" 'pacmacs-right))) + +(defun games/init-tetris () + (use-package tetris + :defer t + :init + (progn + (push '("Tetris" . (tetris :quit spacemacs/tetris-quit-game + :reset tetris-start-game)) helm-games-list) + (setq tetris-score-file (concat spacemacs-games-cache-directory + "tetris-scores.txt"))) + :config + (progn + (evilified-state-evilify tetris-mode tetris-mode-map + "h" 'tetris-move-left + "i" 'tetris-rotate-prev + "j" 'tetris-move-bottom + "k" 'tetris-rotate-next + "l" 'tetris-move-right + "q" 'spacemacs/tetris-quit-game)))) + +(defun games/init-typit () + (use-package typit + :defer t + :init + (progn + (push '("typit (beginner)" . + (spacemacs/games-start-typit-beginner + :quit (kill-buffer-ask (get-buffer "*typit*")) + :reset spacemacs/games-start-typit-beginner)) + helm-games-list) + (push '("typit (expert)" . + (spacemacs/games-start-typit-expert + :quit (kill-buffer-ask (get-buffer "*typit*")) + :reset spacemacs/games-start-typit-expert)) + helm-games-list)))) diff --git a/layers/+fun/selectric/README.org b/layers/+fun/selectric/README.org new file mode 100644 index 0000000..6cd5d60 --- /dev/null +++ b/layers/+fun/selectric/README.org @@ -0,0 +1,28 @@ +#+TITLE: selectric layer + +[[file:img/typewriter.jpg]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key Bindings]] + +* Description +This layer makes your Emacs sound like an IBM Selectric typewriter, for those +moments when your loud, clicky mechanical keyboard is not at hand, yet, you'd +still wish to enjoy the sound. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =selectric= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key Bindings + +| Key Binding | Description | +|-------------+--------------------------| +| ~SPC C-t t~ | Toggle clicky key sounds | + +* Notes + +IBM Selectric image by Oliver Kurmis diff --git a/layers/+fun/selectric/img/typewriter.jpg b/layers/+fun/selectric/img/typewriter.jpg new file mode 100644 index 0000000..c5dac20 Binary files /dev/null and b/layers/+fun/selectric/img/typewriter.jpg differ diff --git a/layers/+fun/selectric/packages.el b/layers/+fun/selectric/packages.el new file mode 100644 index 0000000..90ae8d4 --- /dev/null +++ b/layers/+fun/selectric/packages.el @@ -0,0 +1,20 @@ +;;; packages.el --- selectric Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Gergely Nagy +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq selectric-packages '(selectric-mode)) + +(defun selectric/init-selectric-mode () + (use-package selectric-mode + ;; at the moment of adding this layer, selectric-mode is not + ;; autoloaded. + :commands selectric-mode + :init (spacemacs/set-leader-keys "C-t t" 'selectric-mode) + :config (spacemacs|diminish selectric-mode "♬" "Tw"))) diff --git a/layers/+fun/xkcd/README.org b/layers/+fun/xkcd/README.org new file mode 100644 index 0000000..afdcc49 --- /dev/null +++ b/layers/+fun/xkcd/README.org @@ -0,0 +1,44 @@ +#+TITLE: xkcd layer + +[[file:img/xkcd.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key Bindings]] + - [[#tell-me-how-to-spawn-the-xkcd-greatness][Tell me how to spawn the xkcd greatness!!]] + - [[#okay-what-now][Okay, what now]] + +* Description +This layer adds a [[http://xkcd.com/][xkcd]] navigation mode using [[https://github.com/vibhavp/emacs-xkcd][emacs-xkcd]]. + +Features: +- Load a random xkcd +- Show the text in the modeline +- Open explanation and current comic in browser +- Cache the comics in =.cache/xkcd= + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =xkcd= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key Bindings +** Tell me how to spawn the xkcd greatness!! + +| Key Binding | Description | +|-------------+----------------| +| ~SPC a x~ | Open xkcd mode | + +** Okay, what now +You can now move through the comics with these + +| Key Binding | Description | +|-------------+-------------------------------------| +| ~e~ | Open explanation in the browser | +| ~j~ or ~l~ | Next comic | +| ~k~ or ~h~ | Previous comic | +| ~o~ | Open the browser | +| ~q~ | Quit the buffer | +| ~r~ | Random comic | +| ~t~ | Show alternate text in the modeline | diff --git a/layers/+fun/xkcd/img/xkcd.png b/layers/+fun/xkcd/img/xkcd.png new file mode 100644 index 0000000..848dd25 Binary files /dev/null and b/layers/+fun/xkcd/img/xkcd.png differ diff --git a/layers/+fun/xkcd/packages.el b/layers/+fun/xkcd/packages.el new file mode 100644 index 0000000..0e76e3c --- /dev/null +++ b/layers/+fun/xkcd/packages.el @@ -0,0 +1,28 @@ +;;; packages.el --- xkcd Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq xkcd-packages '(xkcd)) + +(defun xkcd/init-xkcd () + (use-package xkcd-mode + :defer t + :init + (progn + (setq xkcd-cache-dir (concat spacemacs-cache-directory "xkcd/")) + (when (not (file-directory-p xkcd-cache-dir)) + (make-directory xkcd-cache-dir)) + (spacemacs/set-leader-keys + "ax" 'xkcd) + (evilified-state-evilify xkcd-mode xkcd-mode-map + "h" 'xkcd-prev + "j" 'xkcd-next + "k" 'xkcd-prev + "l" 'xkcd-next)))) diff --git a/layers/+intl/chinese/README.org b/layers/+intl/chinese/README.org new file mode 100644 index 0000000..ad3bd82 --- /dev/null +++ b/layers/+intl/chinese/README.org @@ -0,0 +1,137 @@ +#+TITLE: Chinese layer + +[[file:img/China.png]] [[file:img/Chinese.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#configuration][Configuration]] + - [[#configure-the-default-input-method配置默认中文输入法][Configure the Default Input Method(配置默认中文输入法)]] + - [[#configure-the-chinese-pyim-input-method配置中文拼音输入法][Configure the =Chinese-pyim= Input Method(配置中文拼音输入法)]] + - [[#enable-fcitx][Enable fcitx]] + - [[#requirement][Requirement]] + - [[#enable-youdao有道-dictionary激活有道字典][Enable YouDao(有道) Dictionary(激活有道字典)]] + - [[#set-monospaced-font-size设置等宽字体][Set monospaced font size(设置等宽字体)]] + - [[#enabledisable-ace-pinyin-in-avy-goto-char][Enable/Disable ace-pinyin in =avy-goto-char=]] + - [[#key-bindings][Key Bindings]] + - [[#youdao-dictionary][Youdao Dictionary]] + - [[#find-by-pinyin-dired][Find-by-pinyin-dired]] + +* Description +This Layer adds Chinese related packages: +- [[https://github.com/tumashu/chinese-pyim][chinese-pyim]] : The best Chinese Pinyin(拼音) input method. +- [[https://github.com/andyque/chinese-wbim][chinese-wbim]]: The best Chinese Wubi(五笔) input method. +- [[https://github.com/cute-jumper/fcitx.el][cute-jumper/fcitx.el]]: This package provides a set of functions to make fcitx work better in Emacs. +- [[https://github.com/xuchunyang/youdao-dictionary.el][youdao-dictionary]]: The Youdao(有道) Dictionary interface for Emacs. +- [[https://github.com/redguardtoo/find-by-pinyin-dired][find-by-pinyin-dired]]: Find file by first Pinyin characters of Chinese Hanzi. +- [[https://github.com/cute-jumper/ace-pinyin][ace-pinyin]]: Jump to Chinese character by pinyin with =ace-jump-mode=. +- [[https://github.com/coldnew/pangu-spacing][coldnew/pangu-spacing]] : emacs minor-mode to add space between Chinese and English characters. +- Join consecutive Chinese lines into a single long line without unwanted space when exporting org-mode to html. + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =chinese= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Configuration +*** Configure the Default Input Method(配置默认中文输入法) +The default Chinese input method is =Chinese-pyim=, if you are a Wubi(五笔) user, +you could set the variable =chinese-default-input-method= to =wubi=: +#+begin_src emacs-lisp + (setq-default dotspacemacs-configuration-layers '( + (chinese :variables chinese-default-input-method 'wubi))) +#+end_src + +*** Configure the =Chinese-pyim= Input Method(配置中文拼音输入法) +When the first time you use =Chinese-pyim=, you should install the lexicon(词库) +file. You could call =pyim-dicts-manager= to open up the settings buffer and +press =i e= to install the default lexicon. The lexicon is about 20M, so you +should be patient when downloading starts. After the lexicon file is downloaded, +just press =s= to save and =R= to restart configuration. + +*** Enable fcitx +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '((chinese :variables + chinese-enable-fcitx t))) +#+END_SRC +If you don’t need to type Chinese in minibuffer, you could temporarily disable fcitx in minibuffer +with the following configuration. + +#+BEGIN_SRC emacs-lisp + (fcitx-aggressive-setup) +#+END_SRC + +**** Requirement +***** Linux +You need use this with =fcitx= and make sure =fcitx-remote= is in your search path. + +***** Mac OS X +We don't have a =fcitx= in OS X yet but we already added an emulation called +=fcitx-remote= to make you happy with other Chinese input-methods. + +You can install [[https://github.com/CodeFalling/fcitx-remote-for-osx][fcitx-remote-for-osx]] from homebrew. + +#+BEGIN_SRC shell + brew install fcitx-remote-for-osx --with-input-method=baidu-pinyin +#+END_SRC + +=--with-input-method=baidu-pinyin= means install for Baidu-pinyin Input Method. + +You can use =brew info fcitx-remote-for-osx= to get more options info for input +method support. + +#+BEGIN_EXAMPLE +--with-input-method= + Select input method: baidu-pinyin(default), baidu-wubi, sogou-pinyin, qq-wubi, squirrel-rime, osx-pinyin +#+END_EXAMPLE + +***** Windows +In order to use =fcitx.el= in Windows, you should install [[https://github.com/cute-jumper/fcitx-remote-for-windows][fcitx-remote-for-windows]]. + +*** Enable YouDao(有道) Dictionary(激活有道字典) +The YouDao Dictionary is disabled by default, if you want enable it. +You should set =chinese-enable-youdao-dict= to =t=. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '((chinese :variables + chinese-enable-youdao-dict t))) + +#+END_SRC + +*** Set monospaced font size(设置等宽字体) +If you are mixing Chinese words with English words, the text is not perfectly +aligned in org table. That's because normally the Chinese font size is not equal +to the English font size. You could call =spacemacs//set-monospaced-font= with +your own Chinese font name in =dotspacemacs/user-config= function. + +Example configuration: +#+BEGIN_SRC emacs-lisp +;; Note: The Hiragino Sans GB is bundled with MacOS X. +;; If you are not using MacOS X, you should change it to another Chinese font name. +(spacemacs//set-monospaced-font "Source Code Pro" "Hiragino Sans GB" 14 16) +#+END_SRC + +*** Enable/Disable ace-pinyin in =avy-goto-char= +You can use =avy-goto-char= with pinyin supported by default, if you want to +disable it.You can set =chinese-enable-avy-pinyin= to =nil=. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '((chinese :variables + chinese-enable-avy-pinyin nil))) +#+END_SRC + +* Key Bindings +Currently, there are no built-in key bindings for this layer. You could define +your own preference. + +Here are a few suggested key bindings (remember that ~SPC o~ is reserved for +personal usage, spacemacs won´t put any binding under this prefix): + +** Youdao Dictionary +Bind ~SPC o y~ to =youdao-dictionary-search-at-point+=. + +** Find-by-pinyin-dired +Bind ~SPC o d~ to =find-by-pinyin-dired= + diff --git a/layers/+intl/chinese/config.el b/layers/+intl/chinese/config.el new file mode 100644 index 0000000..fc79f55 --- /dev/null +++ b/layers/+intl/chinese/config.el @@ -0,0 +1,38 @@ +;;; config.el --- Chinese Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(defvar chinese-default-input-method 'pinyin + "The default chinese input method. Can be `wubi` or `pinyin`.") + +(defvar chinese-enable-youdao-dict nil + "Enable YouDao Dict translation service.") + +(defvar chinese-enable-avy-pinyin t + "Enable ace-pinyin in avy-goto-char") + +(defvar chinese-enable-fcitx nil + "Enable fcitx to help writing Chinese in Evil mode.") + +;; Set the monospaced font size when mixed Chinese and English words +(defun spacemacs//set-monospaced-font (english chinese english-size chinese-size) + (set-face-attribute 'default nil :font + (format "%s:pixelsize=%d" english english-size)) + (dolist (charset '(kana han cjk-misc bopomofo)) + (set-fontset-font (frame-parameter nil 'font) charset + (font-spec :family chinese :size chinese-size)))) + +;; If the Hiragino Sans GB font is not found in your system, you could call this +;; method in dotspacemacs/user-config function with a different Chinese font name. +;; If you are using mac, you could put the following code in your dotspacemacs/user-config function. +;; (when (spacemacs/system-is-mac) +;; (spacemacs//set-monospaced-font "Source Code Pro" "Hiragino Sans GB" 14 16)) diff --git a/layers/+intl/chinese/img/China.png b/layers/+intl/chinese/img/China.png new file mode 100644 index 0000000..a2c4ea2 Binary files /dev/null and b/layers/+intl/chinese/img/China.png differ diff --git a/layers/+intl/chinese/img/Chinese.png b/layers/+intl/chinese/img/Chinese.png new file mode 100644 index 0000000..5ac390c Binary files /dev/null and b/layers/+intl/chinese/img/Chinese.png differ diff --git a/layers/+intl/chinese/packages.el b/layers/+intl/chinese/packages.el new file mode 100644 index 0000000..0737600 --- /dev/null +++ b/layers/+intl/chinese/packages.el @@ -0,0 +1,109 @@ +;;; packages.el --- Chinese Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; List of all packages to install and/or initialize. Built-in packages +;; which require an initialization must be listed explicitly in the list. +(setq chinese-packages + '( + (chinese-pyim :toggle (eq chinese-default-input-method 'pinyin)) + (chinese-wbim :toggle (eq chinese-default-input-method 'wubi)) + (fcitx :toggle chinese-enable-fcitx) + find-by-pinyin-dired + ace-pinyin + pangu-spacing + org + (youdao-dictionary :toggle chinese-enable-youdao-dict) + )) + +(defun chinese/init-fcitx () + (use-package fcitx + :init + (fcitx-evil-turn-on))) + +(defun chinese/init-chinese-wbim () + "Initialize chinese-wubi" + (use-package chinese-wbim + :if (eq 'wubi chinese-default-input-method) + :init + (progn + (autoload 'chinese-wbim-use-package "chinese-wubi" + "Another emacs input method") + ;; Tooptip is not good enough, so disable it here. + (setq chinese-wbim-use-tooltip nil) + (register-input-method + "chinese-wubi" "euc-cn" 'chinese-wbim-use-package + "五笔" "汉字五笔输入法" "wb.txt") + (require 'chinese-wbim-extra) + (global-set-key ";" 'chinese-wbim-insert-ascii) + (setq default-input-method 'chinese-wubi)))) + +(defun chinese/init-youdao-dictionary () + (use-package youdao-dictionary + :if chinese-enable-youdao-dict + :defer + :config + (progn + ;; Enable Cache + (setq url-automatic-caching t + ;; Set file path for saving search history + youdao-dictionary-search-history-file + (concat spacemacs-cache-directory ".youdao") + ;; Enable Chinese word segmentation support + youdao-dictionary-use-chinese-word-segmentation t)))) + +(defun chinese/init-chinese-pyim () + (use-package chinese-pyim + :if (eq 'pinyin chinese-default-input-method) + :init + (progn + (setq pyim-use-tooltip t + pyim-dicts-directory spacemacs-cache-directory + pyim-personal-file (concat spacemacs-cache-directory + "pyim-personal.txt") + default-input-method "chinese-pyim") + (evilified-state-evilify pyim-dicts-manager-mode pyim-dicts-manager-mode-map)))) + +(defun chinese/init-find-by-pinyin-dired () + (use-package find-by-pinyin-dired + :defer t)) + +(defun chinese/init-ace-pinyin () + (use-package ace-pinyin + :defer t + :init + (progn + (if chinese-enable-avy-pinyin + (setq ace-pinyin-use-avy t)) + (ace-pinyin-global-mode t) + (spacemacs|hide-lighter ace-pinyin-mode)))) + +(defun chinese/init-pangu-spacing () + (use-package pangu-spacing + :defer t + :init (progn (global-pangu-spacing-mode 1) + (spacemacs|hide-lighter pangu-spacing-mode) + ;; Always insert `real' space in org-mode. + (add-hook 'org-mode-hook + '(lambda () + (set (make-local-variable 'pangu-spacing-real-insert-separtor) t)))))) + +(defun chinese/post-init-org () + (defadvice org-html-paragraph (before org-html-paragraph-advice + (paragraph contents info) activate) + "Join consecutive Chinese lines into a single long line without +unwanted space when exporting org-mode to html." + (let* ((origin-contents (ad-get-arg 1)) + (fix-regexp "[[:multibyte:]]") + (fixed-contents + (replace-regexp-in-string + (concat + "\\(" fix-regexp "\\) *\n *\\(" fix-regexp "\\)") "\\1\\2" origin-contents))) + (ad-set-arg 1 fixed-contents)))) diff --git a/layers/+intl/keyboard-layout/README.org b/layers/+intl/keyboard-layout/README.org new file mode 100644 index 0000000..fa80bb6 --- /dev/null +++ b/layers/+intl/keyboard-layout/README.org @@ -0,0 +1,189 @@ +#+TITLE: keyboard-layout layer + +[[file:img/keyboard-layout.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#installation][Installation]] + - [[#configuration][Configuration]] + - [[#enabledisable-package-configurations][Enable/Disable package configurations]] + - [[#addoverride-key-bindings][Add/Override key bindings]] + - [[#concept][Concept]] + - [[#keyboard-layouts][Keyboard layouts]] + - [[#bepo][bepo]] + - [[#dvorak][dvorak]] + - [[#package-configurations][Package Configurations]] + - [[#keybindings][Keybindings]] + - [[#sources][Sources]] + +* Description +This layer configures some keybindings in spacemacs to make it compatible with +keyboard layouts that differs from the traditional =en-us= keymap. + +* Installation +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =keyboard-layout= to the existing =dotspacemacs-configuration-layers= list +in this file. You can then select the desired layout by specifying the +=kl-layout= variable: + +#+begin_src emacs-lisp +(setq-default dotspacemacs-configuration-layers '( + (keyboard-layout :variables kl-layout 'dvorak))) +#+end_src + +* Configuration +** Enable/Disable package configurations +This layer can be customized with two variables: +- kl-enabled-configurations +- kl-disabled-configurations + +The first one is used to set the list of configurations to activate, and the +second one to prevent loading certain configurations. If the +=kl-enabled-configurations= is nil (by default), all configurations are loaded. +Otherwise, only the listed configurations are loaded. Any configuration listed +in =kl-disabled-configurations= will never be loaded, whether it is in the +enabled list or not (empty by default). + +#+begin_src emacs-lisp +(setq-default dotspacemacs-configuration-layers '( + (keyboard-layout :variables + kl-layout 'dvorak + kl-disabled-configurations '(org magit)))) +#+end_src + +** Add/Override key bindings +It is possible to override or add bindings by defining functions named +=kl/pre-config-= and =kl/post-config-= in =dotspacemacs/user-init=. +They are respectively called just before and after the actual configuration of +keybindings in this layer, so *you don't have to think about when to apply the +configuration by yourself*. == is the name of the configuration you want +to customize, they are listed under the [[#configuration][Configuration]] section. + +Example: +#+begin_src emacs-lisp +(defun kl/post-config-company () + "Company delete backward." + (kl/set-in-state company-active-map (kbd "C-w") 'evil-delete-backward-word)) +#+end_src + +Note: If you define some of these functions in your own layer, be sure that the +=keyboard-layout= layer is placed _after_ it in the +=dotspacemacs-configuration-layers= list. + +* Concept +This package first switch traditional ~hjkl~ movement keys with their equivalent +in destination layout, and then try to correct the bugs introduced by these +changes in other parts of Spacemacs. This layer only tries to do these changes +when the letters are used for *doing a movement*. + +The equivalent remapping is also made for uppercase letters, ~CTRL+KEY~, +~META+KEY~ and leaders keybindings (~SPC …~) whenever it makes sense to make +such changes. + +In some cases the key remapping will not follow these conventions, mainly +because there are better alternatives, or because some moves don't make sense. + +#+begin_verse +Example: In the =magit= status buffer, the ~c~ is used for =commit= by default, +but if we want to follow the conventions, it should be remapped to "move left" +in bepo. As it is not useful to move left on =magit= because operations are done +line by line the ~c~ is not remapped. +#+end_verse + +* Keyboard layouts +The keyboard-layouts available with this layer are the following: + +** bepo +[[file:img/bepo-logo.png]] + +=bepo= is a keyboard layout optimized for the French language. + +[[file:img/bepo-keymap.png]] + +The mapping correction is the one proposed for vim on the official bepo [[http://bepo.fr/wiki/Vim#Principe][wiki]]. + +- Map the movements keys under the right hand's fingers: + - ~c → h~ + - ~t → j~ + - ~s → k~ + - ~r → l~ + +- Map lost functionalities back to some keys: + - ~h → r~ + - ~j → t~ + - ~k → s~ + - ~l → c~ + +Some bepo keys are not used in traditional mapping, mainly because they are not +on the =en-us= keyboard layout. They are used as aliases for other shortcuts: + +- Map unused ~é~ key as an alias of ~w~, more useful in vim mode: + - ~é → w~ + - ~É → W~ + +- Map indentation on direct-access keys: + - ~» → >~ + - ~« → <~ + +Some default configurations are also not optimal for vim, so the following +defaults are changed: + +- Change =evil-escape= escape combination to something faster to type, while + being nearly nonexistent in French or English words: + - ~fd → gq~ + +- In =avy=, the key used to select words/lines are remapped to the 8 characters + under the fingers: + - ~a u i e t s r n~ + +Note: One difference exists with the wiki version: the ~w~ is *not* remapped to +~C-w~ to avoid having to change its meaning in other modes. Spacemacs provides +already a ~SPC w~ key binding for working with windows. + +** dvorak +=dvorak= is a keyboard layout optimized for the English language. [[http://www.kaufmann.no/roland/dvorak/][dvorak +programmer]] is an optimized keyboard layout focused in programming and it's a +variant of the more general =dvorak= (us) keyboard layout. This configuration +will remap keybindings for the =dvorak-programmer= variant. + +[[file:img/dvorak-keymap.png]] + +* Package Configurations +The available configurations are: + +- ace-window +- avy +- comint +- company +- elfeed +- evil +- evil-escape +- evil-evilified-state +- evil-surround +- eyebrowse +- flycheck +- helm +- imenu-list +- ivy +- magit +- mu4e +- neotree +- org +- org-agenda +- ranger +- twittering-mode + +* Keybindings +This layer is using functions that try to /automatically/ remap keybindings in a +lot of modes, so it's difficult to list all changed keybindings. And + +- You chose to use a different keyboard layout. +- You chose to be on the dark side by using evil (because they have :cookie: obviously). +- You chose to use a layer, written with :heart:, that try to solve the induced mess. + +So the price you have to pay is the absence of a keybindings list. + +* Sources +The keyboard-layout logo is coming from [[https://openclipart.org/detail/202777/keyboard-layout][openclipart.org]] and is under the public +domain. The bepo logo and the keymap images are coming from the [[http://bepo.fr/][bepo]] official +website. They are licensed under the [[http://creativecommons.org/licenses/by-sa/3.0/deed.en][CC-BY-SA]]. diff --git a/layers/+intl/keyboard-layout/config.el b/layers/+intl/keyboard-layout/config.el new file mode 100644 index 0000000..c2be535 --- /dev/null +++ b/layers/+intl/keyboard-layout/config.el @@ -0,0 +1,75 @@ +;;; config.el --- keyboard-layout Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Fabien Dubosson +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;;------------------------------------------------------------------------------ +;; PUBLIC VARIABLES +;;------------------------------------------------------------------------------ + +(defvar kl-layout 'dvorak + "The keyboard-layout to use. Possible values are `dvorak' and `bepo'.") + +(defvar kl-enabled-configurations nil + "If non nil, `keyboard-layout' will enable configurations only +for the passed list of symbols. Configurations that are also in +`kl-disabled-configurations' will not be loaded.") + +(defvar kl-disabled-configurations nil + "If non nil, `keyboard-layout' will disable configurations for +the passed list of symbols. This list takes priority over +`kl-enabled-configurations', so they will not be loaded in +any case.") + +;;------------------------------------------------------------------------------ +;; PRIVATE VARIABLES +;;------------------------------------------------------------------------------ + +(defvar kl--base-rebinding-maps + '((bepo . (("c" . "h") + ("t" . "j") + ("s" . "k") + ("r" . "l") + ;; + ("h" . "r") + ("j" . "t") + ("k" . "s") + ("l" . "c"))) + (dvorak . (("h" . "h") + ("t" . "j") + ("n" . "k") + ("s" . "l") + ;; + ("h" . "h") + ("j" . "t") + ("k" . "n") + ("l" . "s")))) + "The base rebinding map. Dots should be read as `will behave + as'. It should be a bidirectional mapping, i.e. all present + keys should be once in each column.") + +(defvar kl--rebinding-maps + (mapcar (lambda (map) `(,(car map) . ,(kl//generate-full-rebinding-map (cdr map)))) + kl--base-rebinding-maps) + "The full rebinding map. Dots should be read as `will behave as'.") + +(with-eval-after-load 'evil + (defvar kl--all-evil-states + (list evil-normal-state-map + evil-visual-state-map + evil-insert-state-map + evil-emacs-state-map + evil-motion-state-map) + "The list of all evil states.") + + (defvar kl--all-evil-states-but-insert + (list evil-normal-state-map + evil-visual-state-map + evil-motion-state-map) + "The list of all evil states except insert.")) diff --git a/layers/+intl/keyboard-layout/funcs.el b/layers/+intl/keyboard-layout/funcs.el new file mode 100644 index 0000000..7928801 --- /dev/null +++ b/layers/+intl/keyboard-layout/funcs.el @@ -0,0 +1,206 @@ +;;; funcs.el --- keyboard-layout Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Fabien Dubosson +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Map multiple states at once. Courtesy of Michael Markert; +;; http://permalink.gmane.org/gmane.emacs.vim-emulation/1674 + +;;------------------------------------------------------------------------------ +;; PRIVATE FUNCTIONS +;;------------------------------------------------------------------------------ + +(defun kl//generate-full-rebinding-map (basemap) + "Generate the full rebinding map from a base map." + (mapcan (lambda (binding) + (let ((key1 (car binding)) + (key2 (cdr binding))) + (append + (list (cons (upcase key1) (upcase key2)) + (cons key1 key2)) + (mapcar + (lambda (modifier) + (cons (concat modifier key1) (concat modifier key2))) + '("" "C-" "M-" "C-S-"))))) + basemap)) + +(defun kl//define-key (maps key def bindings) + "Define a list of KEYS to their associated DEFINITIONS in all +the given MAPS." + (declare (indent 1)) + (while key + ;; Define the key + (dolist (map maps) + (define-key map (kbd key) def)) + ;; Get next keybinding + (setq key (pop bindings) + def (pop bindings)))) + +(defun kl//remap-key-as (map bindings) + "Define keys to the associated definitions of other ones. All +remapping are done atomically, i.e. if `a' -> `b' and `c' -> `a', +then `c' will be defined to the old `a' function, not to `b'." + (declare (indent 1)) + (let ((map-original (copy-tree map))) + (dolist (binding bindings) + (let ((key1 (kbd (car binding))) + (key2 (kbd (cdr binding)))) + (define-key map key1 (lookup-key map-original key2)))))) + +(defun kl//replace-in-list-rec (lst elem repl) + "Replace recursively all occurrences of `elem' by `repl' in the +list `lst'." + (declare (indent 0)) + (if (typep lst 'list) + (let* ((body-position (cl-position elem lst))) + (if body-position + ;; The element is in the list, replace it + (progn + (setf (nth body-position lst) repl) + lst) + ;; The element is not in the list, recurse + (dolist (l lst) + (kl//replace-in-list-rec l elem repl)))))) + +(defun kl//guess-rebindings (key) + "Tries to guess the rebindings needed to correct the given +key." + (let* ((key1 key) + (prefix nil) + (rebinding-map (cdr (assoc kl-layout kl--rebinding-maps)))) + ;; If key not existing as-is in the kl--rebinding-maps, try on last letter. + (when (not (assoc key1 rebinding-map)) + (setq key1 (substring key -1)) + (setq prefix (substring key 0 -1))) + (let* ((key2 (cdr (assoc key1 rebinding-map))) + (bind1 (assoc key1 rebinding-map)) + (bind2 (assoc key2 rebinding-map))) + (when prefix + (defun kl//guess-prefixit (bind) + `(,(concat prefix (car bind)) . ,(concat prefix (cdr bind)))) + (setq bind1 (kl//guess-prefixit bind1)) + (setq bind2 (kl//guess-prefixit bind2))) + `(,bind1 ,bind2)))) + +;;------------------------------------------------------------------------------ +;; HELPER FUNCTIONS +;;------------------------------------------------------------------------------ + +(defun kl/set-in-state (map key def &rest bindings) + "Define a list of keys with their associated functions in a +given state map." + (declare (indent 1)) + (kl//define-key (list map) key def bindings)) + +(defun kl/set-in-states (maps key def &rest bindings) + "Define a list of keys with their associated functions in all +given state maps." + (declare (indent 1)) + (kl//define-key maps key def bindings)) + +(defun kl/set-in-all-evil-states (key def &rest bindings) + "Define a list of keys with their associated functions in all +evil states." + (declare (indent 0)) + (kl//define-key kl--all-evil-states key def bindings)) + +(defun kl/set-in-all-evil-states-but-insert (key def &rest bindings) + "Define a list of keys with their associated functions in all +evil states, except insert." + (declare (indent 0)) + (kl//define-key kl--all-evil-states-but-insert key def bindings)) + +(defun kl/leader-alias-of (key1 key2) + "Define a leader key as an alias of another one." + (spacemacs/set-leader-keys key1 (lookup-key spacemacs-default-map key2))) + +(defun kl/leader-swap-keys (key1 key2) + "Invert the behaviour of two leader keys." + (let ((map1 (lookup-key spacemacs-default-map key1)) + (map2 (lookup-key spacemacs-default-map key2))) + (spacemacs/set-leader-keys key1 map2 key2 map1))) + +;;------------------------------------------------------------------------------ +;; CORRECTION FUNCTIONS +;;------------------------------------------------------------------------------ + +(defun kl/correct-keys (map &rest keys) + (declare (indent 1)) + (let ((bindings (mapcan #'kl//guess-rebindings keys))) + (kl//remap-key-as map (remove-if #'null bindings)))) + +(defun kl/evil-correct-keys (state map &rest keys) + (declare (indent 2)) + (apply #'kl/correct-keys (evil-get-auxiliary-keymap map state) keys)) + +(defun kl/leader-correct-keys (&rest keys) + (declare (indent 0)) + (apply #'kl/correct-keys spacemacs-default-map keys)) + +;;------------------------------------------------------------------------------ +;; MAIN MACRO +;;------------------------------------------------------------------------------ + +(defmacro kl|config (name &rest props) + "Macro used for structuring `keyboard-layout' configuration changes. + +Usage: + + (kl|config configuration-name + [:keyword option]...) + +:disable Boolean, whether the configuration is disabled or not. +:description String, documents what the configuration does. +:functions Code, functions definitions. +:loader Code, used to load the configuration. Must contains `BODY' + where the real configuration must be placed. +:config Code, the configuration code. +:special Code executed as-is at the end, without being wrapped inside + the `:loader'. + +All keywords are optional, except for `:config'. + +These configurations can be overridden by the user using a +`kl/pre-config-' or `kl/post-config-' +function (taking no argument). These functions will be called just +before or after the keyboard-layout's configurations." + (declare (indent 1)) + (let* ((disable (plist-get props :disable)) + (description (plist-get props :description)) + (functions (plist-get props :functions)) + (loader (plist-get props :loader)) + (common (plist-get props :common)) + (specific (plist-get props (intern (format ":%s" kl-layout)))) + (special (plist-get props :special)) + (preconf (intern (format "kl/pre-config-%s" name))) + (postconf (intern (format "kl/post-config-%s" name))) + (body `(progn + (when (fboundp ',preconf) (funcall ',preconf)) + ,common + ,specific + (when (fboundp ',postconf) (funcall ',postconf)) + ))) + ;; Use loader if defined + (when loader + (kl//replace-in-list-rec loader 'BODY body) + (setq body loader)) + ;; If the configuration is not disabled + (when (not disable) + ;; If the configuration is not in disabled-list + (when (not (member name kl-disabled-configurations)) + ;; If the package is in enabled-list, if any. + (when (or (not kl-enabled-configurations) (member name kl-enabled-configurations)) + (when init-file-debug + (message (format "[kl] Configuration enabled: '%s'" name))) + `(progn + ,functions + ,body + ,special + ,description + )))))) diff --git a/layers/+intl/keyboard-layout/img/bepo-keymap.png b/layers/+intl/keyboard-layout/img/bepo-keymap.png new file mode 100644 index 0000000..5f9d75a Binary files /dev/null and b/layers/+intl/keyboard-layout/img/bepo-keymap.png differ diff --git a/layers/+intl/keyboard-layout/img/bepo-logo.png b/layers/+intl/keyboard-layout/img/bepo-logo.png new file mode 100644 index 0000000..dac4544 Binary files /dev/null and b/layers/+intl/keyboard-layout/img/bepo-logo.png differ diff --git a/layers/+intl/keyboard-layout/img/dvorak-keymap.png b/layers/+intl/keyboard-layout/img/dvorak-keymap.png new file mode 100644 index 0000000..7be078b Binary files /dev/null and b/layers/+intl/keyboard-layout/img/dvorak-keymap.png differ diff --git a/layers/+intl/keyboard-layout/img/keyboard-layout.png b/layers/+intl/keyboard-layout/img/keyboard-layout.png new file mode 100644 index 0000000..4aea959 Binary files /dev/null and b/layers/+intl/keyboard-layout/img/keyboard-layout.png differ diff --git a/layers/+intl/keyboard-layout/packages.el b/layers/+intl/keyboard-layout/packages.el new file mode 100644 index 0000000..5708ff3 --- /dev/null +++ b/layers/+intl/keyboard-layout/packages.el @@ -0,0 +1,485 @@ +;;; config.el --- keyboard-layout Layer Packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Fabien Dubosson +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defconst keyboard-layout-packages + '( + ace-window + avy + comint + company + elfeed + evil + evil-escape + evil-evilified-state + evil-surround + eyebrowse + flycheck + helm + imenu-list + ivy + magit + mu4e + neotree + org + org-agenda + ranger + twittering-mode + )) + +(defun keyboard-layout/pre-init-ace-window () + (kl|config ace-window + :description + "Change `ace-window' keys to the central row." + :loader + (spacemacs|use-package-add-hook ace-window :post-init BODY) + :bepo + (setq aw-keys '(?a ?u ?i ?e ?t ?s ?r ?n)) + :dvorak + (setq aw-keys '(?a ?o ?e ?u ?h ?t ?n ?s)))) + +(defun keyboard-layout/pre-init-avy () + (kl|config avy + :description + "Change `avy' keys to the central row." + :loader + (spacemacs|use-package-add-hook avy :post-init BODY) + :bepo + (setq-default avy-keys '(?a ?u ?i ?e ?t ?s ?r ?n)) + :dvorak + (setq-default avy-keys '(?a ?o ?e ?u ?h ?t ?n ?s)))) + +(defun keyboard-layout/pre-init-comint () + (kl|config comint-mode + :description + "Remap `comint' bindings." + :loader + (with-eval-after-load 'shell BODY) + :common + (dolist (m '(normal insert)) + (eval `(kl/evil-correct-keys `,m comint-mode-map + "C-j" + "C-k"))))) + +(defun keyboard-layout/pre-init-company () + (kl|config company + :description + "Remap `company' bindings." + :loader + (spacemacs|use-package-add-hook company :post-config BODY) + :common + (kl/correct-keys company-active-map + "C-h" + "C-j" + "C-k" + "C-l"))) + +(defun keyboard-layout/pre-init-elfeed () + (kl|config elfeed + :description + "Remap `elfeed' bindings." + :loader + (spacemacs|use-package-add-hook elfeed :post-config BODY) + :common + (progn + (kl/evil-correct-keys 'evilified elfeed-search-mode-map + "j" + "k") + (kl/evil-correct-keys 'evilified elfeed-show-mode-map + "j" + "k" + "C-j" + "C-k")) + :bepo + ;; HACK: The auto correction doesn't work... mystery. + (evil-define-key 'evilified elfeed-search-mode-map + "k" 'elfeed-search-live-filter))) + +(defun keyboard-layout/pre-init-evil () + (kl|config evil + :description + "Remap `evil' bindings." + :loader + (with-eval-after-load 'evil BODY) + :common + (dolist (map kl--all-evil-states-but-insert) + (kl/correct-keys map + "h" + "j" + "k" + "l" + ;; + "H" + "J" + "K" + "L")) + :bepo + (progn + (kl/set-in-all-evil-states-but-insert + "é" 'evil-forward-word-begin + "É" 'evil-forward-WORD-begin) + (kl/set-in-state evil-inner-text-objects-map + "é" 'evil-inner-word + "É" 'evil-inner-WORD) + (kl/set-in-state evil-outer-text-objects-map + "é" 'evil-a-word + "É" 'evil-a-WORD) + (kl/set-in-all-evil-states-but-insert + "«" 'evil-shift-left + "»" 'evil-shift-right)) + :dvorak + ;; Invert it twice to reset `k' and `K' for searching + (dolist (map kl--all-evil-states-but-insert) + (kl/correct-keys map + "K"))) + + (kl|config evil-window + :description + "Remap `evil-window' bindings." + :loader + (with-eval-after-load 'evil-commands BODY) + :common + ;; FIXME: Not working + (kl/leader-correct-keys + "wh" + "wj" + "wk" + "wl" + ;; + "wH" + "wJ" + "wK" + "wL") + :bepo + (progn + (spacemacs/set-leader-keys + "wé" 'other-window + "wq" 'delete-window) + (kl/leader-alias-of "é" "w")))) + +(defun keyboard-layout/pre-init-evil-escape () + (kl|config evil-escape + :description + "Change `evil-escape' default escape combination for a better one than `fd'." + :loader + (spacemacs|use-package-add-hook evil-escape :post-init BODY) + :bepo + (setq-default evil-escape-key-sequence "gq"))) + +(defun keyboard-layout/pre-init-evil-evilified-state () + (kl|config evil-evilified-state + :description + "Remap `evil-evilified-state' bindings." + :loader + (with-eval-after-load 'evil-evilified-state BODY) + :common + (kl/correct-keys evil-evilified-state-map + "h" + "j" + "k" + "l"))) + +(defun keyboard-layout/pre-init-evil-surround () + (kl|config evil-surround + :description + "Remap `evil-surround' bindings." + :loader + (spacemacs|use-package-add-hook evil-surround :post-init BODY) + :common + (kl/evil-correct-keys 'visual evil-surround-mode-map "s"))) + +(defun keyboard-layout/pre-init-eyebrowse () + (kl|config eyebrowse + :description + "Remap `eyebrowse' keybindings conflicting with evil." + :loader + (spacemacs|use-package-add-hook eyebrowse :post-init BODY) + :common + (kl/correct-keys evil-motion-state-map "gj")) + + (kl|config eyebrowse + :description + "Remap `eyebrowse' keybindings conflicting with evil-commands." + :loader + (with-eval-after-load 'evil-commands BODY) + :common + (kl/correct-keys evil-motion-state-map "gJ"))) + +(defun keyboard-layout/pre-init-flycheck () + (kl|config flycheck-error-list + :description + "Remap `flycheck-error-list' bindings." + :loader + (spacemacs|use-package-add-hook flycheck :post-init BODY) + :common + (kl/evil-correct-keys 'evilified flycheck-error-list-mode-map + "j" + "k"))) + +(defun keyboard-layout/pre-init-helm () + (kl|config helm + :description + "Remap `helm' bindings." + :loader + (spacemacs|use-package-add-hook helm :post-config BODY) + :common + (kl/correct-keys helm-map + "C-h" + "C-j" + "C-k" + "C-l")) + + (kl|config helm-buffers + :description + "Remap `helm-buffers' bindings." + :loader + (with-eval-after-load 'helm-buffers BODY) + :bepo + ;; HACK: Forced to correct wrong behaviour + (kl/set-in-state helm-buffer-map "C-s" 'helm-previous-line)) + + (kl|config helm-files + :description + "Remap `helm-files' bindings." + :loader + (with-eval-after-load 'helm-files BODY) + :bepo + (progn + ;; HACK: Forced to correct wrong behaviour + (kl/set-in-state helm-find-files-map "C-s" 'helm-previous-line) + (kl/set-in-state helm-find-files-map "C-k" 'helm-ff-run-grep) + (kl/set-in-state helm-find-files-map "C-r" 'helm-maybe-exit-minibuffer) + (kl/set-in-state helm-read-file-map "C-s" 'helm-previous-line) + (kl/set-in-state helm-read-file-map "C-K" 'helm-previous-line))) + + (kl|config helm-locate + :description + "Remap `helm-locate' bindings." + :loader + (with-eval-after-load 'helm-locate BODY) + :bepo + (progn + ;; HACK: Forced to correct wrong behaviour + (kl/set-in-state helm-generic-files-map "C-s" 'helm-previous-line) + (kl/set-in-state helm-generic-files-map "C-k" 'helm-ff-run-grep)) + :bepo + (progn + ;; HACK: Forced to correct wrong behaviour + (kl/set-in-state helm-generic-files-map "C-n" 'helm-previous-line) + (kl/set-in-state helm-generic-files-map "C-k" 'helm-ff-run-grep)))) + +(defun keyboard-layout/pre-init-imenu-list () + (kl|config imenu-list + :description + "Remap `imenu-list' bindings." + :loader + (spacemacs|use-package-add-hook imenu-list :post-config BODY) + :common + (kl/evil-correct-keys 'evilified imenu-list-major-mode-map + "j" + "k"))) + +(defun keyboard-layout/pre-init-ivy () + (kl|config ivy + :description + "Remap `ivy' bindings." + :loader + (spacemacs|use-package-add-hook ivy :post-config BODY) + :common + (progn + (kl/correct-keys ivy-minibuffer-map + "C-h" + "C-j" + "C-k" + "C-l")))) + +(defun keyboard-layout/pre-init-magit () + (kl|config magit + :description + "Remap `magit' bindings." + :loader + (spacemacs|use-package-add-hook magit :post-config BODY) + :common + (progn + (kl/evil-correct-keys evil-magit-state magit-mode-map + "j" + "k" + "C-j" + "C-k") + (kl/evil-correct-keys 'normal evil-magit-toggle-text-minor-mode-map + "C-j") + (dolist (map (list magit-branch-section-map + magit-commit-section-map + magit-file-section-map + magit-hunk-section-map + magit-remote-section-map + magit-staged-section-map + magit-unstaged-section-map + magit-module-commit-section-map + magit-stash-section-map + magit-stashes-section-map + magit-tag-section-map + magit-unpulled-section-map + magit-unpushed-section-map + magit-untracked-section-map)) + (kl/correct-keys map + "j" + "k" + "C-j" + "C-k"))) + :bepo + (progn + (magit-change-popup-key 'magit-dispatch-popup :actions ?t ?j) + (magit-change-popup-key 'magit-dispatch-popup :actions ?s ?k) + (magit-change-popup-key 'magit-dispatch-popup :actions ?S ?K)))) + +(defun keyboard-layout/pre-init-mu4e () + (kl|config mu4e + :description + "Remap navigation keys in `mu4e' headers and view mode." + :loader + (spacemacs|use-package-add-hook mu4e :post-config BODY) + :common + (dolist (map (list mu4e-headers-mode-map + mu4e-view-mode-map)) + (kl/evil-correct-keys 'evilified map + "h" + "j" + "k" + "l" + "C-j" + "C-k")) + :bepo + (dolist (map (list mu4e-headers-mode-map + mu4e-view-mode-map)) + (evil-define-key 'evilified map + "è" 'mu4e-headers-mark-subthread + "/" 'mu4e-headers-search)))) + +(defun keyboard-layout/pre-init-neotree () + (kl|config neotree + :descripition + "Remap `neotree' bindings." + :loader + (spacemacs|use-package-add-hook neotree :post-config BODY) + :common + (kl/evil-correct-keys 'evilified neotree-mode-map + "h" + "j" + "k" + "l" + ;; + "H" + "J" + "K" + "L") + :bepo + (kl/set-in-state (evil-get-auxiliary-keymap neotree-mode-map 'evilified) + "h" 'neotree-hidden-file-toggle + "k" 'neotree-rename-node))) + +(defun keyboard-layout/pre-init-org () + (kl|config org + :description + "Remap keys in `org-mode'." + :loader + (with-eval-after-load 'org BODY) + :bepo + (progn + (evil-define-key 'normal evil-org-mode-map + "t" 'evil-next-line + "j" 'org-todo) + (dolist (m '(normal insert)) + (eval `(evil-define-key ',m evil-org-mode-map + ;; ctsr + (kbd "M-c") 'org-metaleft + (kbd "M-t") 'org-metadown + (kbd "M-s") 'org-metaup + (kbd "M-r") 'org-metaright + (kbd "M-C") 'org-shiftmetaleft + (kbd "M-T") 'org-shiftmetadown + (kbd "M-S") 'org-shiftmetaup + (kbd "M-R") 'org-shiftmetaright + ;; hjkl + (kbd "M-h") 'capitalize-word + (kbd "M-j") 'transpose-chars + (kbd "M-k") 'kill-sentence + (kbd "M-l") 'move-to-window-line-top-bottom + (kbd "M-H") 'capitalize-word + (kbd "M-J") 'transpose-chars + (kbd "M-K") 'kill-sentence + (kbd "M-L") 'move-to-window-line-top-bottom))) + (spacemacs/set-leader-keys-for-major-mode 'org-mode + ;; ctsr + "C-S-c" 'org-shiftcontrolleft + "C-S-t" 'org-shiftcontroldown + "C-S-s" 'org-shiftcontrolup + "C-S-r" 'org-shiftcontrolright + ;; hjkl + "C-S-h" nil + "C-S-j" nil + "C-S-k" nil + "C-S-l" nil) + (evil-define-key 'normal evil-org-mode-map + ;; ctsr + "gt" 'org-forward-heading-same-level + "gs" 'org-backward-heading-same-level + ;; hjkl + "gj" nil + "gk" nil + ;; additional + (kbd "«") 'org-metaleft + (kbd "»") 'org-metaright)))) + +(defun keyboard-layout/pre-init-org-agenda () + (kl|config org-agenda + :description + "Remap `org-agenda' bindings." + :loader + (spacemacs|use-package-add-hook org-agenda :post-config BODY) + :common + (kl/evil-correct-keys 'evilified org-agenda-mode-map + "j" + "k" + "M-h" + "M-j" + "M-k" + "M-l"))) + +(defun keyboard-layout/pre-init-ranger () + (kl|config ranger + :description + "Remap navigation keys in `ranger'." + :loader + (spacemacs|use-package-add-hook ranger :post-config BODY) + :common + (kl/correct-keys ranger-mode-map + "h" + "j" + "k" + "l"))) + +(defun kl/pre-init-twittering-mode () + (kl|config twittering-mode + :description + "Remap navigation keys in `twittering-mode'." + :loader + (spacemacs|use-package-add-hook twittering-mode :post-init BODY) + :config + (kl/correct-keys twittering-mode-map + "h" + "j" + "k" + "l" + ;; + "H" + "J" + "K" + "L"))) diff --git a/layers/+lang/agda/README.org b/layers/+lang/agda/README.org new file mode 100644 index 0000000..4e54814 --- /dev/null +++ b/layers/+lang/agda/README.org @@ -0,0 +1,80 @@ +#+TITLE: Agda layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#some-features][Some features:]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#agda][Agda]] + - [[#key-bindings][Key bindings]] + +* Description +This layer adds support for the [[http://wiki.portal.chalmers.se/agda/pmwiki.php][Agda]] programming language. + +** Some features: +- Faces redefined to correctly play with themes. +- Spacemacs bindings to Agda's interactive tools. + +*This layer is in construction, it needs your contributions and bug reports.* + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =agda= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Agda +Quick instructions to install Agda assuming you have cabal installed: + +#+BEGIN_SRC sh + cabal install alex happy "cpphs < 1.19" agda +#+END_SRC + +Then check that =agda= is available on your =$PATH= and seen by Emacs. For +information about setting up =$PATH=, check out the corresponding section in the +FAQ (~SPC h SPC $PATH RET~). + +By default the =agda-mode= executable bundled with most agda installations is +used to locate the agda-mode package. If you don't have it and want to use a +local agda-mode package, you can customize the layer variable =agda-mode-path= +to your needs. Set it to =nil= if =agda2.el= is already discoverable in Emacs’ +load path, otherwise set it to the path at which =agda2.el= can be found. For +example, + +#+BEGIN_SRC emacs-lisp + (agda2 :variables agda-mode-path "/some/path/to/agda2.el") +#+END_SRC + +* Key bindings +The key bindings of this layer don't follow the Spacemacs conventions, +we opted to a simple transcription of stock Agda mode key bindings to +Spacemacs leader key. + +All Agda specific bindings are prefixed with the major-mode leader +~SPC m~. + +| Key Binding | Description | +|-------------+-------------------------------------------------------------------------------------------------------------------------------------------| +| ~SPC m =~ | Show constraints. | +| ~SPC m ?~ | Show all goals. | +| ~SPC m ​,​~ | Shows the type of the goal at point and the currect context. | +| ~SPC m .~ | Shows the context, the goal and the given expression's inferred type. | +| ~SPC m a~ | Simple proof search. | +| ~SPC m b~ | Go to the previous goal, if any and activate goal-navigation transient-state. | +| ~SPC m c~ | Refine the pattern variables given in the goal. | +| ~SPC m d~ | Infers the type of the given expression. | +| ~SPC m e~ | Show the context of the goal at point. | +| ~SPC m f~ | Go to the next goal, if any and activate goal-navigation transient-state. | +| ~SPC m h~ | Compute the type of a hypothetical helper function. | +| ~SPC m l~ | Load current buffer. | +| ~SPC m n~ | Computes the normal form of the given expression, using the scope of the current goal or, if point is not in a goal, the top-level scope. | +| ~SPC m p~ | Shows all the top-level names in the given module. | +| ~SPC m r~ | Refine the goal at point. | +| ~SPC m s~ | Solves all goals that are already instantiated internally. | +| ~SPC m t~ | Show the type of the goal at point. | +| ~SPC m x c~ | Compile current module. | +| ~SPC m x d~ | Removes buffer annotations (overlays and text properties). | +| ~SPC m x h~ | Toggle display of implicit arguments. | +| ~SPC m x q~ | Quit and clean up after agda2. | +| ~SPC m x r~ | Kill and restart the *agda2* buffer and load =agda2-toplevel-module=. | +| ~SPC m w~ | Explains why a given name is in scope. | diff --git a/layers/+lang/agda/config.el b/layers/+lang/agda/config.el new file mode 100644 index 0000000..6e0ab3d --- /dev/null +++ b/layers/+lang/agda/config.el @@ -0,0 +1,19 @@ +;;; config.el --- Agda2 Layer config File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: FreeSalad +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar agda-mode-path 'use-helper + "Indicates the location of the agda-mode package (the file +`agda2.el') If `nil', it is assumed to be already available by +Emacs. If `use-helper', the `agda-mode' executable is used to +find its location.") + +(spacemacs|define-jump-handlers agda2-mode agda2-goto-definition-keyboard) +(spacemacs|defvar-company-backends agda2-mode) diff --git a/layers/+lang/agda/packages.el b/layers/+lang/agda/packages.el new file mode 100644 index 0000000..5f26af3 --- /dev/null +++ b/layers/+lang/agda/packages.el @@ -0,0 +1,90 @@ +;;; packages.el --- Agda2 Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Oliver Charles +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq agda-packages + '((agda :location local) + company + golden-ratio)) + +(defun agda/post-init-company () + (spacemacs|add-company-hook agda2-mode) + (push 'company-capf company-backends-agda2-mode)) + +(defun agda/init-agda () + (if (and (eq 'use-helper agda-mode-path) + (not (executable-find "agda-mode"))) + (spacemacs-buffer/warning + (concat "Couldn't find `agda-mode', make sure it is " + "available in your PATH or check the installation " + "instructions in the README file.")) + + (when (eq 'use-helper agda-mode-path) + (setq agda-mode-path (let ((coding-system-for-read 'utf-8)) + (shell-command-to-string "agda-mode locate")))) + + (use-package agda2-mode + :defer t + :init (when agda-mode-path (load-file agda-mode-path)) + (progn + (mapc + (lambda (x) (add-to-list 'face-remapping-alist x)) + '((agda2-highlight-datatype-face . font-lock-type-face) + (agda2-highlight-function-face . font-lock-type-face) + (agda2-highlight-inductive-constructor-face . font-lock-function-name-face) + (agda2-highlight-keyword-face . font-lock-keyword-face) + (agda2-highlight-module-face . font-lock-constant-face) + (agda2-highlight-number-face . nil) + (agda2-highlight-postulate-face . font-lock-type-face) + (agda2-highlight-primitive-type-face . font-lock-type-face) + (agda2-highlight-record-face . font-lock-type-face)))) + :config + (progn + (spacemacs|define-transient-state goal-navigation + :title "Goal Navigation Transient State" + :doc "\n[_f_] next [_b_] previous [_q_] quit" + :bindings + ("f" agda2-next-goal) + ("b" agda2-previous-goal) + ("q" nil :exit t)) + (spacemacs/set-leader-keys-for-major-mode 'agda2-mode + "f" 'spacemacs/goal-navigation-transient-state/agda2-next-goal + "b" 'spacemacs/goal-navigation-transient-state/agda2-previous-goal) + + (spacemacs/set-leader-keys-for-major-mode 'agda2-mode + "?" 'agda2-show-goals + "." 'agda2-goal-and-context-and-inferred + "," 'agda2-goal-and-context + "=" 'agda2-show-constraints + "SPC" 'agda2-give + "a" 'agda2-auto + "c" 'agda2-make-case + "d" 'agda2-infer-type-maybe-toplevel + "e" 'agda2-show-context + "gG" 'agda2-go-back + "h" 'agda2-helper-function-type + "l" 'agda2-load + "n" 'agda2-compute-normalised-maybe-toplevel + "p" 'agda2-module-contents-maybe-toplevel + "r" 'agda2-refine + "s" 'agda2-solveAll + "t" 'agda2-goal-type + "w" 'agda2-why-in-scope-maybe-toplevel + "xc" 'agda2-compile + "xd" 'agda2-remove-annotations + "xh" 'agda2-display-implicit-arguments + "xq" 'agda2-quit + "xr" 'agda2-restart))))) + +(defun idris/pre-init-golden-ratio () + (spacemacs|use-package-add-hook golden-ratio + :post-config + (add-to-list 'golden-ratio-exclude-buffer-names + "*Agda information*"))) diff --git a/layers/+lang/asciidoc/README.org b/layers/+lang/asciidoc/README.org new file mode 100644 index 0000000..f2b6116 --- /dev/null +++ b/layers/+lang/asciidoc/README.org @@ -0,0 +1,45 @@ +#+TITLE: Asciidoc layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#feature][Feature]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + - [[#element-insertion][Element insertion]] + - [[#promotion-demotion][Promotion, Demotion]] + +* Description +This layer adds [[https://asciidoctor.org][AsciiDoc]] markup language support to Spacemacs. + +** Feature +- asciidoc format support via [[https://github.com/sensorflo/adoc-mode][adoc-mode]] +- =.adoc= files are associated with =adoc-mode= by default + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =asciidoc= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key bindings +** Element insertion + +| Key Binding | Description | +|-------------+-----------------------------------------------| +| ~SPC m h 1~ | Insert title level 1 | +| ~SPC m h I~ | Insert title level 1 (the most important one) | +| ~SPC m h 2~ | Insert title level 2 | +| ~SPC m h i~ | Insert title level 2 (the most usual one) | +| ~SPC m h 3~ | Insert title level 3 | +| ~SPC m h 4~ | Insert title level 4 | +| ~SPC m h 5~ | Insert title level 5 | +| ~SPC m h 5~ | Insert title level 5 | +| ~SPC m x b~ | Boldface selected | +| ~SPC m x i~ | Italicize selected | + +** Promotion, Demotion + +| Key Binding | Description | +|-------------+---------------------| +| ~M-h~ | Promote title level | +| ~M-l~ | Demote title level | + diff --git a/layers/+lang/asciidoc/packages.el b/layers/+lang/asciidoc/packages.el new file mode 100644 index 0000000..390f6f5 --- /dev/null +++ b/layers/+lang/asciidoc/packages.el @@ -0,0 +1,46 @@ +;;; packages.el --- Asciidoc Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Mark Safronov +;; Author: Torben Hoffmann +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq asciidoc-packages '(adoc-mode)) + +(defun asciidoc/init-adoc-mode () + (use-package adoc-mode + ;; We will NOT default `.txt' files to AsciiDoc mode, + ;; and `.asciidoc' extension is just plain stupid. + :mode (("\\.adoc?\\'" . adoc-mode)) + :defer t + :config + (progn + ;; We have quite a lot of possible keybindings. + ;; See `adoc-mode.el', its bottom part where the huge easy-menu + ;; is defined and after that, where the various `tempo-template-*' + ;; functions are defined. + + ;; See /doc/CONVENTIONS.md#plain-text-markup-languages + (spacemacs/set-leader-keys-for-major-mode 'adoc-mode + "h1" 'tempo-template-adoc-title-1 + ;; Alternative method of inserting top-level heading + "hI" 'tempo-template-adoc-title-1 + "h2" 'tempo-template-adoc-title-2 + ;; Alternative method of inserting the most usual heading + "hi" 'tempo-template-adoc-title-2 + "h3" 'tempo-template-adoc-title-3 + "h4" 'tempo-template-adoc-title-4 + "h5" 'tempo-template-adoc-title-5 + "xb" 'tempo-template-adoc-strong + "xi" 'tempo-template-adoc-emphasis) + ;; yes, exactly like that. To "promote" title is to INCREASE its size. + ;; `adoc-demote' does the opposite: increases its LEVEL, + ;; which DECREASES its size. + (define-key adoc-mode-map (kbd "M-h") 'adoc-demote) + ;; see the comment about adoc-demote above + (define-key adoc-mode-map (kbd "M-l") 'adoc-promote)))) diff --git a/layers/+lang/asm/README.org b/layers/+lang/asm/README.org new file mode 100644 index 0000000..54642ea --- /dev/null +++ b/layers/+lang/asm/README.org @@ -0,0 +1,76 @@ +#+TITLE: asm layer + +[[file:img/asm.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#pdfs][PDFs]] + - [[#key-bindings][Key bindings]] + +* Description +This layer adds support for Assembly code. The built-in major mode for +editing assembly code in Emacs is =asm-mode=. + +The layer also adds =nasm-mode= for NASM-specific syntax. Although =nasm-mode= +is intended for NASM, it actually works well with other variants of Assembly +in general, and provides Imenu integration so you can jump around with ~SPC s j~. + +_Features_: +- Improved syntax highlighting. +- Automatic indentation. +- Auto-completion for symbol in opened buffers. +- Look up documentation for current instruction at cursor. +- Imenu integration. + +* Install +*** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =asm= to the existing =dotspacemacs-configuration-layers= list in this +file. + +*** PDFs +To look up the x86 instructions, two things are required: + +- the =pdftotext= command line tool from Poppler: + +#+begin_src sh + sudo apt-get install poppler-utils +#+end_src + +- [[http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html][Intel® 64 and IA-32 Architectures Software Developer Manuals]]. Any PDF that + contains the full instruction set reference will work, though volume 2 is the + best choice for x86-lookup. + +Then, set =x86-lookup-pdf= to the location of your PDF document (Tip: If you use +Helm as your completion of choice, you can use ~SPC f f~ to navigate to the +file, and press ~C-c i~ to insert the path). For example, something like this: + +#+begin_src emacs-lisp + (setq x86-lookup-pdf "~/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf") +#+end_src + +The first time you launch the command, it can take a while for indexing, this +is a one time operation and the result is cached for later use. + +* Key bindings + +| Key Binding | Description | +|-------------+----------------------------------------------------| +| ~SPC m h h~ | Look up the documentation for instruction at point | +| ~;~ | Insert a comment | + +_Note_: Quoted from the docstring of =asm-comment=, the command bound to ~;~: + +#+begin_src text +Convert an empty comment to a `larger' kind, or start a new one. +These are the known comment classes: + + 1 -- comment to the right of the code (at the comment-column) + 2 -- comment on its own line, indented like code + 3 -- comment on its own line, beginning at the left-most column. + +Suggested usage: while writing your code, trigger asm-comment +repeatedly until you are satisfied with the kind of comment. +#+end_src diff --git a/layers/+lang/asm/config.el b/layers/+lang/asm/config.el new file mode 100644 index 0000000..ed2f59f --- /dev/null +++ b/layers/+lang/asm/config.el @@ -0,0 +1,16 @@ +;;; config.el --- Asm Layer config File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Tu, Do Hoang +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; variables +(spacemacs|defvar-company-backends asm-mode) +(spacemacs|defvar-company-backends nasm-mode) + +(spacemacs|define-jump-handlers asm-mode) diff --git a/layers/+lang/asm/funcs.el b/layers/+lang/asm/funcs.el new file mode 100644 index 0000000..cbcba6a --- /dev/null +++ b/layers/+lang/asm/funcs.el @@ -0,0 +1,40 @@ +;;; funcs.el --- Asm Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Tu, Do Hoang +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun asm-generic-setup () + (setq indent-tabs-mode nil) ; use spaces to indent + (setq tab-stop-list (number-sequence 2 60 2))) ; 2 spaces per tab + +(defun asm-electric-indent-local-mode-off () + (electric-indent-local-mode -1)) + +;; when we press ':' character, it runs `asm-colon' command in asm-mode. +;; The command automatically removes the indentation ofcurrent line, since +;; every non-whitespace character before a colon is a label in asm and +;; label has to be at the beginning of a line. However, the problem is +;; that when deleting indentation, trailing spaces are left between the +;; colon and the original point the colon was inserted. +;; +;; These functions solve that problem. First, check whether we have any +;; space or tab after point. If so, don't do anything becuase the spaces are +;; there intentionally. If not, we delete all trailing spaces between +;; point and colon. +(defvar asm-colon-has-space nil) +(defun asm-colon-check-space () + (setq asm-colon-has-space nil) + (when (and (not (null (char-after))) + (member (string (char-after)) '(" " "\t"))) + (setq asm-colon-has-space t))) +(defun asm-colon-delete-spaces () + (unless asm-colon-has-space + (call-interactively 'delete-horizontal-space))) +(advice-add 'asm-colon :before 'asm-colon-check-space) +(advice-add 'asm-colon :after 'asm-colon-delete-spaces) diff --git a/layers/+lang/asm/img/asm.png b/layers/+lang/asm/img/asm.png new file mode 100644 index 0000000..ece69d6 Binary files /dev/null and b/layers/+lang/asm/img/asm.png differ diff --git a/layers/+lang/asm/packages.el b/layers/+lang/asm/packages.el new file mode 100644 index 0000000..b378985 --- /dev/null +++ b/layers/+lang/asm/packages.el @@ -0,0 +1,71 @@ +;;; packages.el --- Asm Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Tu, Do Hoang +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq asm-packages + '( + ;; package names go here + asm-mode + electric-indent-mode + ggtags + helm-gtags + nasm-mode + x86-lookup + )) + +(defun asm/init-asm-mode () + (use-package asm-mode + :init + (spacemacs/set-leader-keys-for-major-mode 'asm-mode "h" 'x86-lookup) + :config + (progn + ;; We need to insert a non-indented line, otherwise it's annoying + ;; everytime we insert a comment for a routine + (define-key asm-mode-map (kbd "C-j") 'newline) + (add-hook 'asm-mode-hook #'asm-generic-setup)))) + +(defun asm/post-init-electric-indent-mode () + (spacemacs/add-to-hooks 'asm-electric-indent-local-mode-off + '(asm-mode-hook nasm-mode-hook))) + +(defun asm/init-nasm-mode () + "Setup for built-in `nasm-mode', which could be thought as improved `asm-mode'" + (use-package nasm-mode + :init + (progn + (add-hook 'nasm-mode-hook #'asm-generic-setup) + (add-to-list 'auto-mode-alist '("\\.[n]*\\(asm\\|s\\)\\'" . nasm-mode)) + (spacemacs/set-leader-keys-for-major-mode 'nasm-mode "h" 'x86-lookup)) + :config + (progn + ;; We need to insert a non-indented line, otherwise it's annoying + ;; everytime we insert a comment for a routine + (define-key nasm-mode-map (kbd "C-j") 'newline) + ;; we use the advised `asm-colon' because `nasm-colon indents the whole line, even + ;; inside a comment + (define-key nasm-mode-map (kbd ":") 'asm-colon)))) + +(defun asm/init-x86-lookup () + (use-package x86-lookup + :init + (progn + ;; when a user installed `pdf-tools', use it for viewing PDF document. + (when (package-installed-p 'pdf-tools) + (setq x86-lookup-browse-pdf-function 'x86-lookup-browse-pdf-pdf-tools))))) + +(defun asm/post-init-company () + (spacemacs|add-company-hook asm-mode) + (spacemacs|add-company-hook nasm-mode)) + +(defun asm/post-init-ggtags () + (add-hook 'asm-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun asm/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'asm-mode)) diff --git a/layers/+lang/autohotkey/README.org b/layers/+lang/autohotkey/README.org new file mode 100644 index 0000000..0e8b34d --- /dev/null +++ b/layers/+lang/autohotkey/README.org @@ -0,0 +1,43 @@ +#+TITLE: Autohotkey layer + +[[file:img/ahk.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#install][Install]] + - [[#key-bindings][Key Bindings]] + +* Description + +Syntax highlighting and Emacs functions for use with [[http://www.autohotkey.com][AutoHotkey]] or +[[http://ahkscript.org][AutoHotkey_L]]. + +Using a combined implementation of ahk-mode from Xah Lee's =xahk-mode= +and Robert Widhopf-Fenk's =autohotkey-mode=. Updated with the latest +ahk and ahk_l commands found in the latest revision of +[[http://fincs.ahk4.net/scite4ahk/][SciTE4AutoHotkey]]. + +Contributed and maintained by [[https://www.github.com/ralesi][Rich Alesi]]. + +* Features + +- Auto-completion +- Documentation Lookup +- Execute Code Snippets +- Correct Indentation and Commenting + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =autohotkey= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key Bindings + +| Key Binding | Description | +|-------------+------------------------------------| +| ~SPC m c b~ | block comment | +| ~SPC m c c~ | line comment | +| ~SPC m e b~ | execute file with =autohotkey.exe= | +| ~SPC m h h~ | open documentation in =browser= | +| ~SPC m h H~ | open documentation in local =chm= | diff --git a/layers/+lang/autohotkey/img/ahk.png b/layers/+lang/autohotkey/img/ahk.png new file mode 100644 index 0000000..d50e776 Binary files /dev/null and b/layers/+lang/autohotkey/img/ahk.png differ diff --git a/layers/+lang/autohotkey/packages.el b/layers/+lang/autohotkey/packages.el new file mode 100644 index 0000000..3392377 --- /dev/null +++ b/layers/+lang/autohotkey/packages.el @@ -0,0 +1,26 @@ +;;; packages.el --- autohotkey Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; Author: Rich Alesi +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq autohotkey-packages + '(ahk-mode)) + +(defun autohotkey/init-ahk-mode () + (use-package ahk-mode + :mode "\\.ahk\\'" + :defer t + :init + (spacemacs/set-leader-keys-for-major-mode 'ahk-mode + "cb" 'ahk-comment-block-dwim + "cc" 'ahk-comment-dwim + "eb" 'ahk-run-script + "hh" 'ahk-lookup-web + "hH" 'ahk-lookup-chm))) diff --git a/layers/+lang/bibtex/README.org b/layers/+lang/bibtex/README.org new file mode 100644 index 0000000..8f84683 --- /dev/null +++ b/layers/+lang/bibtex/README.org @@ -0,0 +1,80 @@ +#+TITLE: BibTeX layer + +[[file:img/logo.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#configuration][Configuration]] + - [[#key-bindings][Key bindings]] + +* Description +BibTeX and BibLaTeX files are a common way to manage bibliographies. The format +was original designed to work with LaTeX files and subsequently has been adopted +by other markup formats such as MarkDown and Org mode. + +This layer adds support to manipulate BibTeX and BibLaTeX files and offer +utilities to automatically add new entries by DOI, arXiv identifier, ISBN, and +more. + +Once enabled, this layer also introduces additional shortcuts in other modes to +easily insert citations. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =bibtex= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Configuration +This layer also supports having a global BibTeX file. For a basic +configuration, add this to your =~/.spacemacs= inside +=dotspacemacs/user-config=: + +#+begin_src emacs-lisp + (setq org-ref-default-bibliography '("~/Papers/references.bib") + org-ref-pdf-directory "~/Papers/" + org-ref-bibliography-notes "~/Papers/notes.org") +#+end_src + +Certain modes, such as =latex-mode= with AucTeX, will automatically lookup +references in a document if any of the recognized bibliography commands are +used. Other modes may have a similar feature, or one could always set +file-local variables (through ~SPC f v f~). + +You can also customize which program is used to display the PDFs. For example, +to use Zathura: + +#+begin_src emacs-lisp + (setq org-ref-open-pdf-function + (lambda (fpath) + (start-process "zathura" "*helm-bibtex-zathura*" "/usr/bin/zathura" fpath))) +#+end_src + +More configuration options are available and are detailed in the =org-ref= and +=helm-bibtex= package documentations. + +* Key bindings +In a Bib(La)TeX file, the following key bindings are added: + +| Key Binding | Description | +|---------------------------+--------------------------------------------| +| ~SPC m j~ / ~g j~ / ~C-j~ | Next entry | +| ~SPC m k~ / ~g k~ / ~C-k~ | Previous entry | +| ~SPC m p~ | Open PDF | +| ~SPC m n~ | Open notes | +| ~SPC m b~ | Open browser | +| ~SPC m i~ | Insert new entry | +| ~SPC m s~ | Sort entry | +| ~SPC m h~ | Various actions on entry | +| ~SPC m l a~ | Lookup and add arXiv paper (don't get PDF) | +| ~SPC m l A~ | Lookup and add arXiv paper (download PDF) | +| ~SPC m l d~ | Lookup and add paper by DOI | +| ~SPC m l i~ | Lookup and add book by ISBN | +| ~SPC m l p~ | Lookup and add paper by PMID | + +In addition, =org-mode=, =latex-mode= and =markdown-mode= all have the following +key binding added: + +| Key Binding | Description | +|-------------+-----------------| +| ~SPC m i c~ | Insert citation | diff --git a/layers/+lang/bibtex/img/logo.png b/layers/+lang/bibtex/img/logo.png new file mode 100644 index 0000000..fac271b Binary files /dev/null and b/layers/+lang/bibtex/img/logo.png differ diff --git a/layers/+lang/bibtex/packages.el b/layers/+lang/bibtex/packages.el new file mode 100644 index 0000000..867fc59 --- /dev/null +++ b/layers/+lang/bibtex/packages.el @@ -0,0 +1,87 @@ +;;; packages.el --- BibTeX Layer packages file for Spacemacs. +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Joshua Ellis +;; URL: https://github.com/JP-Ellis +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defconst bibtex-packages + '( + auctex + org + org-ref + markdown-mode + helm-bibtex + biblio + biblio-core + )) + +(defun bibtex/post-init-auctex () + (spacemacs/set-leader-keys-for-major-mode 'latex-mode + "ic" 'org-ref-helm-insert-cite-link)) + +(defun bibtex/post-init-org () + (spacemacs/set-leader-keys-for-major-mode 'org-mode + "ic" 'org-ref-helm-insert-cite-link)) + +(defun bibtex/init-org-ref () + (use-package org-ref + :defer t + :commands (org-ref-bibtex-next-entry + org-ref-bibtex-previous-entry + org-ref-open-in-browser + org-ref-open-bibtex-notes + org-ref-open-bibtex-pdf + org-ref-bibtex-hydra/body + org-ref-bibtex-hydra/org-ref-bibtex-new-entry/body-and-exit + org-ref-sort-bibtex-entry + arxiv-add-bibtex-entry + arxiv-get-pdf-add-bibtex-entry + doi-utils-add-bibtex-entry-from-doi + isbn-to-bibtex + pubmed-insert-bibtex-from-pmid) + :init + (progn + (evil-define-key 'normal bibtex-mode-map + (kbd "C-j") 'org-ref-bibtex-next-entry + (kbd "C-k") 'org-ref-bibtex-previous-entry + "gj" 'org-ref-bibtex-next-entry + "gk" 'org-ref-bibtex-previous-entry) + + (spacemacs/set-leader-keys-for-major-mode 'bibtex-mode + ;; Navigation + "j" 'org-ref-bibtex-next-entry + "k" 'org-ref-bibtex-previous-entry + + ;; Open + "b" 'org-ref-open-in-browser + "n" 'org-ref-open-bibtex-notes + "p" 'org-ref-open-bibtex-pdf + + ;; Misc + "h" 'org-ref-bibtex-hydra/body + "i" 'org-ref-bibtex-hydra/org-ref-bibtex-new-entry/body-and-exit + "s" 'org-ref-sort-bibtex-entry + + ;; Lookup utilities + "la" 'arxiv-add-bibtex-entry + "lA" 'arxiv-get-pdf-add-bibtex-entry + "ld" 'doi-utils-add-bibtex-entry-from-doi + "li" 'isbn-to-bibtex + "lp" 'pubmed-insert-bibtex-from-pmid)))) + +(defun bibtex/post-init-org-ref () + (add-hook 'org-mode-hook (lambda () (require 'org-ref)))) + +(defun bibtex/post-init-markdown-mode () + (spacemacs/set-leader-keys-for-major-mode 'markdown-mode + "ic" 'org-ref-helm-insert-cite-link)) + +(defun bibtex/init-helm-bibtex ()) +(defun bibtex/init-biblio ()) +(defun bibtex/init-biblio-core ()) + diff --git a/layers/+lang/c-c++/README.org b/layers/+lang/c-c++/README.org new file mode 100644 index 0000000..1510679 --- /dev/null +++ b/layers/+lang/c-c++/README.org @@ -0,0 +1,106 @@ +#+TITLE: C/C++ layer + +[[file:img/ccpp.jpg]] +[[file:img/cmake.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#default-mode-for-header-files][Default mode for header files]] + - [[#enable-clang-support][Enable Clang support]] + - [[#clang-format][clang-format]] + - [[#company-clang-and-flycheck][Company-clang and flycheck]] + - [[#key-bindings][Key Bindings]] + +* Description +This layer adds configuration for C/C++ language as well support for [[http://www.cmake.org/][CMake]] +scripts. + +* Features +- Support syntax checking via flycheck with Clang. +- Support for disassembly of code with [[https://github.com/jart/disaster][disaster]]. +- Support code reformatting with [[http://clang.llvm.org/docs/ClangFormat.html][clang-format]]. +- Display function or variable definition at the bottom. (when =semantic= layer + is included) +- Display current function cursor is in at the top. See [[https://github.com/tuhdo/semantic-stickyfunc-enhance][stickyfunc-demos]] for + demos in some programming languages. (when =semantic= layer is included) +- Support common refactoring with [[https://github.com/tuhdo/semantic-refactor][semantic-refactor]] . See [[https://github.com/tuhdo/semantic-refactor/blob/master/srefactor-demos/demos.org][srefactor-demos]] for + demonstration of refactoring features. (when =semantic= layer is included) +- Support code navigation via cscope (when =cscope= layer is included) and gtags. +- Support auto-completion (when =auto-completion= layer is included) via + company-clang (when =c-c++-enable-clang-support= is turned on), or + company-ycmd (when =ycmd= layer is included). + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =c-c++= to the existing =dotspacemacs-configuration-layers= list in this +file. + +*Note:* [[https://github.com/tuhdo/semantic-refactor][semantic-refactor]] is only available for Emacs 24.4+ + +** Default mode for header files +By default header files are opened in =c-mode=, you can open them in =c++-mode= +by setting the variable =c-c++-default-mode-for-headers= to =c++-mode=. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers + '((c-c++ :variables + c-c++-default-mode-for-headers 'c++-mode))) +#+END_SRC + +*Note:* To set the variable for a given project, create a directory local +variable at the root of your project. More info on directory local variables +can be found in the [[http://www.gnu.org/software/emacs/manual/html_node/elisp/Directory-Local-Variables.html][dir-locals]]. + +** Enable Clang support +To enable Clang support set the layer variable =c-c++-enable-clang-support= +to =t= in the dotfile: + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers + '((c-c++ :variables c-c++-enable-clang-support t))) +#+END_SRC + +*** clang-format +[[http://clang.llvm.org/docs/ClangFormat.html][clang-format]] allows reformatting either a selected region of code +(=clang-format-region=) or a whole buffer (=clang-format-buffer=) to make it +conform to a style defined in a =.clang-format= file. This file is either +located in the same directory as the file being edited, or in any of its parent +directories (otherwise a default style will be used). + +You can add snippets similar to the following to bind clang-format to either a +particular mode or all modes in your =dotspacemacs/user-config= (within your +=~/.spacemacs=): + +#+BEGIN_SRC emacs-lisp + ;; Bind clang-format-region to C-M-tab in all modes: + (global-set-key [C-M-tab] 'clang-format-region) + ;; Bind clang-format-buffer to tab on the c++-mode only: + (add-hook 'c++-mode-hook 'clang-format-bindings) + (defun clang-format-bindings () + (define-key c++-mode-map [tab] 'clang-format-buffer)) +#+END_SRC + +*** Company-clang and flycheck +This layer adds some fancy improvements to =company-clang=. +It includes a hook to load a projects =.clang_complete= file, which is +just a text file with one clang flag per line, a format also used by +other text editor clang plugins. + +Not only does this allow proper autocomplete on projects with extra +includes and flags, but there is also support for flycheck so that it +doesn't complain about missing header files. + +* Key Bindings + +| Key Binding | Description | +|-------------+------------------------------------------------------------------------| +| ~SPC m g a~ | open matching file (e.g. switch between .cpp and .h) | +| ~SPC m g A~ | open matching file in another window (e.g. switch between .cpp and .h) | +| ~SPC m D~ | disaster: disassemble c/c++ code | +| ~SPC m r~ | srefactor: refactor thing at point. | + +*Note:* [[https://github.com/tuhdo/semantic-refactor][semantic-refactor]] is only available for Emacs 24.4+ diff --git a/layers/+lang/c-c++/config.el b/layers/+lang/c-c++/config.el new file mode 100644 index 0000000..cec7c97 --- /dev/null +++ b/layers/+lang/c-c++/config.el @@ -0,0 +1,24 @@ +;;; config.el --- C/C++ Layer config File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; variables + +(defvar c-c++-enable-clang-support nil + "If non nil Clang related packages and configuration are enabled.") + +(spacemacs|defvar-company-backends c-mode-common) +(spacemacs|defvar-company-backends cmake-mode) + +(spacemacs|define-jump-handlers c++-mode) +(spacemacs|define-jump-handlers c-mode) + +(defvar c-c++-default-mode-for-headers 'c-mode + "Default mode to open header files. Can be `c-mode' or `c++-mode'.") diff --git a/layers/+lang/c-c++/funcs.el b/layers/+lang/c-c++/funcs.el new file mode 100644 index 0000000..62149d9 --- /dev/null +++ b/layers/+lang/c-c++/funcs.el @@ -0,0 +1,52 @@ +;;; funcs.el --- C/C++ Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Based on the Sarcasm/irony-mode compilation database code. +(defun company-mode/find-clang-complete-file () + (when buffer-file-name + (let ((dir (locate-dominating-file buffer-file-name ".clang_complete"))) + (when dir + (concat (file-name-as-directory dir) ".clang_complete"))))) + +;; Based on the Sarcasm/irony-mode compilation database code. +(defun company-mode/load-clang-complete-file (cc-file) + "Load the flags from CC-FILE, one flag per line." + (let ((invocation-dir (expand-file-name (file-name-directory cc-file))) + (case-fold-search nil) + compile-flags) + (with-temp-buffer + (insert-file-contents cc-file) + ;; Replace relative paths with absolute paths (by @trishume) + ;; (goto-char (point-min)) + (while (re-search-forward "\\(-I\\|-isystem\n\\)\\(\\S-+\\)" nil t) + (replace-match (format "%s%s" (match-string 1) + (expand-file-name (match-string 2) invocation-dir)))) + ;; Turn lines into a list + (setq compile-flags + ;; remove whitespaces at the end of each line, if any + (mapcar #'(lambda (line) + (if (string-match "[ \t]+$" line) + (replace-match "" t t line) + line)) + (split-string (buffer-string) "\n" t)))) + compile-flags)) + +(defun c-c++/load-clang-args () + "Sets the arguments for company-clang, the system paths for company-c-headers +and the arguments for flyckeck-clang based on a project-specific text file." + (unless company-clang-arguments + (let* ((cc-file (company-mode/find-clang-complete-file)) + (flags (if cc-file (company-mode/load-clang-complete-file cc-file) '())) + (dirs (mapcar (lambda (f) (substring f 2)) + (remove-if-not (lambda (f) (string-prefix-p "-I" f)) flags)))) + (setq-local company-clang-arguments flags) + (setq-local company-c-headers-path-system (append '("/usr/include" "/usr/local/include") dirs)) + (setq-local flycheck-clang-args flags)))) diff --git a/layers/+lang/c-c++/img/ccpp.jpg b/layers/+lang/c-c++/img/ccpp.jpg new file mode 100644 index 0000000..0a39aa9 Binary files /dev/null and b/layers/+lang/c-c++/img/ccpp.jpg differ diff --git a/layers/+lang/c-c++/img/cmake.png b/layers/+lang/c-c++/img/cmake.png new file mode 100644 index 0000000..c9baf13 Binary files /dev/null and b/layers/+lang/c-c++/img/cmake.png differ diff --git a/layers/+lang/c-c++/packages.el b/layers/+lang/c-c++/packages.el new file mode 100644 index 0000000..e6ffffc --- /dev/null +++ b/layers/+lang/c-c++/packages.el @@ -0,0 +1,147 @@ +;;; packages.el --- C/C++ Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq c-c++-packages + '( + cc-mode + disaster + clang-format + cmake-mode + company + (company-c-headers :toggle (configuration-layer/package-usedp 'company)) + company-ycmd + flycheck + gdb-mi + ggtags + helm-cscope + helm-gtags + semantic + srefactor + stickyfunc-enhance + ycmd + xcscope + )) + +(defun c-c++/init-cc-mode () + (use-package cc-mode + :defer t + :init + (progn + (add-to-list 'auto-mode-alist + `("\\.h\\'" . ,c-c++-default-mode-for-headers))) + :config + (progn + (require 'compile) + (c-toggle-auto-newline 1) + (spacemacs/set-leader-keys-for-major-mode 'c-mode + "ga" 'projectile-find-other-file + "gA" 'projectile-find-other-file-other-window) + (spacemacs/set-leader-keys-for-major-mode 'c++-mode + "ga" 'projectile-find-other-file + "gA" 'projectile-find-other-file-other-window)))) + +(defun c-c++/init-disaster () + (use-package disaster + :defer t + :commands (disaster) + :init + (progn + (spacemacs/set-leader-keys-for-major-mode 'c-mode + "D" 'disaster) + (spacemacs/set-leader-keys-for-major-mode 'c++-mode + "D" 'disaster)))) + +(defun c-c++/init-clang-format () + (use-package clang-format + :if c-c++-enable-clang-support)) + +(defun c-c++/init-cmake-mode () + (use-package cmake-mode + :mode (("CMakeLists\\.txt\\'" . cmake-mode) ("\\.cmake\\'" . cmake-mode)) + :init (push 'company-cmake company-backends-cmake-mode))) + +(defun c-c++/post-init-company () + (spacemacs|add-company-hook c-mode-common) + (spacemacs|add-company-hook cmake-mode) + + (when c-c++-enable-clang-support + (push 'company-clang company-backends-c-mode-common) + + (defun company-mode/more-than-prefix-guesser () + (c-c++/load-clang-args) + (company-clang-guess-prefix)) + + (setq company-clang-prefix-guesser 'company-mode/more-than-prefix-guesser) + (spacemacs/add-to-hooks 'c-c++/load-clang-args '(c-mode-hook c++-mode-hook)))) + +(defun c-c++/init-company-c-headers () + (use-package company-c-headers + :defer t + :init (push 'company-c-headers company-backends-c-mode-common))) + +(defun c-c++/post-init-flycheck () + (dolist (mode '(c-mode c++-mode)) + (spacemacs/add-flycheck-hook mode)) + (when c-c++-enable-clang-support + (spacemacs/add-to-hooks 'c-c++/load-clang-args '(c-mode-hook c++-mode-hook)))) + +(defun c-c++/post-init-ggtags () + (add-hook 'c-mode-local-vars-hook #'spacemacs/ggtags-mode-enable) + (add-hook 'c++-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun c-c++/init-gdb-mi () + (use-package gdb-mi + :defer t + :init + (setq + ;; use gdb-many-windows by default when `M-x gdb' + gdb-many-windows t + ;; Non-nil means display source file containing the main routine at startup + gdb-show-main t))) + +(defun c-c++/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'c-mode) + (spacemacs/helm-gtags-define-keys-for-mode 'c++-mode)) + +(defun c-c++/post-init-semantic () + (spacemacs/add-to-hooks 'semantic-mode '(c-mode-hook c++-mode-hook))) + +(defun c-c++/post-init-srefactor () + (spacemacs/set-leader-keys-for-major-mode 'c-mode "r" 'srefactor-refactor-at-point) + (spacemacs/set-leader-keys-for-major-mode 'c++-mode "r" 'srefactor-refactor-at-point) + (spacemacs/add-to-hooks 'spacemacs/lazy-load-srefactor '(c-mode-hook c++-mode-hook))) + +(defun c-c++/post-init-stickyfunc-enhance () + (spacemacs/add-to-hooks 'spacemacs/lazy-load-stickyfunc-enhance '(c-mode-hook c++-mode-hook))) + +(defun c-c++/post-init-ycmd () + (add-hook 'c++-mode-hook 'ycmd-mode) + (add-hook 'c-mode-hook 'ycmd-mode) + (add-to-list 'spacemacs-jump-handlers-c++-mode '(ycmd-goto :async t)) + (add-to-list 'spacemacs-jump-handlers-c-mode '(ycmd-goto :async t)) + (dolist (mode '(c++-mode c-mode)) + (spacemacs/set-leader-keys-for-major-mode mode + "gG" 'ycmd-goto-imprecise))) + +(defun c-c++/post-init-company-ycmd () + (push 'company-ycmd company-backends-c-mode-common)) + +(defun c-c++/pre-init-xcscope () + (spacemacs|use-package-add-hook xcscope + :post-init + (dolist (mode '(c-mode c++-mode)) + (spacemacs/set-leader-keys-for-major-mode mode "gi" 'cscope-index-files)))) + +(defun c-c++/pre-init-helm-cscope () + (spacemacs|use-package-add-hook xcscope + :post-init + (dolist (mode '(c-mode c++-mode)) + (spacemacs/setup-helm-cscope mode)))) diff --git a/layers/+lang/clojure/README.org b/layers/+lang/clojure/README.org new file mode 100644 index 0000000..f36f124 --- /dev/null +++ b/layers/+lang/clojure/README.org @@ -0,0 +1,315 @@ +#+TITLE: Clojure layer + +[[file:img/clojure.png]] [[file:img/cider.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#pretty-symbols][Pretty Symbols]] + - [[#cider-and-clj-refactor][CIDER and clj-refactor]] + - [[#quick-start-with-boot][Quick Start with boot]] + - [[#quick-start-with-lein][Quick Start with lein]] + - [[#more-details][More details]] + - [[#key-bindings][Key Bindings]] + - [[#working-with-clojure-files-barfage-slurpage--more][Working with clojure files (barfage, slurpage & more)]] + - [[#leader][Leader]] + - [[#documentation][Documentation]] + - [[#evaluation][Evaluation]] + - [[#goto][Goto]] + - [[#repl][REPL]] + - [[#tests][Tests]] + - [[#toggles][Toggles]] + - [[#debugging][Debugging]] + - [[#refactoring][Refactoring]] + - [[#reformatting][Reformatting]] + - [[#cider-buffers][CIDER Buffers]] + - [[#stacktrace-mode][stacktrace-mode]] + - [[#inspector-mode][inspector-mode]] + - [[#test-report-mode][test-report-mode]] + - [[#development-notes][Development Notes]] + - [[#indentation][Indentation]] + +* Description +This layer adds support for [[http://clojure.org][Clojure]] language using [[https://github.com/clojure-emacs/cider][CIDER]]. + +* Features +- REPL via [[https://github.com/clojure-emacs/cider][CIDER]] +- Code formatting via [[https://github.com/clojure-emacs/cider][CIDER]] using [[https://github.com/weavejester/cljfmt][Cljfmt]] +- Refactoring via [[https://github.com/clojure-emacs/clj-refactor.el][clj-refactor]] +- Aligning of code forms via [[https://github.com/clojure-emacs/clojure-mode][clojure-mode]] + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =clojure= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Pretty Symbols +Pretty symbols for anonymous functions, set literals and partial, like =(λ [a] +(+ a 5))=, =ƒ(+ % 5)=, =∈{2 4 6}= and =Ƥ=. + +To enable this feature, add the following snippet to the +=dotspacemacs/user-config= section of your =~/.spacemacs= file: + +#+BEGIN_SRC emacs-lisp + (setq clojure-enable-fancify-symbols t) +#+END_SRC + +Or set this variable when loading the configuration layer: +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers + '((clojure :variables clojure-enable-fancify-symbols t))) +#+END_SRC + +** CIDER and clj-refactor +Note that recent versions of CIDER automatically inject the required +dependencies into your boot or leiningen configuration when you connect to the +REPL. Thus, the configuration instructions below only apply to CIDER 0.10 and +older. Most users should be able to just run ~SPC m s i~ to connect to the CIDER +REPL and skip the rest of this section. + +*** Quick Start with boot +- Install =boot= (see https://github.com/boot-clj/boot#install) +- Create a file =~/.boot/profile.boot= with the following content: + +#+BEGIN_SRC clojure +(require 'boot.repl) + +(swap! boot.repl/*default-dependencies* conj + '[refactor-nrepl "1.2.0-SNAPSHOT"] + '[cider/cider-nrepl "0.10.0-SNAPSHOT"]) + +(swap! boot.repl/*default-middleware* conj + 'refactor-nrepl.middleware/wrap-refactor) +#+END_SRC + +- Run ~SPC m s i~ in any of the clojure source files to connect to the CIDER + REPL. Note that a build.boot file must be present in your working directory + for Cider to recognize the presence of boot. + +*** Quick Start with lein +- Install =lein= version 2.5.2 or newer (see http://leiningen.org/#install) +- Create a file =~/.lein/profiles.clj= with the following content: + +#+BEGIN_SRC clojure + {:repl {:plugins [[cider/cider-nrepl "0.10.0-SNAPSHOT"] + [refactor-nrepl "2.0.0-SNAPSHOT"]] + :dependencies [[alembic "0.3.2"] + [org.clojure/tools.nrepl "0.2.12"]]}} +#+END_SRC + +- After creating your project with ~lein new app ~ or + importing an existing project, run ~SPC m s i~ in any of the clojure + source files to connect to the CIDER REPL. + +*** More details +More info regarding installation of nREPL middleware can be found here: +- CIDER: [[https://github.com/clojure-emacs/cider#installation][cider_install]] +- clj-refactor: [[https://github.com/clojure-emacs/refactor-nrepl][refactor-nrepl]] + +* Key Bindings +** Working with clojure files (barfage, slurpage & more) +Spacemacs comes with a special ~lisp-state~ for working with lisp code that +supports slurpage, barfage and more tools you'll likely want when working with +lisp. + +As this state works the same for all files, the documentation is in global +[[https://github.com/syl20bnr/spacemacs/blob/master/doc/DOCUMENTATION.org#lisp-key-bindings][DOCUMENTATION.org]]. In general, use ~SPC k~ to interact with the lisp-state. + +** Leader +*** Documentation + +| Key Binding | Description | +|-------------+-----------------| +| ~SPC m h a~ | cider apropos | +| ~SPC m h g~ | cider grimoire | +| ~SPC m h h~ | cider doc | +| ~SPC m h j~ | cider javadoc | +| ~SPC m h n~ | cider browse ns | + +*** Evaluation + +| Key Binding | Description | +|-------------+-------------------------------------------------| +| ~SPC m e b~ | eval buffer | +| ~SPC m e e~ | eval last sexp | +| ~SPC m e f~ | eval function at point | +| ~SPC m e r~ | eval region | +| ~SPC m e m~ | cider macroexpand 1 | +| ~SPC m e M~ | cider macroexpand all | +| ~SPC m e p~ | print last sexp (clojure interaction mode only) | +| ~SPC m e w~ | eval last sexp and replace with result | + +*** Goto + +| Key Binding | Description | +|-------------+-----------------------| +| ~SPC m g b~ | go back | +| ~SPC m g C~ | browse classpath | +| ~SPC m g g~ | goto var | +| ~SPC m g e~ | goto error | +| ~SPC m g r~ | goto resource | +| ~SPC m g n~ | browse namespaces | +| ~SPC m g N~ | browse all namespaces | + +*** REPL + +| Key Binding | Description | +|-------------+--------------------------------------------------------------------------------| +| ~SPC m ,~ | handle shortcut (cider-repl-handle-shortcut) | +| ~SPC m s b~ | send and eval buffer in REPL | +| ~SPC m s B~ | send and eval buffer and switch to REPL in =insert state= | +| ~SPC m s c~ | connect to REPL (cider-connect) or clear repl buffer (cider-repl-clear-buffer) | +| ~SPC m s C~ | clear REPL (cider-find-and-clear-repl-output) | +| ~SPC m s e~ | send and eval last sexp in REPL | +| ~SPC m s E~ | send and eval last sexp and switch to REPL in =insert state= | +| ~SPC m s f~ | send and eval function in REPL | +| ~SPC m s F~ | send and eval function and switch to REPL in =insert state= | +| ~SPC m s i~ | start REPL (cider-jack-in) | +| ~SPC m s I~ | start clojurescript REPL (cider-jack-in-clojurescript) | +| ~SPC m s n~ | send and eval ns form in REPL | +| ~SPC m s N~ | send and eval ns form and switch to REPL in =insert state= | +| ~SPC m s q~ | kill REPL (cider-quit) | +| ~SPC m s o~ | switch to other repl instance (cider-repl-switch-to-other) | +| ~SPC m s r~ | send and eval region in REPL | +| ~SPC m s R~ | send and eval region and switch to REPL in =insert state= | +| ~SPC m s s~ | switch to REPL or jump to last file or last clj buffer from repl (cider-repl) | + +*** Tests + +| Key Binding | Description | +|-------------+------------------------------------| +| ~SPC m t a~ | run all tests in namespace | +| ~SPC m t r~ | re-run test failures for namespace | +| ~SPC m t t~ | run test at point | + +*** Toggles + +| Key Binding | Description | +|-------------+-----------------------------| +| ~SPC m T e~ | toggle englighten mode | +| ~SPC m T f~ | toggle REPL font-locking | +| ~SPC m T e~ | toggle cider-enlighten-mode | +| ~SPC m T p~ | toggle REPL pretty-printing | +| ~SPC m T i~ | toggle indentation style | +| ~SPC m T t~ | toggle auto test mode | + +*** Debugging + +| Key Binding | Description | +|-------------+--------------------------------| +| ~SPC m d r~ | reload namepspaces | +| ~SPC m d b~ | instrument expression at point | +| ~SPC m d e~ | display last stacktrace | +| ~SPC m d i~ | inspect expression at point | + +*** Refactoring + +| Key Binding | Description | +|---------------+-----------------------------| +| ~SPC m r ?~ | describe refactoring | +| ~SPC m r a d~ | add declaration | +| ~SPC m r a i~ | add import to ns | +| ~SPC m r a m~ | add missing libspec | +| ~SPC m r a p~ | add project dependency | +| ~SPC m r a r~ | add require to ns | +| ~SPC m r a u~ | add use to ns | +| ~SPC m r c c~ | cycle coll | +| ~SPC m r c i~ | cycle if | +| ~SPC m r c n~ | clean ns | +| ~SPC m r c p~ | cycle privacy | +| ~SPC m r d k~ | destructure keys | +| ~SPC m r e c~ | extract constant | +| ~SPC m r e d~ | extract definition | +| ~SPC m r e f~ | extract function | +| ~SPC m r e l~ | expand let | +| ~SPC m r f u~ | find usages | +| ~SPC m r f e~ | create fn from example | +| ~SPC m r h d~ | hotload dependency | +| ~SPC m r i l~ | introduce let | +| ~SPC m r i s~ | inline symbol | +| ~SPC m r m f~ | move form | +| ~SPC m r m l~ | move to let | +| ~SPC m r p c~ | project clean | +| ~SPC m r p f~ | promote function | +| ~SPC m r r d~ | remove debug fns | +| ~SPC m r r f~ | rename file | +| ~SPC m r r l~ | remove let | +| ~SPC m r r r~ | remove unused requires | +| ~SPC m r r s~ | rename symbol | +| ~SPC m r r u~ | replace use | +| ~SPC m r s n~ | sort ns | +| ~SPC m r s p~ | sort project dependencies | +| ~SPC m r s r~ | stop referring | +| ~SPC m r s c~ | show changelog | +| ~SPC m r t f~ | thread first all | +| ~SPC m r t h~ | thread | +| ~SPC m r t l~ | thread last all | +| ~SPC m r u a~ | unwind all | +| ~SPC m r u p~ | update project dependencies | +| ~SPC m r u w~ | unwind | + +*** Reformatting + +| Key Binding | Description | +|---------------------------+-------------------------| +| ~SPC m f l~ | realign current form | +| ~SPC m f b~ or ~SPC m =~ | reformat current buffer | + +** CIDER Buffers +In general, ~q~ should always quit the popped up buffer. + +*** stacktrace-mode + +| Key Binding | Description | +|-------------+---------------------| +| ~C-j~ | next cause | +| ~C-k~ | previous cause | +| ~TAB~ | cycle current cause | +| ~0~ | cycle all causes | +| ~1~ | cycle cause 1 | +| ~2~ | cycle cause 2 | +| ~3~ | cycle cause 3 | +| ~4~ | cycle cause 4 | +| ~5~ | cycle cause 5 | +| ~a~ | toggle all | +| ~c~ | toggle clj | +| ~d~ | toggle duplicates | +| ~J~ | toggle java | +| ~r~ | toggle repl | +| ~T~ | toggle tooling | + +*** inspector-mode + +| Key Binding | Description | +|-------------+---------------------------------| +| ~TAB~ | next inspectable object | +| ~Shift-TAB~ | previous inspectable object | +| ~RET~ | inspect object | +| ~L~ | pop to the parent object | +| ~n~ | next page in paginated view | +| ~N~ | previous page in paginated view | +| ~r~ | refresh | +| ~s~ | set a new page size | + +*** test-report-mode + +| Key Binding | Description | +|-------------+-------------------| +| ~C-j~ | next result | +| ~C-k~ | previous result | +| ~RET~ | jump to test | +| ~d~ | ediff test result | +| ~e~ | show stacktrace | +| ~r~ | rerun tests | +| ~t~ | run test | +| ~T~ | run tests | + +* Development Notes +** Indentation +With a [[https://github.com/clojure-emacs/cider/blob/master/doc/Indent-Spec.md#indent-specification][new]] functionality of Cider to read the custom indentation rules from the +var's metadata, it is better for consistency reasons to not add the custom +indentation rules to Spacemacs, but to add them to the metadata of those +specific vars. diff --git a/layers/+lang/clojure/config.el b/layers/+lang/clojure/config.el new file mode 100644 index 0000000..86a5564 --- /dev/null +++ b/layers/+lang/clojure/config.el @@ -0,0 +1,28 @@ +;;; config.el --- Clojure Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; --------------------------------------------------------------------------- +;; Prefixes +;; --------------------------------------------------------------------------- + +;; Variables + +(spacemacs|defvar-company-backends cider-mode) +(spacemacs|defvar-company-backends cider-repl-mode) + +(spacemacs|define-jump-handlers clojure-mode) +(spacemacs|define-jump-handlers clojurec-mode) +(spacemacs|define-jump-handlers clojurescript-mode) +(spacemacs|define-jump-handlers clojurex-mode) +(spacemacs|define-jump-handlers cider-repl-mode) + +(defvar clojure-enable-fancify-symbols nil + "If non nil the `fancify-symbols' function is enabled.") diff --git a/layers/+lang/clojure/funcs.el b/layers/+lang/clojure/funcs.el new file mode 100644 index 0000000..8759827 --- /dev/null +++ b/layers/+lang/clojure/funcs.el @@ -0,0 +1,172 @@ +;;; funcs.el --- Clojure Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun clojure/fancify-symbols (mode) + "Pretty symbols for Clojure's anonymous functions and sets, + like (λ [a] (+ a 5)), ƒ(+ % 5), and ∈{2 4 6}." + (font-lock-add-keywords mode + `(("(\\(fn\\)[\[[:space:]]" + (0 (progn (compose-region (match-beginning 1) + (match-end 1) "λ")))) + ("(\\(partial\\)[\[[:space:]]" + (0 (progn (compose-region (match-beginning 1) + (match-end 1) "Ƥ")))) + ("(\\(comp\\)[\[[:space:]]" + (0 (progn (compose-region (match-beginning 1) + (match-end 1) "∘")))) + ("\\(#\\)(" + (0 (progn (compose-region (match-beginning 1) + (match-end 1) "ƒ")))) + ("\\(#\\){" + (0 (progn (compose-region (match-beginning 1) + (match-end 1) "∈"))))))) + +(defun spacemacs//cider-eval-in-repl-no-focus (form) + "Insert FORM in the REPL buffer and eval it." + (while (string-match "\\`[ \t\n\r]+\\|[ \t\n\r]+\\'" form) + (setq form (replace-match "" t t form))) + (with-current-buffer (cider-current-repl-buffer) + (let ((pt-max (point-max))) + (goto-char pt-max) + (insert form) + (indent-region pt-max (point)) + (cider-repl-return)))) + +(defun spacemacs/cider-send-last-sexp-to-repl () + "Send last sexp to REPL and evaluate it without changing +the focus." + (interactive) + (spacemacs//cider-eval-in-repl-no-focus (cider-last-sexp))) + +(defun spacemacs/cider-send-last-sexp-to-repl-focus () + "Send last sexp to REPL and evaluate it and switch to the REPL in +`insert state'." + (interactive) + (cider-insert-last-sexp-in-repl t) + (evil-insert-state)) + +(defun spacemacs/cider-send-region-to-repl (start end) + "Send region to REPL and evaluate it without changing +the focus." + (interactive "r") + (spacemacs//cider-eval-in-repl-no-focus + (buffer-substring-no-properties start end))) + +(defun spacemacs/cider-send-region-to-repl-focus (start end) + "Send region to REPL and evaluate it and switch to the REPL in +`insert state'." + (interactive "r") + (cider-insert-in-repl + (buffer-substring-no-properties start end) t) + (evil-insert-state)) + +(defun spacemacs/cider-send-function-to-repl () + "Send current function to REPL and evaluate it without changing +the focus." + (interactive) + (spacemacs//cider-eval-in-repl-no-focus (cider-defun-at-point))) + +(defun spacemacs/cider-send-function-to-repl-focus () + "Send current function to REPL and evaluate it and switch to the REPL in +`insert state'." + (interactive) + (cider-insert-defun-in-repl t) + (evil-insert-state)) + +(defun spacemacs/cider-send-ns-form-to-repl () + "Send buffer's ns form to REPL and evaluate it without changing +the focus." + (interactive) + (spacemacs//cider-eval-in-repl-no-focus (cider-ns-form))) + +(defun spacemacs/cider-send-ns-form-to-repl-focus () + "Send ns form to REPL and evaluate it and switch to the REPL in +`insert state'." + (interactive) + (cider-insert-ns-form-in-repl t) + (evil-insert-state)) + +(defun spacemacs/cider-send-buffer-in-repl-and-focus () + "Send the current buffer in the REPL and switch to the REPL in +`insert state'." + (interactive) + (cider-load-buffer) + (cider-switch-to-repl-buffer) + (evil-insert-state)) + +(defun spacemacs/cider-test-run-focused-test () + "Run test around point." + (interactive) + (cider-load-buffer) + (cider-test-run-test)) + +(defalias 'spacemacs/cider-test-run-all-tests #'spacemacs/cider-test-run-ns-tests + "ns tests are not actually *all* tests; + cider-test-run-project-tests would be better here, but + there currently is a bug with the function. Replace once + it gets fixed.") + +(defun spacemacs/cider-test-run-ns-tests () + "Run namespace test." + (interactive) + (cider-load-buffer) + (cider-test-run-ns-tests nil)) + +(defun spacemacs/cider-test-run-loaded-tests () + "Run loaded tests." + (interactive) + (cider-load-buffer) + (cider-test-run-loaded-tests nil)) + +(defun spacemacs/cider-test-run-project-tests () + "Run project tests." + (interactive) + (cider-load-buffer) + (cider-test-run-project-tests nil)) + +(defun spacemacs/cider-test-rerun-tests () + "Run previous tests again." + (interactive) + (cider-load-buffer) + (cider-test-rerun-tests)) + +(defun spacemacs/cider-display-error-buffer (&optional arg) + "Displays the *cider-error* buffer in the current window. +If called with a prefix argument, uses the other-window instead." + (interactive "P") + (let ((buffer (get-buffer cider-error-buffer))) + (when buffer + (funcall (if (equal arg '(4)) + 'switch-to-buffer-other-window + 'switch-to-buffer) + buffer)))) + +(defun spacemacs/cider-toggle-repl-pretty-printing () + "Toggle REPL pretty printing on and off." + (interactive) + (setq cider-repl-use-pretty-printing + (if cider-repl-use-pretty-printing nil t)) + (message "Cider REPL pretty printing: %s" + (if cider-repl-use-pretty-printing "ON" "OFF"))) + +(defun spacemacs/cider-toggle-repl-font-locking () + "Toggle font locking in REPL." + (interactive) + (setq cider-repl-use-clojure-font-lock + (if cider-repl-use-pretty-printing nil t)) + (message "Cider REPL clojure-mode font-lock: %s" + (if cider-repl-use-clojure-font-lock "ON" "OFF"))) + +(defun spacemacs/cider-debug-setup () + "Initialize debug mode." + (when (memq dotspacemacs-editing-style '(hybrid vim)) + (evil-make-overriding-map cider--debug-mode-map 'normal) + (evil-normalize-keymaps))) diff --git a/layers/+lang/clojure/img/cider.png b/layers/+lang/clojure/img/cider.png new file mode 100644 index 0000000..30dce60 Binary files /dev/null and b/layers/+lang/clojure/img/cider.png differ diff --git a/layers/+lang/clojure/img/clojure.png b/layers/+lang/clojure/img/clojure.png new file mode 100644 index 0000000..55226c7 Binary files /dev/null and b/layers/+lang/clojure/img/clojure.png differ diff --git a/layers/+lang/clojure/packages.el b/layers/+lang/clojure/packages.el new file mode 100644 index 0000000..6744b82 --- /dev/null +++ b/layers/+lang/clojure/packages.el @@ -0,0 +1,296 @@ +(setq clojure-packages + '( + cider + cider-eval-sexp-fu + clj-refactor + clojure-mode + (clojure-snippets :toggle (configuration-layer/layer-usedp 'auto-completion)) + company + eldoc + ggtags + helm-gtags + popwin + smartparens + subword + org + )) + +(defun clojure/init-cider () + (use-package cider + :defer t + :init + (progn + (spacemacs/register-repl 'cider 'cider-jack-in "cider") + (setq cider-stacktrace-default-filters '(tooling dup) + cider-repl-pop-to-buffer-on-connect nil + cider-prompt-save-file-on-load nil + cider-repl-use-clojure-font-lock t) + (push "\\*cider-repl\.\+\\*" spacemacs-useful-buffers-regexp) + (add-hook 'clojure-mode-hook 'cider-mode) + (dolist (x '(spacemacs-jump-handlers-clojure-mode + spacemacs-jump-handlers-clojurec-mode + spacemacs-jump-handlers-clojurescript-mode + spacemacs-jump-handlers-clojurex-mode + spacemacs-jump-handlers-cider-repl-mode)) + (add-to-list x 'cider-find-var))) + :config + (progn + ;; add support for golden-ratio + (with-eval-after-load 'golden-ratio + (push 'cider-popup-buffer-quit-function golden-ratio-extra-commands)) + ;; add support for evil + (evil-set-initial-state 'cider-stacktrace-mode 'motion) + (evil-set-initial-state 'cider-popup-buffer-mode 'motion) + (add-hook 'cider--debug-mode-hook 'spacemacs/cider-debug-setup) + + (evilified-state-evilify cider-stacktrace-mode cider-stacktrace-mode-map + (kbd "C-j") 'cider-stacktrace-next-cause + (kbd "C-k") 'cider-stacktrace-previous-cause + (kbd "TAB") 'cider-stacktrace-cycle-current-cause + (kbd "0") 'cider-stacktrace-cycle-all-causes + (kbd "1") 'cider-stacktrace-cycle-cause-1 + (kbd "2") 'cider-stacktrace-cycle-cause-2 + (kbd "3") 'cider-stacktrace-cycle-cause-3 + (kbd "4") 'cider-stacktrace-cycle-cause-4 + (kbd "5") 'cider-stacktrace-cycle-cause-5 + (kbd "a") 'cider-stacktrace-toggle-all + (kbd "c") 'cider-stacktrace-toggle-clj + (kbd "d") 'cider-stacktrace-toggle-duplicates + (kbd "J") 'cider-stacktrace-toggle-java + (kbd "r") 'cider-stacktrace-toggle-repl + (kbd "T") 'cider-stacktrace-toggle-tooling) + + ;; open cider-doc directly and close it with q + (setq cider-prompt-for-symbol nil) + + (evilified-state-evilify cider-docview-mode cider-docview-mode-map + (kbd "q") 'cider-popup-buffer-quit) + + (evilified-state-evilify cider-inspector-mode cider-inspector-mode-map + (kbd "L") 'cider-inspector-pop + (kbd "n") 'cider-inspector-next-page + (kbd "N") 'cider-inspector-previous-page + (kbd "r") 'cider-inspector-refresh) + + (evilified-state-evilify cider-test-report-mode cider-test-report-mode-map + (kbd "C-j") 'cider-test-next-result + (kbd "C-k") 'cider-test-previous-result + (kbd "RET") 'cider-test-jump + (kbd "d") 'cider-test-ediff + (kbd "e") 'cider-test-stacktrace + (kbd "q") 'cider-popup-buffer-quit + (kbd "r") 'cider-test-rerun-tests + (kbd "t") 'cider-test-run-test + (kbd "T") 'cider-test-run-ns-tests) + + ;; TODO: having this work for cider-macroexpansion-mode would be nice, + ;; but the problem is that it uses clojure-mode as its major-mode + + (setq cider--key-binding-prefixes + '(("md" . "debug") + ("me" . "evaluation") + ("mg" . "goto") + ("mh" . "documentation") + ("ms" . "repl") + ("mt" . "test") + ("mT" . "toggle") + ("mf" . "format"))) + (dolist (m '(clojure-mode + clojurec-mode + clojurescript-mode + clojurex-mode + cider-repl-mode + cider-clojure-interaction-mode)) + (mapc (lambda (x) (spacemacs/declare-prefix-for-mode + m (car x) (cdr x))) + cider--key-binding-prefixes) + + (spacemacs/set-leader-keys-for-major-mode m + "ha" 'cider-apropos + "hh" 'cider-doc + "hg" 'cider-grimoire + "hj" 'cider-javadoc + "hn" 'cider-browse-ns + + "eb" 'cider-eval-buffer + "ee" 'cider-eval-last-sexp + "ef" 'cider-eval-defun-at-point + "em" 'cider-macroexpand-1 + "eM" 'cider-macroexpand-all + "er" 'cider-eval-region + "ew" 'cider-eval-last-sexp-and-replace + + "=" 'cider-format-buffer + "fb" 'cider-format-buffer + + "gb" 'cider-pop-back + "gC" 'cider-classpath + "ge" 'cider-jump-to-compilation-error + "gr" 'cider-jump-to-resource + "gn" 'cider-browse-ns + "gN" 'cider-browse-ns-all + + "'" 'cider-jack-in + "\"" 'cider-jack-in-clojurescript + "sb" 'cider-load-buffer + "sB" 'spacemacs/cider-send-buffer-in-repl-and-focus + "sc" (if (eq m 'cider-repl-mode) + 'cider-repl-clear-buffer + 'cider-connect) + "sC" 'cider-find-and-clear-repl-output + "se" 'spacemacs/cider-send-last-sexp-to-repl + "sE" 'spacemacs/cider-send-last-sexp-to-repl-focus + "sf" 'spacemacs/cider-send-function-to-repl + "sF" 'spacemacs/cider-send-function-to-repl-focus + "si" 'cider-jack-in + "sI" 'cider-jack-in-clojurescript + "sn" 'spacemacs/cider-send-ns-form-to-repl + "sN" 'spacemacs/cider-send-ns-form-to-repl-focus + "so" 'cider-repl-switch-to-other + "sq" 'cider-quit + "sr" 'spacemacs/cider-send-region-to-repl + "sR" 'spacemacs/cider-send-region-to-repl-focus + "ss" (if (eq m 'cider-repl-mode) + 'cider-switch-to-last-clojure-buffer + 'cider-switch-to-repl-buffer) + "sx" 'cider-refresh + + "Te" 'cider-enlighten-mode + "Tf" 'spacemacs/cider-toggle-repl-font-locking + "Tp" 'spacemacs/cider-toggle-repl-pretty-printing + "Tt" 'cider-auto-test-mode + + "ta" 'spacemacs/cider-test-run-all-tests + "tb" 'cider-test-show-report + "tl" 'spacemacs/cider-test-run-loaded-tests + "tp" 'spacemacs/cider-test-run-project-tests + "tn" 'spacemacs/cider-test-run-ns-tests + "tr" 'spacemacs/cider-test-rerun-tests + "tt" 'spacemacs/cider-test-run-focused-test + + "db" 'cider-debug-defun-at-point + "de" 'spacemacs/cider-display-error-buffer + "di" 'cider-inspect)) + + ;; cider-repl-mode only + (spacemacs/set-leader-keys-for-major-mode 'cider-repl-mode + "," 'cider-repl-handle-shortcut) + + (spacemacs/set-leader-keys-for-major-mode 'cider-clojure-interaction-mode + "ep" 'cider-eval-print-last-sexp) + + (evil-define-key 'normal cider-repl-mode-map + "C-j" 'cider-repl-next-input + "C-k" 'cider-repl-previous-input) + + (when clojure-enable-fancify-symbols + (clojure/fancify-symbols 'cider-repl-mode) + (clojure/fancify-symbols 'cider-clojure-interaction-mode))) + + (defadvice cider-jump-to-var (before add-evil-jump activate) + (evil-set-jump)))) + +(defun clojure/init-cider-eval-sexp-fu () + (with-eval-after-load 'eval-sexp-fu + (require 'cider-eval-sexp-fu))) + +(defun clojure/init-clj-refactor () + (use-package clj-refactor + :defer t + :init + (add-hook 'clojure-mode-hook 'clj-refactor-mode) + :config + (progn + (cljr-add-keybindings-with-prefix "C-c C-f") + + (setq clj-refactor--key-binding-prefixes + '(("mr" . "refactor") + ("mra" . "add") + ("mrc" . "cycle/clean") + ("mrd" . "destructure") + ("mre" . "extract/expand") + ("mrf" . "find/function") + ("mrh" . "hotload") + ("mri" . "introduce/inline") + ("mrm" . "move") + ("mrp" . "project/promote") + ("mrr" . "remove/rename/replace") + ("mrs" . "show/sort/stop") + ("mrt" . "thread") + ("mru" . "unwind/update"))) + (dolist (m '(clojure-mode + clojurec-mode + clojurescript-mode + clojurex-mode + cider-repl-mode + cider-clojure-interaction-mode)) + (mapc (lambda (x) (spacemacs/declare-prefix-for-mode + m (car x) (cdr x))) + clj-refactor--key-binding-prefixes) + (dolist (r cljr--all-helpers) + (let* ((binding (car r)) + (func (car (cdr r)))) + (when (not (string-prefix-p "hydra" (symbol-name func))) + (spacemacs/set-leader-keys-for-major-mode m + (concat "r" binding) func)))))))) + +(defun clojure/init-clojure-mode () + (use-package clojure-mode + :defer t + :init + (progn + (add-to-list 'auto-mode-alist '("\\.boot\\'" . clojure-mode)) + ;; This regexp matches shebang expressions like `#!/usr/bin/env boot' + (add-to-list 'magic-mode-alist '("#!.*boot\\s-*$" . clojure-mode))) + :config + (progn + (dolist (m '(clojure-mode clojurec-mode clojurescript-mode clojurex-mode)) + (spacemacs/set-leader-keys-for-major-mode m + "fl" 'clojure-align)) + + (when clojure-enable-fancify-symbols + (dolist (m '(clojure-mode clojurescript-mode clojurec-mode clojurex-mode)) + (clojure/fancify-symbols m)))))) + +(defun clojure/post-init-eldoc () + (add-hook 'cider-mode-hook 'eldoc-mode) + (add-hook 'cider-repl-mode-hook 'eldoc-mode) + (add-hook 'cider-clojure-interaction-mode-hook 'eldoc-mode)) + +(defun clojure/pre-init-popwin () + (spacemacs|use-package-add-hook popwin + :post-config + (push '("*cider-error*" :dedicated t :position bottom :stick t :noselect nil :height 0.4) + popwin:special-display-config) + (push '("*cider-doc*" :dedicated t :position bottom :stick t :noselect nil :height 0.4) + popwin:special-display-config))) + +(defun clojure/post-init-smartparens () + (add-hook 'cider-repl-mode-hook + (if dotspacemacs-smartparens-strict-mode + #'smartparens-strict-mode + #'smartparens-mode))) + +(defun clojure/post-init-subword () + (add-hook 'cider-mode-hook 'subword-mode)) + +(defun clojure/post-init-company () + (push 'company-capf company-backends-cider-mode) + (spacemacs|add-company-hook cider-mode) + (push 'company-capf company-backends-cider-repl-mode) + (spacemacs|add-company-hook cider-repl-mode)) + +(defun clojure/post-init-ggtags () + (add-hook 'clojure-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun clojure/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'clojure-mode)) + +(defun clojure/init-clojure-snippets () + (use-package clojure-snippets + :defer t)) + +(defun clojure/pre-init-org () + (spacemacs|use-package-add-hook org + :post-config (add-to-list 'org-babel-load-languages '(clojure . t)) + (setq org-babel-clojure-backend 'cider))) diff --git a/layers/+lang/common-lisp/README.org b/layers/+lang/common-lisp/README.org new file mode 100644 index 0000000..d49267a --- /dev/null +++ b/layers/+lang/common-lisp/README.org @@ -0,0 +1,109 @@ +#+TITLE: Common Lisp layer + +[[file:img/slime.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key Bindings]] + - [[#working-with-lisp-files-barfage-slurpage--more][Working with lisp files (barfage, slurpage & more)]] + - [[#leader][Leader]] + - [[#help][Help]] + - [[#evaluation][Evaluation]] + - [[#repl][REPL]] + - [[#compile][Compile]] + - [[#navigation][Navigation]] + - [[#macroexpansion][Macroexpansion]] + +* Description +A Spacemacs contribution layer providing Common Lisp support via [[https://github.com/slime/slime][SLIME]]. + +* Install +If you have previously installed slime in any other way, it is recommended that +you uninstall it before proceeding. You should clean up any config files tied to +slime that are left behind as well. Linux users can just purge the slime package +if it was a distribution install. + +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =common-lisp= to the existing =dotspacemacs-configuration-layers= list in this +file. + +This layer defaults to using [[http://www.sbcl.org/][sbcl]]. If you want to use a different implementation +of Common Lisp, you can specify it in your =~/.spacemacs= + +#+BEGIN_SRC emacs-lisp + (defun dotspacemacs/user-config () + (setq inferior-lisp-program "/path/to/your/lisp")) +#+END_SRC + +* Key Bindings +** Working with lisp files (barfage, slurpage & more) +Spacemacs comes with a special ~lisp-state~ for working with lisp code that +supports slurpage, barfage and more tools you'll likely want when working with +lisp. + +As this state works the same for all files, the documentation is in global +[[https://github.com/syl20bnr/spacemacs/blob/master/doc/DOCUMENTATION.org#lisp-key-bindings][DOCUMENTATION.org]]. In general, use ~SPC k~ to interact with the lisp-state. + +** Leader +*** Help + +| Key Binding | Description | +|-------------+---------------------------------------------------------| +| ~SPC m h a~ | SLIME apropos | +| ~SPC m h d~ | Disassemble symbol at point | +| ~SPC m h h~ | Describe symbol at point | +| ~SPC m h H~ | Hyperspec lookup symbol at point | +| ~SPC m h p~ | Browse apropos results for a package's exported symbols | +| ~SPC m h t~ | Toggle tracing of the function at point | +| ~SPC m h T~ | Untrace all functions | +| ~SPC m h <~ | Show all known callers | +| ~SPC m h >~ | Show all known callees | +| ~SPC m h m~ | Show all usages of a macro | +| ~SPC m h r~ | Show references to global variable | +| ~SPC m h s~ | Show all methods specialized on a class | + +*** Evaluation + +| Key Binding | Description | +|-------------+---------------------------------| +| ~SPC m e b~ | Evaluate buffer | +| ~SPC m e e~ | Evaluate last expression | +| ~SPC m e f~ | Evaluate top level s-expression | +| ~SPC m e F~ | Undefine the function at point | +| ~SPC m e r~ | Evaluate region | + +*** REPL + +| Key Binding | Description | +|-------------+----------------------------------| +| ~SPC m s i~ | Start an inferior process | +| ~SPC m s e~ | Evaluate last expression in REPL | +| ~SPC m s q~ | Quit | + +*** Compile + +| Key Binding | Description | +|-------------+--------------------------| +| ~SPC m c c~ | Compile file | +| ~SPC m c C~ | Compile file and load it | +| ~SPC m c l~ | Load file | +| ~SPC m c n~ | Remove compilation notes | +| ~SPC m c f~ | Compile function | +| ~SPC m c r~ | Compile region | + +*** Navigation + +| Key Binding | Description | +|---------------------------+--------------------| +| ~SPC m g g~ | Inspect definition | +| ~SPC m g b~ | Go back | +| ~SPC m g n~ | Next note | +| ~SPC m g N~ or ~SPC m g p | Previous note | + +*** Macroexpansion + +| Key Binding | Description | +|-------------+-----------------------------------------------| +| ~SPC m m a~ | Macroexpand the expression at point completly | +| ~SPC m m o~ | Macroexpand the expression at point once | diff --git a/layers/+lang/common-lisp/config.el b/layers/+lang/common-lisp/config.el new file mode 100644 index 0000000..1bb0a5b --- /dev/null +++ b/layers/+lang/common-lisp/config.el @@ -0,0 +1,13 @@ +;;; config.el --- common-lisp Layer Configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(spacemacs|define-jump-handlers lisp-mode slime-inspect-definition) +(spacemacs|define-jump-handlers common-lisp-mode) diff --git a/layers/+lang/common-lisp/funcs.el b/layers/+lang/common-lisp/funcs.el new file mode 100644 index 0000000..5027c02 --- /dev/null +++ b/layers/+lang/common-lisp/funcs.el @@ -0,0 +1,25 @@ +;;; funcs.el --- Slime Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + +;; Helm integration + +(defun spacemacs//slime-helm-source (&optional table) + (or table (setq table slime-lisp-implementations)) + `((name . "Slime") + (candidates . ,(mapcar #'car table)) + (action . (lambda (candidate) + (car (helm-marked-candidates)))))) + +(defun spacemacs/helm-slime () + (interactive) + (let ((command (helm :sources (spacemacs//slime-helm-source)))) + (and command (slime (intern command))))) diff --git a/layers/+lang/common-lisp/img/slime.png b/layers/+lang/common-lisp/img/slime.png new file mode 100644 index 0000000..dc43081 Binary files /dev/null and b/layers/+lang/common-lisp/img/slime.png differ diff --git a/layers/+lang/common-lisp/packages.el b/layers/+lang/common-lisp/packages.el new file mode 100644 index 0000000..26211d9 --- /dev/null +++ b/layers/+lang/common-lisp/packages.el @@ -0,0 +1,119 @@ +;;; packages.el --- Common Lisp Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq common-lisp-packages + '(auto-highlight-symbol + (common-lisp-snippets :toggle (configuration-layer/package-usedp 'yasnippet)) + ggtags + helm + helm-gtags + slime + slime-company)) + +(defun common-lisp/post-init-auto-highlight-symbol () + (with-eval-after-load 'auto-highlight-symbol + (add-to-list 'ahs-plugin-bod-modes 'lisp-mode))) + +(defun common-lisp/init-common-lisp-snippets ()) + +(defun common-lisp/post-init-helm () + (spacemacs/set-leader-keys-for-major-mode 'lisp-mode + "sI" 'spacemacs/helm-slime)) + +(defun common-lisp/post-init-ggtags () + (add-hook 'common-lisp-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun common-lisp/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'common-lisp-mode)) + +(defun common-lisp/init-slime-company () + (setq slime-company-completion 'fuzzy)) + +(defun common-lisp/init-slime () + (use-package slime + :commands slime-mode + :init + (progn + (spacemacs/register-repl 'slime 'slime) + (setq slime-contribs '(slime-fancy + slime-indentation + slime-sbcl-exts + slime-scratch) + inferior-lisp-program "sbcl") + (when (configuration-layer/package-usedp 'slime-company) + (push 'slime-company slime-contribs)) + ;; enable fuzzy matching in code buffer and SLIME REPL + (setq slime-complete-symbol*-fancy t) + (setq slime-complete-symbol-function 'slime-fuzzy-complete-symbol) + ;; enabel smartparen in code buffer and SLIME REPL + ;; (add-hook 'slime-repl-mode-hook #'smartparens-strict-mode) + (defun slime/disable-smartparens () + (smartparens-strict-mode -1) + (turn-off-smartparens-mode)) + (add-hook 'slime-repl-mode-hook #'slime/disable-smartparens) + (spacemacs/add-to-hooks 'slime-mode '(lisp-mode-hook))) + :config + (progn + (slime-setup) + ;; TODO: Add bindings for the SLIME debugger? + (spacemacs/set-leader-keys-for-major-mode 'lisp-mode + "'" 'slime + + "cc" 'slime-compile-file + "cC" 'slime-compile-and-load-file + "cl" 'slime-load-file + "cf" 'slime-compile-defun + "cr" 'slime-compile-region + "cn" 'slime-remove-notes + + "eb" 'slime-eval-buffer + "ef" 'slime-eval-defun + "eF" 'slime-undefine-function + "ee" 'slime-eval-last-expression + "er" 'slime-eval-region + + "gb" 'slime-pop-find-definition-stack + "gn" 'slime-next-note + "gN" 'slime-previous-note + + "ha" 'slime-apropos + "hA" 'slime-apropos-all + "hd" 'slime-disassemble-symbol + "hh" 'slime-describe-symbol + "hH" 'slime-hyperspec-lookup + "hp" 'slime-apropos-package + "ht" 'slime-toggle-trace-fdefinition + "hT" 'slime-untrace-all + "h<" 'slime-who-calls + "h>" 'slime-calls-who + ;; TODO: Add key bindings for who binds/sets globals? + "hr" 'slime-who-references + "hm" 'slime-who-macroexpands + "hs" 'slime-who-specializes + + "ma" 'slime-macroexpand-all + "mo" 'slime-macroexpand-1 + + "se" 'slime-eval-last-expression-in-repl + "si" 'slime + "sq" 'slime-quit-lisp + + "tf" 'slime-toggle-fancy-trace) + ;; prefix names for which-key + (mapc (lambda (x) + (spacemacs/declare-prefix-for-mode 'lisp-mode (car x) (cdr x))) + '(("mh" . "help") + ("me" . "eval") + ("ms" . "repl") + ("mc" . "compile") + ("mg" . "nav") + ("mm" . "macro") + ("mt" . "toggle")))))) diff --git a/layers/+lang/csharp/README.org b/layers/+lang/csharp/README.org new file mode 100644 index 0000000..26212e8 --- /dev/null +++ b/layers/+lang/csharp/README.org @@ -0,0 +1,146 @@ +#+TITLE: C# layer + +[[file:img/csharp.png]] [[file:img/dotnet.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#packages-included][Packages Included]] + - [[#install][Install]] + - [[#prerequisites][Prerequisites]] + - [[#aspnet-5][ASP.NET 5]] + - [[#curl][curl]] + - [[#omnisharp-server][Omnisharp server]] + - [[#caveats][Caveats]] + - [[#key-bindings][Key Bindings]] + - [[#compilation][Compilation]] + - [[#filesolutionproject-manipulation][File/Solution/Project manipulation]] + - [[#navigation][Navigation]] + - [[#helpers-documentation-info][Helpers (documentation, info)]] + - [[#refactoring][Refactoring]] + - [[#omnisharp-server-interaction][OmniSharp server interaction]] + - [[#tests][Tests]] + - [[#code-manipulation][Code manipulation]] + +* Description +This layer adds experimental support for C# language using [[https://github.com/OmniSharp/omnisharp-emacs][OmniSharp]]. + +* Packages Included +- [[https://github.com/OmniSharp/omnisharp-emacs][OmniSharp-emacs]] + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =csharp= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Prerequisites +*** ASP.NET 5 +Follow the instructions for your platform [[https://github.com/aspnet/home#getting-started][here]]. + +*** curl +You'll need [[http://curl.haxx.se/][curl]] to be able to use the Omnisharp package. Use your favorite +package manager to install it (on Windows you can use [[https://chocolatey.org/][chocolatey]]). + +Be sure to make the =curl= binary available to your PATH environment variable, +or set the variable =omnisharp--curl-executable-path= in your dotfile function +=dotspacemacs-config=: + +#+BEGIN_SRC emacs-lisp + (setq-default omnisharp--curl-executable-path "/PATH/TO/CURL/curl") +#+END_SRC + +*** Omnisharp server +You have to compile the OmniSharp server following the instructions which can +be found [[https://github.com/OmniSharp/omnisharp-server][here]]. + +Don't forget to add the server binary directory to your system PATH environment +variable. The full path the binary can also be directly referenced in the +variable =omnisharp-server-executable-path= (put this in your +=dotspacemacs-config= function): + +#+BEGIN_SRC emacs-lisp + (setq-default omnisharp-server-executable-path "/PATH/TO/OMNISHARP/OmniSharpServer") +#+END_SRC + +OmniSharp should now automatically load and start a server when you open a +=.cs= file. + +* Caveats +- It's currently not possible to create a C# solution outside of an IDE such as + [[http://www.monodevelop.com/][MonoDevelop]], it's therefore recommended that you install it to create your + solutions. + +- Debugging is possible using [[https://github.com/mono/sdb][SDB]]. + +* Key Bindings +** Compilation + +| Key Binding | Description | +|-------------+--------------------| +| ~SPC m c c~ | Build the solution | + +** File/Solution/Project manipulation + +| Key Binding | Description | +|-------------+-----------------------------------------------| +| ~SPC m f a~ | Add the current file to solution | +| ~SPC m f A~ | Add files selected in dired to solution | +| ~SPC m f r~ | Remove the current file from solution | +| ~SPC m f R~ | Removed files selected in dired from solution | +| ~SPC m p l~ | Add reference to solution | + +** Navigation + +| Key Binding | Description | +|-------------+-----------------------------------------------| +| ~SPC m g f~ | Go to solution file | +| ~SPC m g F~ | Go to solution file then member | +| ~SPC m g c~ | Go to member in current file | +| ~SPC m g g~ | Go to definition | +| ~SPC m g G~ | Go to definition in other window | +| ~SPC m g i~ | Find implementations | +| ~SPC m g I~ | Find implementations using ido | +| ~SPC m g m~ | Go to solution member | +| ~SPC m g M~ | Go to solution member in other window | +| ~SPC m g r~ | Go to region | +| ~SPC m g s~ | Find symbols using Helm | +| ~SPC m g u~ | Find usages of symbol under cursor using Helm | +| ~SPC m g U~ | Find usages of symbol under cursor using ido | + +** Helpers (documentation, info) + +| Key Binding | Description | +|-------------+------------------------------------------------------------------------| +| ~SPC m h t~ | Get type information for symbol under cursor | +| ~SPC m h T~ | Get type information for symbol under cursor and put it into kill-ring | + +** Refactoring + +| Key Binding | Description | +|-------------+------------------------------------------| +| ~SPC m r m~ | Rename symbol under cursor | +| ~SPC m r M~ | Rename symbol under cursor interactively | +| ~SPC m r r~ | Refactor symbol under cursor | + +** OmniSharp server interaction + +| Key Binding | Description | +|-------------+----------------------------| +| ~SPC m s r~ | Reload the solution | +| ~SPC m s s~ | Start the OmniSharp server | +| ~SPC m s S~ | Stop the OmniSharp server | + +** Tests + +| Key Binding | Description | +|-------------+---------------------------------------| +| ~SPC m t a~ | Run all tests in project | +| ~SPC m t b~ | Run all tests in current file/fixture | +| ~SPC m t t~ | Run test under cursor | + +** Code manipulation + +| Key Binding | Description | +|-------------+---------------------------| +| ~SPC m o~ | Auto complete overrides | +| ~SPC m i~ | Fix usings/imports | +| ~SPC m =~ | Format the current buffer | diff --git a/layers/+lang/csharp/config.el b/layers/+lang/csharp/config.el new file mode 100644 index 0000000..b6b974f --- /dev/null +++ b/layers/+lang/csharp/config.el @@ -0,0 +1,16 @@ +;;; packages.el --- C# Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; variables + +(spacemacs|defvar-company-backends csharp-mode) + +(spacemacs|define-jump-handlers csharp-mode) diff --git a/layers/+lang/csharp/img/csharp.png b/layers/+lang/csharp/img/csharp.png new file mode 100644 index 0000000..4694ede Binary files /dev/null and b/layers/+lang/csharp/img/csharp.png differ diff --git a/layers/+lang/csharp/img/dotnet.png b/layers/+lang/csharp/img/dotnet.png new file mode 100644 index 0000000..63346fa Binary files /dev/null and b/layers/+lang/csharp/img/dotnet.png differ diff --git a/layers/+lang/csharp/packages.el b/layers/+lang/csharp/packages.el new file mode 100644 index 0000000..ed48aae --- /dev/null +++ b/layers/+lang/csharp/packages.el @@ -0,0 +1,105 @@ +;;; packages.el --- csharp Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq csharp-packages + '( + company + csharp-mode + evil-matchit + ggtags + helm-gtags + omnisharp + )) + +(defun csharp/init-omnisharp () + ;; Load omnisharp-mode with csharp-mode, this should start the omnisharp server automatically + (add-hook 'csharp-mode-hook 'omnisharp-mode) + (use-package omnisharp + :defer t + :init + (progn + (when (configuration-layer/package-usedp 'company) + ;; needed to avoid an error when fetching doc using company + ;; Note: if you are using a roslyn based omnisharp server you can + ;; set back this variable to t. + (setq omnisharp-auto-complete-want-documentation nil)) + (push 'company-omnisharp company-backends-csharp-mode) + (add-to-list 'spacemacs-jump-handlers-csharp-mode + 'omnisharp-go-to-definition)) + :config + (progn + (spacemacs/declare-prefix-for-mode 'csharp-mode "mc" "csharp/compile") + (spacemacs/declare-prefix-for-mode 'csharp-mode "mf" "csharp/file") + (spacemacs/declare-prefix-for-mode 'csharp-mode "mg" "csharp/navigation") + (spacemacs/declare-prefix-for-mode 'csharp-mode "mh" "csharp/documentation") + (spacemacs/declare-prefix-for-mode 'csharp-mode "mr" "csharp/refactoring") + (spacemacs/declare-prefix-for-mode 'csharp-mode "ms" "csharp/server") + (spacemacs/declare-prefix-for-mode 'csharp-mode "mt" "csharp/tests") + (spacemacs/set-leader-keys-for-major-mode 'csharp-mode + ;; Compile + "cc" 'omnisharp-build-in-emacs ;; Only one compile command so use top-level + ;; Solution/project manipulation + "fa" 'omnisharp-add-to-solution-current-file + "fA" 'omnisharp-add-to-solution-dired-selected-files + "fr" 'omnisharp-remove-from-project-current-file + "fR" 'omnisharp-remove-from-project-dired-selected-files + "pl" 'omnisharp-add-reference + ;; Navigation + "gG" 'omnisharp-go-to-definition-other-window + "gu" 'omnisharp-helm-find-usages + "gU" 'omnisharp-find-usages-with-ido + "gs" 'omnisharp-helm-find-symbols + "gi" 'omnisharp-find-implementations + "gI" 'omnisharp-find-implementations-with-ido + "gr" 'omnisharp-navigate-to-region + "gm" 'omnisharp-navigate-to-solution-member + "gM" 'omnisharp-navigate-to-solution-member-other-window + "gf" 'omnisharp-navigate-to-solution-file + "gF" 'omnisharp-navigate-to-solution-file-then-file-member + "gc" 'omnisharp-navigate-to-current-file-member + ;; Help, documentation, info + "ht" 'omnisharp-current-type-information + "hT" 'omnisharp-current-type-information-to-kill-ring + ;; Refactoring + "rm" 'omnisharp-rename + "rM" 'omnisharp-rename-interactively + "rr" 'omnisharp-run-code-action-refactoring + ;; Server manipulation, inspired spacemacs REPL bindings since C# does not provice a REPL + "ss" 'omnisharp-start-omnisharp-server + "sS" 'omnisharp-stop-server + "sr" 'omnisharp-reload-solution + ;; Tests + "ta" 'omnisharp-unit-test-all + "tb" 'omnisharp-unit-test-fixture + "tt" 'omnisharp-unit-test-single + ;; Code manipulation + "u" 'omnisharp-auto-complete-overrides + "i" 'omnisharp-fix-usings + "=" 'omnisharp-code-format)))) + +(defun csharp/post-init-company () + (spacemacs|add-company-hook csharp-mode)) + +(defun csharp/init-csharp-mode () + (use-package csharp-mode + :defer t)) + +(defun csharp/post-init-evil-matchit () + (with-eval-after-load 'evil-matchit + (plist-put evilmi-plugins 'csharp-mode '((evilmi-simple-get-tag evilmi-simple-jump) + (evilmi-c-get-tag evilmi-c-jump)))) + (add-hook 'csharp-mode-hook 'turn-on-evil-matchit-mode)) + +(defun csharp/post-init-ggtags () + (add-hook 'csharp-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun csharp/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'csharp-mode)) diff --git a/layers/+lang/csv/README.org b/layers/+lang/csv/README.org new file mode 100644 index 0000000..eb6ef11 --- /dev/null +++ b/layers/+lang/csv/README.org @@ -0,0 +1,41 @@ +#+TITLE: CSV layer + +[[file:img/csv.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#key-bindings][Key Bindings]] + +* Description + +This layer adds tools for better integration of CSV files in Spacemacs. + +* Install + +** Layer + +To use this contribution add it to your =~/.spacemacs= + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '(csv)) +#+END_SRC + +* Key Bindings + +| Key Binding | Description | +|-------------+----------------------------------| +| ~SPC m a~ | Align fields | +| ~SPC m d~ | Kill fields | +| ~SPC m i~ | Toggle delimiter invisibility | +| ~SPC m n~ | Move forward 1 field | +| ~SPC m p~ | Move backwards 1 field | +| ~SPC m r~ | Reverse region | +| ~SPC m s f~ | Sort fields | +| ~SPC m s n~ | Sort fields numerically | +| ~SPC m s o~ | Toggle sort order | +| ~SPC m t~ | Transpose | +| ~SPC m v f~ | Paste killed fields | +| ~SPC m v t~ | Paste killed fields as new table | +| ~SPC m u~ | Unalign fields | diff --git a/layers/+lang/csv/img/csv.png b/layers/+lang/csv/img/csv.png new file mode 100644 index 0000000..b45884b Binary files /dev/null and b/layers/+lang/csv/img/csv.png differ diff --git a/layers/+lang/csv/packages.el b/layers/+lang/csv/packages.el new file mode 100644 index 0000000..88b6221 --- /dev/null +++ b/layers/+lang/csv/packages.el @@ -0,0 +1,34 @@ +;;; packages.el --- csharp Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: William Casarin +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq csv-packages '(csv-mode)) + +(defun csv/init-csv-mode () + (use-package csv-mode + :defer t + :init + (progn + (spacemacs/declare-prefix-for-mode 'csv-mode "ms" "sort") + (spacemacs/declare-prefix-for-mode 'csv-mode "mv" "yank") + (spacemacs/set-leader-keys-for-major-mode 'csv-mode + "a" 'csv-align-fields + "d" 'csv-kill-fields + "i" 'csv-toggle-invisibility + "n" 'csv-forward-field + "p" 'csv-backward-field + "r" 'csv-reverse-region + "sf" 'csv-sort-fields + "sn" 'csv-sort-numeric-fields + "so" 'csv-toggle-descending + "t" 'csv-transpose + "u" 'csv-unalign-fields + "vf" 'csv-yank-fields + "vt" 'csv-yank-as-new-table)))) diff --git a/layers/+lang/d/README.org b/layers/+lang/d/README.org new file mode 100644 index 0000000..8d514af --- /dev/null +++ b/layers/+lang/d/README.org @@ -0,0 +1,32 @@ +#+TITLE: D language layer + +[[file:img/dlogo.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + +* Description +This simple layer adds support for the [[http://dlang.org/][D language]]. +It adds =d-mode= as well as integrating it with =auto-completion= and =syntax-checking=. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =d= to the existing =dotspacemacs-configuration-layers= list in this +file. + +To enable smart D completion, you need to install [[https://github.com/Hackerpilot/DCD][DCD]]. Here are [[https://github.com/Hackerpilot/DCD#setup][installation +instructions]]. After successfully built DCD, you need to copy the binary +=dcd-server= and =dcd-client= in =bin/= directory to somewhere in your $PATH e.g. +=/usr/local/bin= on Linux. + +* Key bindings + +| Key Binding | Description | +|-------------+-------------------------------------------------------| +| ~SPC m g g~ | Go to definition | +| ~SPC m g b~ | Jump back (after go to definition with above command) | +| ~SPC m g r~ | find references to all symbol at point | +|-------------+-------------------------------------------------------| + diff --git a/layers/+lang/d/config.el b/layers/+lang/d/config.el new file mode 100644 index 0000000..d92def0 --- /dev/null +++ b/layers/+lang/d/config.el @@ -0,0 +1,16 @@ +;;; config.el --- d Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(spacemacs|defvar-company-backends d-mode) + +(spacemacs|define-jump-handlers d-mode) diff --git a/layers/+lang/d/img/dlogo.png b/layers/+lang/d/img/dlogo.png new file mode 100644 index 0000000..c4e4a53 Binary files /dev/null and b/layers/+lang/d/img/dlogo.png differ diff --git a/layers/+lang/d/packages.el b/layers/+lang/d/packages.el new file mode 100644 index 0000000..1a38df7 --- /dev/null +++ b/layers/+lang/d/packages.el @@ -0,0 +1,57 @@ +;;; packages.el --- d Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; List of all packages to install and/or initialize. Built-in packages +;; which require an initialization must be listed explicitly in the list. +(setq d-packages + '( + company + (company-dcd :toggle (configuration-layer/package-usedp 'company)) + d-mode + flycheck + (flycheck-dmd-dub :toggle (configuration-layer/package-usedp 'flycheck)) + ggtags + helm-gtags + )) + +(defun d/post-init-company () + ;; Need to convince company that this C-derived mode is a code mode. + (with-eval-after-load 'company-dabbrev-code (push 'd-mode company-dabbrev-code-modes)) + (spacemacs|add-company-hook d-mode)) + +(defun d/init-company-dcd () + (use-package company-dcd + :defer t + :init + (progn + (add-hook 'd-mode-hook 'company-dcd-mode) + (push 'company-dcd company-backends-d-mode) + (spacemacs/set-leader-keys-for-major-mode 'd-mode + "gg" 'company-dcd-goto-definition + "gb" 'company-dcd-goto-def-pop-marker + "hh" 'company-dcd-show-ddoc-with-buffer + "gr" 'company-dcd-ivy-search-symbol)))) + +(defun d/init-d-mode () + (use-package d-mode :defer t)) + +(defun d/post-init-flycheck () + (spacemacs/add-flycheck-hook 'd-mode)) + +(defun d/init-flycheck-dmd-dub () + (use-package flycheck-dmd-dub :defer t + :init (add-hook 'd-mode-hook 'flycheck-dmd-dub-set-include-path))) + +(defun d/post-init-ggtags () + (add-hook 'd-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun d/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'd-mode)) diff --git a/layers/+lang/elixir/README.org b/layers/+lang/elixir/README.org new file mode 100644 index 0000000..095d52b --- /dev/null +++ b/layers/+lang/elixir/README.org @@ -0,0 +1,187 @@ +#+TITLE: Elixir layer + +[[file:img/elixir.png]] with [[file:img/alchemist.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#configuration][Configuration]] + - [[#flycheck][Flycheck]] + - [[#credo][Credo]] + - [[#mix-compile][mix compile]] + - [[#key-bindings][Key bindings]] + - [[#refcard][Refcard]] + - [[#help][Help]] + - [[#mix][Mix]] + - [[#project][Project]] + - [[#evaluation-in-place][Evaluation in place]] + - [[#repl-interactions][REPL interactions]] + - [[#tests][Tests]] + - [[#compile][Compile]] + - [[#execute][Execute]] + - [[#code-definition-jump][Code Definition Jump]] + +* Description +This layer adds support for [[http://elixir-lang.org/][Elixir]] . + +[[https://github.com/tonini/alchemist.el][Alchemist]] brings the Elixir tooling to Emacs and comes with a bunch of +features like: +- Powerful IEx integration +- Mix integration +- Compile & Execution of Elixir code +- Inline code evaluation +- Documentation lookup +- Definition lookup +- Smart code completion +- Elixir project management +- Integration with [[http://company-mode.github.io/][company-mode]] +- Flycheck support for mix compile +- Flycheck support for [[https://github.com/rrrene/credo][credo]] +- Flycheck support for test results + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =elixir= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Configuration +** Flycheck +*Note:* since flycheck checkers are slow, the checks are enabled only at save +time. + +*** Credo +A flycheck checker for [[https://github.com/rrrene/credo][credo]] is installed. The check needs both =bunt= and +=credo= to be available, you can install them like this: + +#+BEGIN_SRC shell +git clone https://github.com/rrrene/bunt +cd bunt +mix archive.build +mix archive.install +#+END_SRC + +#+BEGIN_SRC shell +git clone https://github.com/rrrene/credo +cd credo +mix deps.get +mix archive.build +mix archive.install +#+END_SRC + +*** mix compile +*Important:* +Elixir compiler is based on macros and can execute arbitrary during compilation. +Therefore Spacemacs disable flycheck compilation checker by default. + +To enable flycheck support for compilation errors *globally* the variable +=elixir-enable-compilation-checking= can be set explicitly to =t= in your +dotfile but it is not recommended to do so because of the limitation described +above. + +Instead you should use directory local variables in order to enable the flycheck +checker only for certain projects. Directory local variables are stored in a +file named =.dir-local.el= usually at the root of a project. To easily add a +directory local variable use the key binding ~SPC f v d~ then choose the +=elixir-mode= and the variable name =elixir-enable-compilation-checking= with +a value of t. The result is a new file =.dir-local.el= with the following +contents: + +#+BEGIN_SRC elisp +;;; Directory Local Variables +;;; For more information see (info "(emacs) Directory Variables") + +((elixir-mode + (elixir-enable-compilation-checking . t))) +#+END_SRC + +Spacemacs marks the variable =elixir-enable-compilation-checking= as safe so +Emacs won't ask you if the variable is safe whenever an elixir file is opened. + +Remember that you can verify the flycheck checkers status with ~SPC e v~. + +* Key bindings +** Refcard +You find and overview of all the key-bindings on the [[file:alchemist-refcard.pdf][Alchemist-Refcard]]. + +** Help + +| Key Binding | Description | +|-------------+-------------------------------------| +| ~SPC m h :~ | Run custom search for help | +| ~SPC m h h~ | Show help of the current expression | +| ~SPC m h H~ | Toggle through search history | +| ~SPC m h r~ | Show help for current region | + +** Mix + +| Key Binding | Description | +|-------------+------------------------------------------------------------| +| ~SPC m m :~ | Prompt for a =mix= command | +| ~SPC m m c~ | Compile the whole application | +| ~SPC m m h~ | Show help for a specific =mix= command | +| ~SPC m m x~ | Run the given expression in the Elixir application context | + +** Project + +| Key Binding | Description | +|-------------+------------------------------------------------------------| +| ~SPC m p t~ | Open project test directory and list all test files. | +| ~SPC m g t~ | Toggle between a file and its tests in the current window. | +| ~SPC m g T~ | Toggle between a file and its tests in other window. | + +** Evaluation in place + +| Key Binding | Description | +|-------------+-----------------------------------------| +| ~SPC m e b~ | Evaluate buffer | +| ~SPC m e B~ | Evaluate buffer and insert result | +| ~SPC m e l~ | Evaluate current line | +| ~SPC m e L~ | Evaluate current line and insert result | +| ~SPC m e r~ | Evaluate region | +| ~SPC m e R~ | Evaluate region and insert result | + +** REPL interactions + +| Key Binding | Description | +|-------------+-----------------------------------------------------------------| +| ~SPC m s c~ | Compiles the current buffer in the IEx process. | +| ~SPC m s i~ | Start an =iex= inferior process | +| ~SPC m s I~ | Start an IEx process with mix (=iex -S mix=) | +| ~SPC m s l~ | Send current line to REPL buffer | +| ~SPC m s L~ | Send current line to REPL buffer and focus it in =insert state= | +| ~SPC m s m~ | Reloads the module in the current buffer in your IEx process | +| ~SPC m s r~ | Send region to REPL buffer | +| ~SPC m s R~ | Send region to REPL buffer and focus it in =insert state= | + +** Tests + +| Key Binding | Description | +|-------------+---------------------------------------| +| ~SPC m g t~ | Open the test file for current buffer | +| ~SPC m t a~ | Run all the tests | +| ~SPC m t b~ | Run all the tests from current buffer | +| ~SPC m t r~ | Rerun the last test | +| ~SPC m t t~ | Run test under point | + +** Compile + +| Key Binding | Description | +|-------------+----------------------------------------------------| +| ~SPC m c :~ | Run a custom compile command with =elixirc= | +| ~SPC m c b~ | Compile the current buffer with elixirc. =elixirc= | +| ~SPC m c f~ | Compile the given filename with =elixirc= | + +** Execute + +| Key Binding | Description | +|-------------+--------------------------------------------| +| ~SPC m x :~ | Run a custom execute command with =elixir= | +| ~SPC m x b~ | Run the current buffer through =elixir= | +| ~SPC m x f~ | Run =elixir= with the given filename | + +** Code Definition Jump + +| Key Binding | Description | +|-------------+----------------------------------------------------| +| ~SPC m g g~ | Jump to the elixir expression definition at point. | +| ~SPC m ​,​~ | Pop back to where ~SPC m g g~ was last invoked. | diff --git a/layers/+lang/elixir/alchemist-refcard.pdf b/layers/+lang/elixir/alchemist-refcard.pdf new file mode 100644 index 0000000..35338f6 Binary files /dev/null and b/layers/+lang/elixir/alchemist-refcard.pdf differ diff --git a/layers/+lang/elixir/alchemist-refcard.tex b/layers/+lang/elixir/alchemist-refcard.tex new file mode 100644 index 0000000..c4a8c5b --- /dev/null +++ b/layers/+lang/elixir/alchemist-refcard.tex @@ -0,0 +1,126 @@ +\documentclass[a4paper,8pt]{extarticle} + +\usepackage{textcomp} +\usepackage{fullpage} +\usepackage{boxedminipage} +\usepackage{multicol} +\usepackage[a4paper,left=0.8cm,right=0.8cm,top=1.5cm,bottom=2cm]{geometry} +\pagestyle{empty} + +\marginparwidth = 10pt + +\usepackage[T1]{fontenc} +\newcommand{\changefont}[3]{ +\fontfamily{#1} \fontseries{#2} \fontshape{#3} \selectfont} + +\newcommand{\docheading}{\Huge\centering{Alchemist Quick Reference Card [Spacemacs Version]}\normalsize\bigskip} +\newcommand{\helpgroup}[1]{\par\noindent\centering{\textbf{\large#1}\medskip}} +\newcommand{\helpkey}[2]{\par~~\noindent\textbf{#1}\hfill{#2}~~} +\newcommand{\group}[1]{\bigskip\par\noindent\textbf{\large#1}\bigskip} +\newcommand{\subgroup}[1]{\medskip\par\noindent\textbf{#1}\medskip} +\newcommand{\key}[2]{\par\noindent\textbf{#1}\hfill{#2}} +\newcommand{\meta}[1]{\textlangle{#1}\textrangle} + +\begin{document} + +\changefont{pag}{m}{n} + +\renewcommand{\baselinestretch}{1.2} + +\docheading + +\bigskip + +\begin{boxedminipage}[t]{11cm} + +\medskip + +\helpgroup{Getting help in Emacs} + +\helpkey{SPC h d f}{describe a function} +\helpkey{SPC h d v}{describe a variable} +\helpkey{SPC h d k}{describe a key} +\helpkey{SPC h d m}{describe current modes} +\helpkey{SPC h d p}{describe a package} +\helpkey{SPC h m}{search available man pages} + +\medskip + +\end{boxedminipage} + +\setlength{\bigskipamount}{1cm} + +\bigskip +\bigskip + +\setlength{\columnsep}{1cm} + +\begin{multicols}{2} + +\group{Mix} + +\key{SPC m m :}{alchemist-mix} +\key{SPC m t a}{alchemist-mix-test} +\key{SPC m m c}{alchemist-mix-compile} +\key{SPC m t f}{alchemist-mix-test-file} +\key{SPC m t b}{alchemist-mix-test-this-buffer} +\key{SPC m t t}{alchemist-mix-test-at-point} + +\group{Compilation} + +\key{SPC m c :}{alchemist-compile} +\key{SPC m c f}{alchemist-compile-file} +\key{SPC m c b}{alchemist-compile-this-buffer} + +\group{Execution} + +\key{SPC m x :}{alchemist-execute} +\key{SPC m x f}{alchemist-execute-file} +\key{SPC m x b}{alchemist-execute-this-buffer} + +\group{IEx} + +\key{SPC m s i}{alchemist-iex-run} +\key{SPC m s I}{alchemist-iex-project-run} +\key{SPC m s l}{alchemist-iex-send-current-line} +\key{SPC m s L}{alchemist-iex-send-current-line-and-go} +\key{SPC m s r}{alchemist-iex-send-region} +\key{SPC m s R}{alchemist-iex-send-region-and-go} +\key{SPC m s c}{alchemist-iex-compile-this-buffer} + +\group{Documentation Lookup} + +\key{SPC m h :}{alchemist-help} +\key{SPC m h H}{alchemist-help-history} +\key{SPC m h h}{alchemist-help-search-at-point} +\key{SPC m h r}{alchemist-help-search-marked-region} + +\group{Project} + +\key{SPC m p t}{alchemist-project-find-test} +\key{SPC m g t}{alchemist-project-toggle-file-and-tests} +\key{SPC m g T}{alchemist-project-toggle-file-and-tests-other-window} + +\group{Eval} + +\key{SPC m e l}{alchemist-eval-current-line} +\key{SPC m e L}{alchemist-eval-print-current-line} +\key{SPC m e j}{alchemist-eval-quoted-current-line} +\key{SPC m e J}{alchemist-eval-print-quoted-current-line} +\key{SPC m e r}{alchemist-eval-region} +\key{SPC m e R}{alchemist-eval-print-region} +\key{SPC m e u}{alchemist-eval-quoted-region} +\key{SPC m e U}{alchemist-eval-print-quoted-region} +\key{SPC m e b}{alchemist-eval-buffer} +\key{SPC m e B}{alchemist-eval-print-buffer} +\key{SPC m e v}{alchemist-eval-quoted-buffer} +\key{SPC m e V}{alchemist-eval-print-quoted-buffer} + +\group{Definition Lookup} + +\key{SPC m g g}{alchemist-goto-definition-at-point} +\key{SPC m ,}{alchemist-goto-jump-back} + +\end{multicols} + +\end{document} diff --git a/layers/+lang/elixir/config.el b/layers/+lang/elixir/config.el new file mode 100644 index 0000000..a109c1a --- /dev/null +++ b/layers/+lang/elixir/config.el @@ -0,0 +1,23 @@ +;;; config.el --- Elixir Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(defvar elixir-enable-compilation-checking nil + "If non-nil syntax checking is enable for compilation. +Default is nil because Elixir compilation is based on macros and thus it +is unsafe. Activate this option only for trusted code, usage of a +directory variable is recommended.") + +(spacemacs|defvar-company-backends elixir-mode) +(spacemacs|defvar-company-backends alchemist-iex-mode) + +(spacemacs|define-jump-handlers elixir-mode) diff --git a/layers/+lang/elixir/funcs.el b/layers/+lang/elixir/funcs.el new file mode 100644 index 0000000..979e070 --- /dev/null +++ b/layers/+lang/elixir/funcs.el @@ -0,0 +1,21 @@ +;;; funcs.el --- Elixir Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spacemacs//elixir-do-end-close-action (id action context) + (when (eq action 'insert) + (newline-and-indent) + (forward-line -1) + (indent-according-to-mode))) + +(defun spacemacs//elixir-enable-compilation-checking () + "Enable compile checking if `elixir-enable-compilation-checking' is non nil." + (when (or elixir-enable-compilation-checking) + (flycheck-mix-setup))) diff --git a/layers/+lang/elixir/img/alchemist.png b/layers/+lang/elixir/img/alchemist.png new file mode 100644 index 0000000..46d9d0d Binary files /dev/null and b/layers/+lang/elixir/img/alchemist.png differ diff --git a/layers/+lang/elixir/img/elixir.png b/layers/+lang/elixir/img/elixir.png new file mode 100644 index 0000000..9cc895c Binary files /dev/null and b/layers/+lang/elixir/img/elixir.png differ diff --git a/layers/+lang/elixir/packages.el b/layers/+lang/elixir/packages.el new file mode 100644 index 0000000..a84df8c --- /dev/null +++ b/layers/+lang/elixir/packages.el @@ -0,0 +1,178 @@ +;;; packages.el --- Elixir Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq elixir-packages + '( + alchemist + company + elixir-mode + flycheck + flycheck-mix + ggtags + helm-gtags + ob-elixir + popwin + smartparens + )) + +(defun elixir/post-init-company () + (spacemacs|add-company-hook elixir-mode) + (spacemacs|add-company-hook alchemist-iex-mode)) + +(defun elixir/init-alchemist () + (use-package alchemist + :defer t + :init + (progn + (spacemacs/register-repl 'alchemist 'alchemist-iex-run "alchemist") + (add-hook 'elixir-mode-hook 'alchemist-mode) + (setq alchemist-project-compile-when-needed t + alchemist-test-status-modeline nil) + ;; setup company backends + (push 'alchemist-company company-backends-elixir-mode) + (push 'alchemist-company company-backends-alchemist-iex-mode) + (add-to-list 'spacemacs-jump-handlers-elixir-mode + 'alchemist-goto-definition-at-point)) + :config + (spacemacs/declare-prefix-for-mode 'elixir-mode "mc" "compile") + (spacemacs/declare-prefix-for-mode 'elixir-mode "me" "eval") + (spacemacs/declare-prefix-for-mode 'elixir-mode "mp" "project") + (spacemacs/declare-prefix-for-mode 'elixir-mode "mh" "help") + (spacemacs/declare-prefix-for-mode 'elixir-mode "mt" "test") + (spacemacs/declare-prefix-for-mode 'elixir-mode "ms" "iex") + (spacemacs/declare-prefix-for-mode 'elixir-mode "mm" "mix") + (spacemacs/declare-prefix-for-mode 'elixir-mode "mx" "execute") + (spacemacs/declare-prefix-for-mode 'elixir-mode "mg" "goto") + (spacemacs/set-leader-keys-for-major-mode 'elixir-mode + "el" 'alchemist-eval-current-line + "eL" 'alchemist-eval-print-current-line + "er" 'alchemist-eval-region + "eR" 'alchemist-eval-print-region + "eb" 'alchemist-eval-buffer + "eB" 'alchemist-eval-print-buffer + "ej" 'alchemist-eval-quoted-current-line + "eJ" 'alchemist-eval-print-quoted-current-line + "eu" 'alchemist-eval-quoted-region + "eU" 'alchemist-eval-print-quoted-region + "ev" 'alchemist-eval-quoted-buffer + "eV" 'alchemist-eval-print-quoted-buffer + + "pt" 'alchemist-project-find-test + "gt" 'alchemist-project-toggle-file-and-tests + "gT" 'alchemist-project-toggle-file-and-tests-other-window + + "h:" 'alchemist-help + "hH" 'alchemist-help-history + "hh" 'alchemist-help-search-at-point + "hr" 'alchemist-help-search-marked-region + + "m:" 'alchemist-mix + "mc" 'alchemist-mix-compile + "mx" 'alchemist-mix-run + "mh" 'alchemist-mix-help + + "'" 'alchemist-iex-run + "sc" 'alchemist-iex-compile-this-buffer + "si" 'alchemist-iex-run + "sI" 'alchemist-iex-project-run + "sl" 'alchemist-iex-send-current-line + "sL" 'alchemist-iex-send-current-line-and-go + "sm" 'alchemist-iex-reload-module + "sr" 'alchemist-iex-send-region + "sR" 'alchemist-iex-send-region-and-go + + "ta" 'alchemist-mix-test + "tb" 'alchemist-mix-test-this-buffer + "tt" 'alchemist-mix-test-at-point + "tf" 'alchemist-test-file + "tn" 'alchemist-test-jump-to-next-test + "tp" 'alchemist-test-jump-to-previous-test + "tr" 'alchemist-mix-rerun-last-test + + "xb" 'alchemist-execute-this-buffer + "xf" 'alchemist-execute-file + "x:" 'alchemist-execute + + "cb" 'alchemist-compile-this-buffer + "cf" 'alchemist-compile-file + "c:" 'alchemist-compile + + "," 'alchemist-goto-jump-back) + + (dolist (mode (list alchemist-compile-mode-map + alchemist-eval-mode-map + alchemist-execute-mode-map + alchemist-message-mode-map + alchemist-help-minor-mode-map + alchemist-mix-mode-map + alchemist-macroexpand-mode-map + alchemist-refcard-mode-map + alchemist-test-report-mode-map)) + (evil-define-key 'normal mode + (kbd "q") 'quit-window)))) + +(defun elixir/init-flycheck-mix () + (use-package flycheck-mix + :commands (flycheck-mix-setup) + :init + (progn + (add-to-list 'safe-local-variable-values + (cons 'elixir-enable-compilation-checking nil)) + (add-to-list 'safe-local-variable-values + (cons 'elixir-enable-compilation-checking t)) + (add-hook 'elixir-mode-local-vars-hook + 'spacemacs//elixir-enable-compilation-checking)))) + +(defun elixir/init-elixir-mode () + (use-package elixir-mode + :defer t)) + +(defun elixir/post-init-flycheck () + (spacemacs/add-flycheck-hook 'elixir-mode)) + +(defun elixir/pre-init-org () + (spacemacs|use-package-add-hook org + :post-config (add-to-list 'org-babel-load-languages '(elixir . t)))) + +(defun elixir/init-ob-elixir () + (spacemacs|use-package-add-hook org + :post-config + (use-package ob-elixir + :init (add-to-list 'org-babel-load-languages '(elixir . t))))) + + +(defun elixir/pre-init-popwin () + (spacemacs|use-package-add-hook popwin + :post-config + (push '("*mix*" :tail t :noselect t) popwin:special-display-config))) + +(defun elixir/pre-init-smartparens () + (spacemacs|use-package-add-hook smartparens + :post-config + (progn + (sp-with-modes '(elixir-mode) + (sp-local-pair + "->" "end" + :when '(("RET")) + :post-handlers '(:add spacemacs//elixir-do-end-close-action) + :actions '(insert))) + (sp-with-modes '(elixir-mode) + (sp-local-pair + "do" "end" + :when '(("SPC" "RET")) + :post-handlers '(:add spacemacs//elixir-do-end-close-action) + :actions '(insert)))))) + +(defun elixir/post-init-ggtags () + (add-hook 'elixir-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun elixir/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'elixir-mode)) diff --git a/layers/+lang/elm/README.org b/layers/+lang/elm/README.org new file mode 100644 index 0000000..8dd6396 --- /dev/null +++ b/layers/+lang/elm/README.org @@ -0,0 +1,208 @@ +#+TITLE: Elm layer + +[[file:img/elm.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#elm-platform][Elm Platform]] + - [[#os-x-and-windows-installers][OS X and Windows installers]] + - [[#universal-installer-using-npm][Universal installer using npm]] + - [[#source-code][Source code]] + - [[#elm-oracle][elm-oracle]] + - [[#elm-format][elm-format]] + - [[#basic-usage-tips][Basic usage tips]] + - [[#compilation][Compilation]] + - [[#reactor][Reactor]] + - [[#sort-imports-on-save][Sort imports on save]] + - [[#key-bindings][Key bindings]] + - [[#elm-make][elm-make]] + - [[#elm-repl][elm-repl]] + - [[#elm-reactor][elm-reactor]] + - [[#elm-package][elm-package]] + - [[#package-list-buffer][package list buffer]] + - [[#elm-oracle-1][elm-oracle]] + - [[#elm-format-1][elm-format]] + - [[#refactoring][Refactoring]] + +* Description +This layer adds support for [[http://elm-lang.org][Elm]]. + +It relies on [[https://github.com/jcollard/elm-mode][elm-mode]] and [[https://github.com/bsermons/flycheck-elm][flycheck-elm]] to provide the following features: +- Syntax highlighting. +- Intelligent indentation +- Auto-completion integration for company (default) or auto-complete modes, + with using elm-oracle +- Syntax checking support using flycheck +- Integration with elm-make +- Integration with elm-repl +- Integration with elm-reactor +- Integration with elm-package + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =elm= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Elm Platform +The ~elm-platform~ is a bundle of tools, including the ~elm-compiler~, +~elm-make~, ~elm-reactor~, ~elm-repl~ and ~elm-package~. + +Depending on the method of installation, the ~elm-mode~ package would need to be +able to access commands such as ~elm-reactor~ or ~elm-make~. + +*** OS X and Windows installers +Official installers for these operating systems are available from: +[[http://elm-lang.org/install][http://elm-lang.org/install]] + +*** Universal installer using npm +A npm based installer is available to, and provides pre-compiled binaries for +certain operating system and architectures. +#+BEGIN_SRC sh + npm install --global elm +#+END_SRC +Also, note that you might need to set the ~ELM_HOME~ environment variables to +the corresponding directory created by the installer. + +If you are facing problems with previewing a buffer with ~elm-reactor~ ensure +that the absolute path of the npm global bin file is on your path within emacs + +OS X Users facing problems with ~elm-reactor~ failing to properly install or +run, see this issue [[https://github.com/kevva/elm-bin/issues/28][https://github.com/kevva/elm-bin/issues/28]]. + +*** Source code +To build from source, see instructions here: +[[https://github.com/elm-lang/elm-platform][https://github.com/elm-lang/elm-platform]] + +** elm-oracle +~elm-oracle~ can be used to show type signatures and docs for tokens under the +cursor and provide support for auto-completion, but it is not part of the +standard elm-platform. + +Both the "company" and "auto-complete" backends are supported, but this layer +is configured with company. + +To install ~elm-oracle~, install ~node.js~ and ~npm~, then +run this command: + +#+BEGIN_SRC sh + npm install -g elm-oracle +#+END_SRC + +** elm-format +~elm-format~ can be used to format elm code according to a standard set of +rules. + +To install ~elm-format~ follow the the instructions for the version of elm +installed: https://github.com/avh4/elm-format + +Also, note that if you use homebrew to install ~elm-format~ the installed exe +has a version suffix, the installed command name can be set in your +=~/spacemacs=: + +#+BEGIN_SRC emacs-lisp + (elm :variables + elm-format-command "elm-format-0.17") +#+END_SRC + +* Basic usage tips +** Compilation +To control the name of the compiled JavaScript file, use ~SPC m c B~ instead of +~SPC m c b~. This will overwrite the ~--output~ parameter of ~elm-make~ to +~[buffer-name].js~ instead of the default. + +** Reactor +~elm-reactor~ is an interactive development tool, used to develop and debug Elm +programs. It will automatically compile an Elm program, and run it in the +browser, with editor agnostic support for hot-swapping and time-travel +debugging. + +To preview ~Main.elm~, press ~C-c C-m~ (or ~SPC m R m~). +Alternatively, to preview from buffer, press ~C-u C-c C-n~ (or ~SPC m R +n~). To preview in debug mode, prefix with ~C-u~ (or ~SPC u~). + +By default, ~elm-reactor~ with launch with its own generated index.html. To use +a custom html, you'd need to load the debuger excplictly and use an http daemon +to serve your custom file. + +If needed, default values for host and port used by for the elm-reactor server +can be controlled by passing in these variables in your =~/.spacemacs=: + +#+BEGIN_SRC emacs-lisp + (elm :variables + elm-reactor-port "3000" ; default 8000 + elm-reactor-address "0.0.0.0") ; default 127.0.0.1 +#+END_SRC + +** Sort imports on save +Set ~elm-sort-imports-on-save~ to ~t~ to sort the imports in the current file on +every save. + +#+BEGIN_SRC emacs-lisp + (elm :variables elm-sort-imports-on-save t) +#+END_SRC + +* Key bindings +** elm-make + +| Key Binding | Description | +|-------------+----------------------------------------------| +| ~SPC m c b~ | elm-compile-buffer | +| ~SPC m c B~ | spacemacs/elm-compile-buffer-override-output | +| ~SPC m c m~ | elm-compile-main | + +** elm-repl + +| Key Binding | Description | +|-------------+------------------------------------------------------------| +| ~SPC m s i~ | elm-repl-load | +| ~SPC m s f~ | send current function to REPL | +| ~SPC m s F~ | send current function to REPL and focus it in insert state | +| ~SPC m s r~ | send current region to REPL | +| ~SPC m s R~ | send current region to REPL and focus it in insert state | + +** elm-reactor + +| Key Binding | Description | +|-------------+--------------------| +| ~SPC m R n~ | elm-preview-buffer | +| ~SPC m R m~ | elm-preview-main | + +** elm-package + +| Key Binding | Description | +|-------------+--------------------------| +| ~SPC m p i~ | elm-import | +| ~SPC m p c~ | elm-package-catalog | +| ~SPC m p d~ | elm-documentation-lookup | + +*** package list buffer + +| Key Binding | Description | +|-------------+---------------------| +| ~g~ | elm-package-refresh | +| ~v~ | elm-package-view | +| ~m~ | elm-package-mark | +| ~u~ | elm-package-unmark | +| ~x~ | elm-package-install | +| ~q~ | quit-window | + +** elm-oracle + +| Key Binding | Description | +|-------------+--------------------------| +| ~SPC m h h~ | elm-oracle-doc-at-point | +| ~SPC m h t~ | elm-oracle-type-at-point | + +** elm-format + +| Key Binding | Description | +| ~SPC m = b~ | elm-mode-format-buffer | + +** Refactoring + +| Key Binding | Description | +|-------------+------------------| +| ~SPC m r i~ | elm-sort-imports | diff --git a/layers/+lang/elm/config.el b/layers/+lang/elm/config.el new file mode 100644 index 0000000..f2ef182 --- /dev/null +++ b/layers/+lang/elm/config.el @@ -0,0 +1,12 @@ +;;; config.el --- elm Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(spacemacs|defvar-company-backends elm-mode) diff --git a/layers/+lang/elm/funcs.el b/layers/+lang/elm/funcs.el new file mode 100644 index 0000000..722a844 --- /dev/null +++ b/layers/+lang/elm/funcs.el @@ -0,0 +1,34 @@ +;;; funcs.el --- Elm Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + +;; elm-mode + +(defun spacemacs//elm-find-root () + (setq default-directory (elm--find-dependency-file-path))) + +(defun spacemacs/elm-compile-buffer-output () + (interactive) + (let* ((fname (format "%s.js" (downcase (file-name-base (buffer-file-name)))))) + (elm-compile--file (elm--buffer-local-file-name) fname))) + +(defun spacemacs/elm-repl-push-decl-focus () + "Send current function to the REPL and focus it in insert state." + (interactive) + (elm-repl-push-decl) + (run-elm-interactive) + (evil-insert-state)) + +(defun spacemacs/elm-repl-push-focus () + "Send current region to the REPL and focus it in insert state." + (elm-repl-push) + (run-elm-interactive) + (evil-insert-state)) diff --git a/layers/+lang/elm/img/elm.png b/layers/+lang/elm/img/elm.png new file mode 100644 index 0000000..ab9154b Binary files /dev/null and b/layers/+lang/elm/img/elm.png differ diff --git a/layers/+lang/elm/packages.el b/layers/+lang/elm/packages.el new file mode 100644 index 0000000..c0a46ac --- /dev/null +++ b/layers/+lang/elm/packages.el @@ -0,0 +1,108 @@ +;;; packages.el --- elm Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq elm-packages + '( + company + elm-mode + flycheck + (flycheck-elm :toggle (configuration-layer/package-usedp 'flycheck)) + popwin + smartparens + )) + +(defun elm/post-init-company () + (spacemacs|add-company-hook elm-mode) + (add-hook 'elm-mode-hook 'elm-oracle-setup-completion) + (push 'company-elm company-backends-elm-mode)) + +(defun elm/post-init-flycheck () + (add-hook 'elm-mode-hook 'flycheck-mode) + (add-hook 'elm-mode-hook 'spacemacs//elm-find-root)) + +(defun elm/init-flycheck-elm () + "Initialize flycheck-elm" + (use-package flycheck-elm + :defer t + :init (add-hook 'flycheck-mode-hook 'flycheck-elm-setup t))) + +(defun elm/init-elm-mode () + "Initialize elm-mode" + (use-package elm-mode + :mode ("\\.elm\\'" . elm-mode) + :init + (progn + (spacemacs/register-repl 'elm-mode 'elm-repl-load "elm") + + (defun spacemacs/init-elm-mode () + "Disable electric-indent-mode and let indentation cycling feature work" + (if (fboundp 'electric-indent-local-mode) + (electric-indent-local-mode -1))) + + (add-hook 'elm-mode-hook 'spacemacs/init-elm-mode)) + :config + (progn + (push "\\*elm\\*" spacemacs-useful-buffers-regexp) + + (spacemacs/set-leader-keys-for-major-mode 'elm-mode + ;; format + "=b" 'elm-mode-format-buffer + ;; make + "cb" 'elm-compile-buffer + "cB" 'spacemacs/elm-compile-buffer-output + "cm" 'elm-compile-main + ;; oracle + "hh" 'elm-oracle-doc-at-point + "ht" 'elm-oracle-type-at-point + ;; refactoring + "ri" 'elm-sort-imports + ;; repl + "'" 'elm-repl-load + "si" 'elm-repl-load + "sf" 'elm-repl-push-decl + "sF" 'spacemacs/elm-repl-push-decl-focus + "sr" 'elm-repl-push + "sR" 'spacemacs/elm-repl-push-focus + ;; reactor + "Rn" 'elm-preview-buffer + "Rm" 'elm-preview-main + ;; package + "pi" 'elm-import + "pc" 'elm-package-catalog + "pd" 'elm-documentation-lookup) + + (dolist (x '(("m=" . "format") + ("mc" . "compile") + ("mh" . "help") + ("mp" . "package") + ("mR" . "reactor") + ("mr" . "refactor") + ("ms" . "repl"))) + (spacemacs/declare-prefix-for-mode 'elm-mode (car x) (cdr x))) + + (evilified-state-evilify elm-package-mode elm-package-mode-map + "g" 'elm-package-refresh + "v" 'elm-package-view + "m" 'elm-package-mark + "u" 'elm-package-unmark + "x" 'elm-package-install + "q" 'quit-window)))) + +(defun elm/pre-init-popwin () + (spacemacs|use-package-add-hook popwin + :post-config + (push '("*elm*" :tail t :noselect t) popwin:special-display-config) + (push '("*elm-make*" :tail t :noselect t) popwin:special-display-config))) + +(defun elm/post-init-smartparens () + (if dotspacemacs-smartparens-strict-mode + (add-hook 'elm-mode-hook #'smartparens-strict-mode) + (add-hook 'elm-mode-hook #'smartparens-mode))) diff --git a/layers/+lang/emacs-lisp/README.org b/layers/+lang/emacs-lisp/README.org new file mode 100644 index 0000000..358e38f --- /dev/null +++ b/layers/+lang/emacs-lisp/README.org @@ -0,0 +1,73 @@ +#+TITLE: Emacs Lisp layer + +[[file:img/emacs.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#auto-compile][Auto-compile]] + - [[#key-bindings][Key bindings]] + - [[#working-with-lisp-files-barfage-slurpage--more][Working with lisp files (barfage, slurpage & more)]] + - [[#leader][Leader]] + - [[#srefactor][srefactor]] + +* Description +This layer gathers all the configuration related to emacs-lisp. This should +always be in your dotfile, it is not recommended to uninstall it. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =emacs-lisp= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Auto-compile +This layer adds the [[https://github.com/tarsius/auto-compile][auto-compile]] package to automatically keep the byte-compiled +version of your Emacs lisp files synced with the uncompiled version on every +save. If there are any compiler errors in the file, you will see a counter show +up in the mode line. You can hover over these numbers to get a description or +view the compiler output with the ~SPC m c l~ key binding. To disable the +feature use this line in your =dotspacemacs/user-config= function. + +#+BEGIN_SRC emacs-lisp + (remove-hook 'emacs-lisp-mode-hook 'auto-compile-mode) +#+END_SRC + +You can also exclude the =auto-compile= package. + +* Key bindings +** Working with lisp files (barfage, slurpage & more) +Spacemacs comes with a special ~lisp-state~ for working with lisp code that +supports slurpage, barfage and more tools you'll likely want when working with +lisp. + +As this state works the same for all files, the documentation is in global +[[https://github.com/syl20bnr/spacemacs/blob/master/doc/DOCUMENTATION.org#lisp-key-bindings][DOCUMENTATION.org]]. In general, use ~SPC k~ to interact with the lisp-state. + +** Leader + +| Key Binding | Description | +|----------------------------+------------------------------------------------------------| +| ~SPC m g g~ | go to definition of symbol under point | +| ~SPC m h h~ | describe symbol at point | +| ~SPC m c c~ | byte compile the current file | +| ~SPC m c l~ | popup compile-log buffer | +| ~SPC m e $~ or ~SPC m e l~ | go to end of current line and evaluate | +| ~SPC m e b~ | evaluate current buffer | +| ~SPC m e c~ | evaluate current form (start with =defun=, =setq=, etc...) | +| ~SPC m e e~ | evaluate sexp before point | +| ~SPC m e r~ | evaluate current region | +| ~SPC m e f~ | evaluation current function | +| ~SPC m ​,​~ | toggle =lisp state= | +| ~SPC m t b~ | run tests of current buffer | +| ~SPC m t q~ | run =ert= | +| ~SPC m d m~ | open [[https://github.com/joddie/macrostep][macrostep]] transient-state | + +** srefactor +The [[file:../../semantic/README.org][semantic]] layer should be installed for these key bindings to become active. + +| Key Binding | Description | +|-------------+-------------------------| +| ~SPC m = b~ | format current buffer | +| ~SPC m = f~ | format current function | +| ~SPC m = o~ | format all on one line | +| ~SPC m = s~ | format current sexp | diff --git a/layers/+lang/emacs-lisp/config.el b/layers/+lang/emacs-lisp/config.el new file mode 100644 index 0000000..2404f5e --- /dev/null +++ b/layers/+lang/emacs-lisp/config.el @@ -0,0 +1,18 @@ +;;; config.el --- Emacs Lisp Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(spacemacs|defvar-company-backends emacs-lisp-mode) +(spacemacs|defvar-company-backends ielm-mode) + +(spacemacs|define-jump-handlers emacs-lisp-mode) +(spacemacs|define-jump-handlers lisp-interaction-mode) diff --git a/layers/+lang/emacs-lisp/funcs.el b/layers/+lang/emacs-lisp/funcs.el new file mode 100644 index 0000000..4b07d98 --- /dev/null +++ b/layers/+lang/emacs-lisp/funcs.el @@ -0,0 +1,31 @@ +;;; funcs.el --- Emacs Lisp functions File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + + +;; idea from http://www.reddit.com/r/emacs/comments/312ge1/i_created_this_function_because_i_was_tired_of/ +(defun spacemacs/eval-current-form () + "Looks for the current def* or set* command then evaluates, unlike `eval-defun', does not go to topmost function" + (interactive) + (save-excursion + (search-backward-regexp "(def\\|(set") + (forward-list) + (call-interactively 'eval-last-sexp))) + +(defun spacemacs/nav-find-elisp-thing-at-point-other-window () + "Find thing under point and go to it another window." + (interactive) + (let ((symb (variable-at-point))) + (if (and symb + (not (equal symb 0)) + (not (fboundp symb))) + (find-variable-other-window symb) + (find-function-at-point)))) diff --git a/layers/+lang/emacs-lisp/img/emacs.png b/layers/+lang/emacs-lisp/img/emacs.png new file mode 100644 index 0000000..9ab43d7 Binary files /dev/null and b/layers/+lang/emacs-lisp/img/emacs.png differ diff --git a/layers/+lang/emacs-lisp/packages.el b/layers/+lang/emacs-lisp/packages.el new file mode 100644 index 0000000..277b042 --- /dev/null +++ b/layers/+lang/emacs-lisp/packages.el @@ -0,0 +1,202 @@ +;;; packages.el --- Emacs Lisp Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq emacs-lisp-packages + '( + auto-compile + company + eldoc + elisp-slime-nav + (emacs-lisp :location built-in) + evil + flycheck + ggtags + helm-gtags + (ielm :location built-in) + macrostep + semantic + smartparens + srefactor)) + +(defun emacs-lisp/init-ielm () + (use-package ielm + :defer t + :init + (progn + (spacemacs/register-repl 'ielm 'ielm) + (dolist (mode '(emacs-lisp-mode lisp-interaction-mode)) + (spacemacs/declare-prefix-for-mode mode "ms" "ielm") + (spacemacs/set-leader-keys-for-major-mode mode + "'" 'ielm + "si" 'ielm))) + :config + (defun ielm-indent-line () + (interactive) + (let ((current-point (point))) + (save-restriction + (narrow-to-region (search-backward-regexp "^ELISP>") (goto-char current-point)) + (lisp-indent-line)))))) + +(defun emacs-lisp/post-init-company () + (spacemacs|add-company-hook ielm-mode) + (push '(company-files company-capf) company-backends-ielm-mode)) + +(defun emacs-lisp/post-init-eldoc () + (add-hook 'emacs-lisp-mode-hook 'eldoc-mode)) + +(defun emacs-lisp/init-auto-compile () + (use-package auto-compile + :defer t + :diminish (auto-compile-mode . "") + :init + (progn + (setq auto-compile-display-buffer nil + ;; lets spaceline manage the mode-line + auto-compile-use-mode-line nil + auto-compile-mode-line-counter t) + (add-hook 'emacs-lisp-mode-hook 'auto-compile-mode)) + :config + (progn + (spacemacs/set-leader-keys-for-major-mode 'emacs-lisp-mode + "cl" 'auto-compile-display-log)))) + +(defun emacs-lisp/init-elisp-slime-nav () + ;; Elisp go-to-definition with M-. and back again with M-, + (use-package elisp-slime-nav + :defer t + :diminish elisp-slime-nav-mode + :init + (progn + (add-hook 'emacs-lisp-mode-hook 'elisp-slime-nav-mode) + (dolist (mode '(emacs-lisp-mode lisp-interaction-mode)) + (spacemacs/declare-prefix-for-mode mode "mg" "find-symbol") + (spacemacs/declare-prefix-for-mode mode "mh" "help") + (spacemacs/set-leader-keys-for-major-mode mode + "hh" 'elisp-slime-nav-describe-elisp-thing-at-point) + (let ((jumpl (intern (format "spacemacs-jump-handlers-%S" mode)))) + (add-to-list jumpl 'elisp-slime-nav-find-elisp-thing-at-point)))))) + +(defun emacs-lisp/init-emacs-lisp () + (dolist (mode '(emacs-lisp-mode lisp-interaction-mode)) + (spacemacs/declare-prefix-for-mode mode "mc" "compile") + (spacemacs/declare-prefix-for-mode mode "me" "eval") + (spacemacs/declare-prefix-for-mode mode "mt" "tests") + (spacemacs/set-leader-keys-for-major-mode mode + "cc" 'emacs-lisp-byte-compile + "e$" 'lisp-state-eval-sexp-end-of-line + "eb" 'eval-buffer + "ee" 'eval-last-sexp + "er" 'eval-region + "ef" 'eval-defun + "el" 'lisp-state-eval-sexp-end-of-line + "gG" 'spacemacs/nav-find-elisp-thing-at-point-other-window + "," 'lisp-state-toggle-lisp-state + "tb" 'spacemacs/ert-run-tests-buffer + "tq" 'ert)) + ;; company support + (push 'company-capf company-backends-emacs-lisp-mode) + (spacemacs|add-company-hook emacs-lisp-mode)) + +(defun emacs-lisp/init-macrostep () + (use-package macrostep + :defer t + :mode ("\\*.el\\'" . emacs-lisp-mode) + :init + (progn + (evil-define-key 'normal macrostep-keymap "q" 'macrostep-collapse-all) + (spacemacs|define-transient-state macrostep + :title "MacroStep Transient State" + :doc "\n[_e_] expand [_c_] collapse [_n_/_N_] next/previous [_q_] quit" + :foreign-keys run + :bindings + ("e" macrostep-expand) + ("c" macrostep-collapse) + ("n" macrostep-next-macro) + ("N" macrostep-prev-macro) + ("q" macrostep-collapse-all :exit t)) + (spacemacs/set-leader-keys-for-major-mode 'emacs-lisp-mode + "dm" 'spacemacs/macrostep-transient-state/body)))) + +(defun emacs-lisp/post-init-evil () + (add-hook 'emacs-lisp-mode-hook + (lambda () + (spacemacs|define-text-object ";" "elisp-comment" ";; " "")))) + +(defun emacs-lisp/post-init-flycheck () + ;; Don't activate flycheck by default in elisp + ;; because of too much false warnings + ;; (spacemacs/add-flycheck-hook 'emacs-lisp-mode) + + ;; Make flycheck recognize packages in loadpath + ;; i.e (require 'company) will not give an error now + (setq flycheck-emacs-lisp-load-path 'inherit)) + +(defun emacs-lisp/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'emacs-lisp-mode)) + +(defun emacs-lisp/post-init-ggtags () + (add-hook 'emacs-lisp-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun emacs-lisp/post-init-semantic () + (add-hook 'emacs-lisp-mode-hook 'semantic-mode) + (with-eval-after-load 'semantic + (semantic-default-elisp-setup))) + +(defun emacs-lisp/post-init-srefactor () + (add-hook 'emacs-lisp-mode-hook 'spacemacs/lazy-load-srefactor) + (use-package srefactor-lisp + :commands (srefactor-lisp-format-buffer + srefactor-lisp-format-defun + srefactor-lisp-format-sexp + srefactor-lisp-one-line) + :init + (dolist (mode '(emacs-lisp-mode lisp-interaction-mode)) + (spacemacs/declare-prefix-for-mode mode "m=" "srefactor") + (spacemacs/set-leader-keys-for-major-mode mode + "=b" 'srefactor-lisp-format-buffer + "=d" 'srefactor-lisp-format-defun + "=o" 'srefactor-lisp-one-line + "=s" 'srefactor-lisp-format-sexp)))) + +(defun emacs-lisp/post-init-smartparens () + (advice-remove 'elisp--preceding-sexp 'evil--preceding-sexp) + + (defun spacemacs/eval-current-form-sp (&optional arg) + "Call `eval-last-sexp' after moving out of one level of +parentheses. Will exit any strings and/or comments first. +Requires smartparens because all movement is done using +`sp-up-sexp'. An optional ARG can be used which is passed to +`sp-up-sexp' to move out of more than one sexp." + (interactive "p") + (require 'smartparens) + (save-excursion + (let ((max 10)) + (while (and (> max 0) + (sp-point-in-string-or-comment)) + (decf max) + (sp-up-sexp))) + (sp-up-sexp arg) + (call-interactively 'eval-last-sexp))) + + (defun spacemacs/eval-current-symbol-sp () + "Call `eval-last-sexp' on the symbol around point. Requires +smartparens because all movement is done using +`sp-forward-symbol'." + (interactive) + (require 'smartparens) + (save-excursion + (sp-forward-symbol) + (call-interactively 'eval-last-sexp))) + + (dolist (mode '(emacs-lisp-mode lisp-interaction-mode)) + (spacemacs/set-leader-keys-for-major-mode mode + "ec" 'spacemacs/eval-current-form-sp + "es" 'spacemacs/eval-current-symbol-sp))) diff --git a/layers/+lang/erlang/README.org b/layers/+lang/erlang/README.org new file mode 100644 index 0000000..56b0d72 --- /dev/null +++ b/layers/+lang/erlang/README.org @@ -0,0 +1,17 @@ +#+TITLE: Erlang layer + +[[file:img/erlang.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + +* Description + +Very basic layer for Erlang with support for basic =syntax-checking= and +=auto-completion= with the corresponding layers. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =erlang= to the existing =dotspacemacs-configuration-layers= list in this +file. diff --git a/layers/+lang/erlang/config.el b/layers/+lang/erlang/config.el new file mode 100644 index 0000000..b47e5df --- /dev/null +++ b/layers/+lang/erlang/config.el @@ -0,0 +1,14 @@ +;;; packages.el --- Erlang Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; variables + +(spacemacs|define-jump-handlers erlang-mode) diff --git a/layers/+lang/erlang/img/erlang.png b/layers/+lang/erlang/img/erlang.png new file mode 100644 index 0000000..6d60346 Binary files /dev/null and b/layers/+lang/erlang/img/erlang.png differ diff --git a/layers/+lang/erlang/packages.el b/layers/+lang/erlang/packages.el new file mode 100644 index 0000000..646f03a --- /dev/null +++ b/layers/+lang/erlang/packages.el @@ -0,0 +1,52 @@ +;;; packages.el --- Erlang Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq erlang-packages + '( + company + erlang + ggtags + helm-gtags + flycheck + )) + +(defun erlang/post-init-company () + (add-hook 'erlang-mode-hook 'company-mode)) + +(defun erlang/init-erlang () + (use-package erlang + :defer t + :init + (progn + ;; explicitly run prog-mode hooks since erlang mode does is not + ;; derived from prog-mode major-mode + (add-hook 'erlang-mode-hook 'spacemacs/run-prog-mode-hooks) + ;; (setq erlang-root-dir "/usr/lib/erlang/erts-5.10.3") + ;; (add-to-list 'exec-path "/usr/lib/erlang/erts-5.10.3/bin") + ;; (setq erlang-man-root-dir "/usr/lib/erlang/erts-5.10.3/man") + ;; (add-hook 'erlang-mode-hook + ;; (lambda () + ;; (setq mode-name "Erlang") + ;; ;; when starting an Erlang shell in Emacs, with a custom node name + ;; (setq inferior-erlang-machine-options '("-sname" "syl20bnr")) + ;; )) + (setq erlang-compile-extra-opts '(debug_info))) + :config + (require 'erlang-start))) + +(defun erlang/post-init-flycheck () + (spacemacs/add-flycheck-hook 'erlang-mode)) + +(defun erlang/post-init-ggtags () + (add-hook 'erlang-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun erlang/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'erlang-mode)) diff --git a/layers/+lang/ess/README.org b/layers/+lang/ess/README.org new file mode 100644 index 0000000..8d65028 --- /dev/null +++ b/layers/+lang/ess/README.org @@ -0,0 +1,69 @@ +#+TITLE: ESS (R) layer + +[[file:img/r.jpg]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#install][Install]] + - [[#key-bindings][Key Bindings]] + - [[#inferior-repl-process][Inferior REPL process]] + - [[#helpers][Helpers]] + - [[#options][Options]] + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =ess= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key Bindings + +** Inferior REPL process +Send code to inferior process with these commands: + +| Key Binding | Description | +|-------------+------------------------------------------------------------------| +| ~SPC m c c~ | send knitr/sweave chunk and keep buffer focused | +| ~SPC m c C~ | send knitr/sweave chunk and switch to REPL in insert mode | +| ~SPC m c d~ | send knitr/sweave chunk and step to next chunk | +| ~SPC m c m~ | mark knitr/sweave chunk around point | +| ~SPC m c n~ | next knitr/sweave chunk | +| ~SPC m c N~ | previous knitr/sweave chunk | +| ~SPC m s b~ | send buffer and keep code buffer focused | +| ~SPC m s B~ | send buffer and switch to REPL in insert mode | +| ~SPC m s d~ | send region or line and step (debug) | +| ~SPC m s D~ | send function or paragraph and step (debug) | +| ~SPC m s i~ | start an inferior REPL process | +| ~SPC m s l~ | send line and keep code buffer focused | +| ~SPC m s L~ | send line and switch to REPL in insert mode | +| ~SPC m s r~ | send region and keep code buffer focused | +| ~SPC m s R~ | send region and switch to REPL in insert mode | +| ~SPC m s t~ | send thing at point (function) and keep code buffer focused | +| ~SPC m s T~ | send thing at point (function) and switch to REPL in insert mode | +| ~CTRL+j~ | next item in REPL history | +| ~CTRL+k~ | previous item in REPL history | + +** Helpers +Helpers for inspecting objects at point are available in R buffers only. + +| Key Binding | Description | +|-------------+---------------------------------------------------------------------| +| ~SPC m h d~ | view data under point using [ess-R-data-view][ess-R-data-view] | +| ~SPC m h i~ | object introspection popup [ess-R-object-popup][ess-R-object-popup] | +| ~SPC m h t~ | view table using [ess-R-data-view][ess-R-data-view] | + +* Options +=ess-smart-equals= is disabled by default. In order to enable it, set in your +=~/.spacemacs= + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '((ess :variables + ess-enable-smart-equals t))) +#+END_SRC + +To turn off the automatic replacement of underscores by =<-=, add the following +hook: + +#+begin_src emacs-lisp + (add-hook 'ess-mode-hook + (lambda () + (ess-toggle-underscore nil))) +#+end_src diff --git a/layers/+lang/ess/config.el b/layers/+lang/ess/config.el new file mode 100644 index 0000000..a599c3f --- /dev/null +++ b/layers/+lang/ess/config.el @@ -0,0 +1,15 @@ +;;; config.el --- ESS Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(defvar ess-enable-smart-equals nil + "If non-nil smart-equal support is enabled") diff --git a/layers/+lang/ess/img/r.jpg b/layers/+lang/ess/img/r.jpg new file mode 100644 index 0000000..c417791 Binary files /dev/null and b/layers/+lang/ess/img/r.jpg differ diff --git a/layers/+lang/ess/packages.el b/layers/+lang/ess/packages.el new file mode 100644 index 0000000..2278af4 --- /dev/null +++ b/layers/+lang/ess/packages.el @@ -0,0 +1,137 @@ +;;; packages.el --- ESS (R) Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq ess-packages + '( + ess + ess-R-data-view + ess-R-object-popup + ess-smart-equals + golden-ratio + org)) + +(defun ess/init-ess () + (use-package ess-site + :mode (("\\.sp\\'" . S-mode) + ("/R/.*\\.q\\'" . R-mode) + ("\\.[qsS]\\'" . S-mode) + ("\\.ssc\\'" . S-mode) + ("\\.SSC\\'" . S-mode) + ("\\.[rR]\\'" . R-mode) + ("\\.[rR]nw\\'" . Rnw-mode) + ("\\.[sS]nw\\'" . Snw-mode) + ("\\.[rR]profile\\'" . R-mode) + ("NAMESPACE\\'" . R-mode) + ("CITATION\\'" . R-mode) + ("\\.omg\\'" . omegahat-mode) + ("\\.hat\\'" . omegahat-mode) + ("\\.lsp\\'" . XLS-mode) + ("\\.do\\'" . STA-mode) + ("\\.ado\\'" . STA-mode) + ("\\.[Ss][Aa][Ss]\\'" . SAS-mode) + ("\\.jl\\'" . ess-julia-mode) + ("\\.[Ss]t\\'" . S-transcript-mode) + ("\\.Sout" . S-transcript-mode) + ("\\.[Rr]out" . R-transcript-mode) + ("\\.Rd\\'" . Rd-mode) + ("\\.[Bb][Uu][Gg]\\'" . ess-bugs-mode) + ("\\.[Bb][Oo][Gg]\\'" . ess-bugs-mode) + ("\\.[Bb][Mm][Dd]\\'" . ess-bugs-mode) + ("\\.[Jj][Aa][Gg]\\'" . ess-jags-mode) + ("\\.[Jj][Oo][Gg]\\'" . ess-jags-mode) + ("\\.[Jj][Mm][Dd]\\'" . ess-jags-mode)) + :commands (R stata julia SAS) + :init + (progn + (spacemacs/register-repl 'ess-site 'julia) + (spacemacs/register-repl 'ess-site 'R) + (spacemacs/register-repl 'ess-site 'SAS) + (spacemacs/register-repl 'ess-site 'stata) + ;; Explicitly run prog-mode hooks since ess-mode does not derive from + ;; prog-mode major-mode + (add-hook 'ess-mode-hook 'spacemacs/run-prog-mode-hooks) + (when (configuration-layer/package-usedp 'company) + (add-hook 'ess-mode-hook 'company-mode)))) + + ;; R -------------------------------------------------------------------------- + (with-eval-after-load 'ess-site + ;; Follow Hadley Wickham's R style guide + (setq ess-first-continued-statement-offset 2 + ess-continued-statement-offset 0 + ess-expression-offset 2 + ess-nuke-trailing-whitespace-p t + ess-default-style 'DEFAULT) + + (defun spacemacs/ess-start-repl () + "Start a REPL corresponding to the ess-language of the current buffer." + (interactive) + (cond + ((string= "S" ess-language) (call-interactively 'R)) + ((string= "STA" ess-language) (call-interactively 'stata)) + ((string= "SAS" ess-language) (call-interactively 'SAS)))) + + (spacemacs/set-leader-keys-for-major-mode 'ess-julia-mode + "'" 'julia + "si" 'julia) + (spacemacs/set-leader-keys-for-major-mode 'ess-mode + "'" 'spacemacs/ess-start-repl + "si" 'spacemacs/ess-start-repl + ;; noweb + "cC" 'ess-eval-chunk-and-go + "cc" 'ess-eval-chunk + "cd" 'ess-eval-chunk-and-step + "cm" 'ess-noweb-mark-chunk + "cN" 'ess-noweb-previous-chunk + "cn" 'ess-noweb-next-chunk + ;; REPL + "sB" 'ess-eval-buffer-and-go + "sb" 'ess-eval-buffer + "sD" 'ess-eval-function-or-paragraph-and-step + "sd" 'ess-eval-region-or-line-and-step + "sL" 'ess-eval-line-and-go + "sl" 'ess-eval-line + "sR" 'ess-eval-region-and-go + "sr" 'ess-eval-region + "sT" 'ess-eval-function-and-go + "st" 'ess-eval-function + ;; R helpers + "hd" 'ess-R-dv-pprint + "hi" 'ess-R-object-popup + "ht" 'ess-R-dv-ctable + ) + (define-key ess-mode-map (kbd "") 'ess-eval-line) + (define-key inferior-ess-mode-map (kbd "C-j") 'comint-next-input) + (define-key inferior-ess-mode-map (kbd "C-k") 'comint-previous-input))) + +(defun ess/init-ess-R-data-view ()) + +(defun ess/init-ess-R-object-popup ()) + +(defun ess/init-ess-smart-equals () + (use-package ess-smart-equals + :defer t + :if ess-enable-smart-equals + :init + (progn + (add-hook 'ess-mode-hook 'ess-smart-equals-mode) + (add-hook 'inferior-ess-mode-hook 'ess-smart-equals-mode)))) + +(defun ess/pre-init-golden-ratio () + (spacemacs|use-package-add-hook golden-ratio + :post-config + (dolist (f '(ess-eval-buffer-and-go + ess-eval-function-and-go + ess-eval-line-and-go)) + (add-to-list 'golden-ratio-extra-commands f)))) + +(defun ess/pre-init-org () + (spacemacs|use-package-add-hook org + :post-config (add-to-list 'org-babel-load-languages '(R . t)))) diff --git a/layers/+lang/extra-langs/README.org b/layers/+lang/extra-langs/README.org new file mode 100644 index 0000000..acd4ca4 --- /dev/null +++ b/layers/+lang/extra-langs/README.org @@ -0,0 +1,18 @@ +#+TITLE: Extra Languages + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + +* Description + +Adds many more language modes for less common languages, some more niche than others. + +These include: +- Arduino +- Julia +- MATLAB +- QML +- OpenScad +- Stan +- Thrift +- Wolfram Language / Mathematica diff --git a/layers/+lang/extra-langs/packages.el b/layers/+lang/extra-langs/packages.el new file mode 100644 index 0000000..2cd85d0 --- /dev/null +++ b/layers/+lang/extra-langs/packages.el @@ -0,0 +1,43 @@ +(setq extra-langs-packages + '( + arduino-mode + julia-mode + matlab-mode + qml-mode + scad-mode + stan-mode + thrift + wolfram-mode + )) + +(defun extra-langs/init-arduino-mode () + (use-package arduino-mode :defer t)) + +(defun extra-langs/init-scad-mode () + (use-package scad-mode :defer t)) + +(defun extra-langs/init-qml-mode () + (use-package qml-mode :defer t :mode "\\.qml\\'")) + +(defun extra-langs/init-julia-mode () + (use-package julia-mode :defer t)) + +(defun extra-langs/init-matlab-mode () + (use-package matlab-mode + :defer t + :init + ;; Explicitly run prog-mode hooks since matlab-mode does not derive from + ;; prog-mode major-mode + (add-hook 'matlab-mode-hook 'spacemacs/run-prog-mode-hooks))) + +(defun extra-langs/init-stan-mode () + (use-package stan-mode :defer t)) + +(defun extra-langs/init-thrift () + (use-package thrift :defer t)) + +;; no associated extension because conflicts with more common Objective-C, manually invoke for .m files. +(defun extra-langs/init-wolfram-mode () + (use-package wolfram-mode + :defer t + :interpreter "\\(Wolfram\\|Mathematica\\)Script\\( -script\\)?")) diff --git a/layers/+lang/faust/README.org b/layers/+lang/faust/README.org new file mode 100644 index 0000000..cc6a088 --- /dev/null +++ b/layers/+lang/faust/README.org @@ -0,0 +1,27 @@ +#+TITLE: faust layer + +[[file:img/faust.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + +* Description +This simple layer adds support for the [[http://faust.grame.fr/][faust language]]. +It adds =faust-mode= as well as integrating it with =auto-completion= layer. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =faust= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key bindings + +| Key Binding | Description | +|-------------+---------------------------------------| +| ~SPC m c f~ | Compile to SVG and open in Firefox | +| ~SPC m c g~ | Compile a jack-gtk program and run it | +| ~SPC m c q~ | Compile a jack-qt program and run it | +| ~SPC m g b~ | Jump back to previous location | +| ~SPC m g g~ | Jump to definition around point | diff --git a/layers/+lang/faust/config.el b/layers/+lang/faust/config.el new file mode 100644 index 0000000..7d20f68 --- /dev/null +++ b/layers/+lang/faust/config.el @@ -0,0 +1,16 @@ +;;; config.el --- faust Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Bart Brouns +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(spacemacs|defvar-company-backends faust-mode) + +(spacemacs|define-jump-handlers faust-mode) diff --git a/layers/+lang/faust/funcs.el b/layers/+lang/faust/funcs.el new file mode 100644 index 0000000..2accd4f --- /dev/null +++ b/layers/+lang/faust/funcs.el @@ -0,0 +1,45 @@ +;;; funcs.el -- Faust Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spacemacs/faust-to-firefox () + "Compile a block-diagram and show it in the browser." + (interactive) + (set-process-sentinel + (start-process-shell-command "faust2svg" "faust-compile" + (concat "faust2svg " buffer-file-name)) + 'spacemacs//faust2svg-sentinel)) + +(defun spacemacs/faust-to-jack-gtk () + "Compile a jack-gtk program and run it." + (interactive) + (set-process-sentinel + (start-process-shell-command "faust2jack" "faust-compile" + (concat "faust2jack " buffer-file-name)) + 'spacemacs//faust-run-sentinel)) + +(defun spacemacs/faust-to-jack-qt () + "Compile a jack-qt program and run it." + (interactive) + (set-process-sentinel + (start-process-shell-command "faust2jaqt" "faust-compile" + (concat "faust2jaqt " buffer-file-name)) + 'spacemacs//faust-run-sentinel)) + +(defun spacemacs//faust2svg-sentinel (process event) + "Show block-diagram in browser" + (browse-url-of-file (concat (file-name-sans-extension buffer-file-name) + "-svg/process.svg"))) + +(defun spacemacs//faust-run-sentinel (process event) + "Run the program" + (start-process-shell-command "faust-run" nil + (file-name-sans-extension (buffer-file-name))) + (switch-to-buffer-other-window "faust-compile")) diff --git a/layers/+lang/faust/img/faust.png b/layers/+lang/faust/img/faust.png new file mode 100644 index 0000000..c722ddc Binary files /dev/null and b/layers/+lang/faust/img/faust.png differ diff --git a/layers/+lang/faust/packages.el b/layers/+lang/faust/packages.el new file mode 100644 index 0000000..e4d3192 --- /dev/null +++ b/layers/+lang/faust/packages.el @@ -0,0 +1,34 @@ +;;; packages.el --- faust layer packages file for Spacemacs. +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Bart Brouns +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;;; Code: + +(defconst faust-packages + '(company + faust-mode + yasnippet)) + +(defun faust/post-init-company () + (spacemacs|add-company-hook faust-mode)) + +(defun faust/init-faust-mode () + (use-package faust-mode + :defer t + :mode "\\.\\(dsp\\|lib\\)\\'" + :init + (progn + (spacemacs/set-leader-keys-for-major-mode 'faust-mode + "cf" 'spacemacs/faust-to-firefox + "cg" 'spacemacs/faust-to-jack-gtk + "cq" 'spacemacs/faust-to-jack-qt)))) + +(defun faust/post-init-yasnippet () + (add-hook 'faust-mode-hook 'spacemacs/load-yasnippet)) diff --git a/layers/+lang/fsharp/README.org b/layers/+lang/fsharp/README.org new file mode 100644 index 0000000..6158f65 --- /dev/null +++ b/layers/+lang/fsharp/README.org @@ -0,0 +1,44 @@ +#+TITLE: F# layer + +[[file:img/fsharp.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#packages-included][Packages Included]] + - [[#install][Install]] + - [[#key-bindings][Key Bindings]] + - [[#repl][REPL]] + +* Description + +This layer adds support for F# language using [[https://github.com/fsharp/fsharpbinding][fsharpbinding]]. + +* Packages Included + +- [[https://github.com/fsharp/fsharpbinding][fsharp-mode]] + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =fsharp= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key Bindings + +| Key Binding | Description | +|-------------+----------------------------| +| ~SPC m c c~ | Build the project | +| ~SPC m g g~ | Go to definition at point | +| ~SPC m h t~ | Show tooltip help at point | + +** REPL + +| Key Binding | Description | +|-------------+------------------------------------------------------------------| +| ~SPC m s b~ | Send buffer to the REPL | +| ~SPC m s B~ | Send buffer to the REPL and switch to the REPL in =insert state= | +| ~SPC m s i~ | Start a REPL | +| ~SPC m s p~ | Send phrase to the REPL | +| ~SPC m s P~ | Send phrase to the REPL and switch to the REPL in =insert state= | +| ~SPC m s r~ | Send region to the REPL | +| ~SPC m s R~ | Send region to the REPL and switch to the REPL in =insert state= | +| ~SPC m s s~ | Show the REPL | diff --git a/layers/+lang/fsharp/config.el b/layers/+lang/fsharp/config.el new file mode 100644 index 0000000..1930d03 --- /dev/null +++ b/layers/+lang/fsharp/config.el @@ -0,0 +1,12 @@ +;;; config.el --- fsharp Layer config File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(spacemacs|define-jump-handlers fsharp-mode fsharp-ac/gotodefn-at-point) diff --git a/layers/+lang/fsharp/img/fsharp.png b/layers/+lang/fsharp/img/fsharp.png new file mode 100644 index 0000000..dc0aa92 Binary files /dev/null and b/layers/+lang/fsharp/img/fsharp.png differ diff --git a/layers/+lang/fsharp/packages.el b/layers/+lang/fsharp/packages.el new file mode 100644 index 0000000..da951ca --- /dev/null +++ b/layers/+lang/fsharp/packages.el @@ -0,0 +1,77 @@ +;;; packages.el --- F# Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq fsharp-packages + '( + fsharp-mode + ggtags + helm-gtags + )) + +(defun fsharp/init-fsharp-mode () + (use-package fsharp-mode + :defer t + :init + (progn + (setq fsharp-doc-idle-delay .2) + (spacemacs/register-repl 'fsharp-mode 'fsharp-show-subshell "F#")) + :config + (progn + + (defun spacemacs/fsharp-load-buffer-file-focus () + "Send the current buffer to REPL and switch to the REPL in + `insert state'." + (interactive) + (fsharp-load-buffer-file) + (switch-to-buffer-other-window inferior-fsharp-buffer-name) + (evil-insert-state)) + + (defun spacemacs/fsharp-eval-phrase-focus () + "Send the current phrase to REPL and switch to the REPL in + `insert state'." + (interactive) + (fsharp-eval-phrase) + (switch-to-buffer-other-window inferior-fsharp-buffer-name) + (evil-insert-state)) + + (defun spacemacs/fsharp-eval-region-focus (start end) + "Send the current phrase to REPL and switch to the REPL in + `insert state'." + (interactive "r") + (fsharp-eval-region start end) + (switch-to-buffer-other-window inferior-fsharp-buffer-name) + (evil-insert-state)) + + (spacemacs/set-leader-keys-for-major-mode 'fsharp-mode + ;; Compile + "cc" 'compile + + "fa" 'fsharp-find-alternate-file + + "ht" 'fsharp-ac/show-tooltip-at-point + + "'" 'fsharp-show-subshell + "sb" 'fsharp-load-buffer-file + "sB" 'spacemacs/fsharp-load-buffer-file-focus + "si" 'fsharp-show-subshell + "sp" 'fsharp-eval-phrase + "sP" 'spacemacs/fsharp-eval-phrase-focus + "sr" 'fsharp-eval-region + "sR" 'spacemacs/fsharp-eval-region-focus + "ss" 'fsharp-show-subshell + + "xf" 'fsharp-run-executable-file)))) + +(defun fsharp/post-init-ggtags () + (add-hook 'fsharp-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun fsharp/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'fsharp-mode)) diff --git a/layers/+lang/go/README.org b/layers/+lang/go/README.org new file mode 100644 index 0000000..7b52db6 --- /dev/null +++ b/layers/+lang/go/README.org @@ -0,0 +1,150 @@ +#+TITLE: GO layer + +[[file:img/go.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features:]] + - [[#install][Install]] + - [[#pre-requisites][Pre-requisites]] + - [[#layer][Layer]] + - [[#configuration][Configuration]] + - [[#indentation][Indentation]] + - [[#tests][Tests]] + - [[#guru][Guru]] + - [[#working-with-go][Working with Go]] + - [[#go-commands-start-with-m][Go commands (start with =m=):]] + - [[#go-guru][Go Guru]] + +* Description +This layer adds extensive support for go. + +** Features: +- gofmt/goimports on file save +- Auto-completion using [[https://github.com/nsf/gocode/tree/master/emacs][go-autocomplete]] (with the =auto-completion= layer) +- Source analysis using [[https://godoc.org/golang.org/x/tools/cmd/guru][go-guru]] +- Linting with flycheck's built-in checkers or flycheck-gometalinter +- Coverage profile visualization + +* Install +** Pre-requisites +You will need =gocode= and =godef=: + +#+BEGIN_SRC sh + go get -u -v github.com/nsf/gocode + go get -u -v github.com/rogpeppe/godef + go get -u -v golang.org/x/tools/cmd/guru + go get -u -v golang.org/x/tools/cmd/gorename + go get -u -v golang.org/x/tools/cmd/goimports +#+END_SRC + +If you wish to use =gometalinter= set the value of =go-use-gometalinter= to t: + +#+begin_src emacs-lisp + (go :variables go-use-gometalinter t) +#+end_src + +and install the tool: + +#+BEGIN_SRC sh + go get -u -v github.com/alecthomas/gometalinter + gometalinter --install --update +#+END_SRC + +For more information read [[https://github.com/alecthomas/gometalinter/blob/master/README.md][gometalinter README.md]] +and [[https://github.com/favadi/flycheck-gometalinter/blob/master/README.md][flycheck-gometalinter README.md]] + +Make sure that =gocode= executable is in your PATH. For information about +setting up =$PATH=, check out the corresponding section in the FAQ (~SPC h SPC +$PATH RET~). + +For best results, make sure that the =auto-completion= and =syntax-checking= +layers are enabled as well. + +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =go= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Configuration + +By default, go buffers are run through =gofmt= on save. To use a different +formatter, set the value of =gofmt-command=, e.g. + +#+begin_src emacs-lisp + (setq gofmt-command "goimports") +#+end_src + +or + +#+begin_src emacs-lisp + (go :variables gofmt-command "goimports") +#+end_src + +** Indentation +By default, the tab width in Go mode is 8 spaces. To use a different value set +the layer variable =go-tab-width=, e.g. + +#+begin_src emacs-lisp + (go :variables go-tab-width 4) +#+end_src + +** Tests +If you're using =gocheck= in your project you can use the +=go-use-gocheck-for-testing= variable to enable suite testing and to get single +function testing to work. + +=go-coverage-display-buffer-func= controls how =go-coverage= should display +the coverage buffer. See [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Choosing-Window.html][=display-buffer=]] for a list of possible functions. +The default value is =display-buffer-reuse-window=. + +** Guru + +Go Oracle has been deprecated as of October 1, 2016, it's replacement is =go-guru=. + +If you would like to use the =goguru= bindings in your work, you will need to +install it, and in your project you will need to set the scope with ~SPC m f o~. +The scope is a comma separated set of packages, and =go='s recursive operator is +supported. In addition, you can prefix with =-= to exclude a package from +searching. + +In addition, =GOPATH= must be set prior to =go-guru= initialization. + +* Working with Go +** Go commands (start with =m=): + +| Key Binding | Description | +|-------------+---------------------------------------------------------------------------------------| +| ~SPC m h h~ | godoc at point | +| ~SPC m i g~ | goto imports | +| ~SPC m i a~ | add import | +| ~SPC m i r~ | remove unused import | +| ~SPC m e b~ | go-play buffer | +| ~SPC m e r~ | go-play region | +| ~SPC m e d~ | download go-play snippet | +| ~SPC m x x~ | run "go run" for the current 'main' package | +| ~SPC m g a~ | jump to matching test file or back from test to code file | +| ~SPC m g c~ | open a clone of the current buffer with a coverage info (=go tool cover -h= for help) | +| ~SPC m g g~ | go jump to definition | +| ~SPC m r n~ | go rename | +| ~SPC m t p~ | run "go test" for the current package | +| ~SPC m t P~ | run "go test" for the current package and all packages under it | +| ~SPC m t t~ | run "go test" for the function you're currently in (while you're in a _.test.go file) | +| ~SPC m t s~ | run "go test" for the suite you're currently in (requires gocheck) | + +** Go Guru + +| Key Binding | Description | +|-------------+------------------------------------------------------| +| ~SPC m f d~ | go-guru describe symbol at point | +| ~SPC m f f~ | go-guru show free variables | +| ~SPC m f i~ | go-guru show implements relation | +| ~SPC m f c~ | go-guru show channel sends/receives | +| ~SPC m f r~ | go-guru show referrers | +| ~SPC m f j~ | go-guru jump to symbol definition | +| ~SPC m f p~ | go-guru show what the select expression points to | +| ~SPC m f s~ | go-guru show callstack | +| ~SPC m f e~ | go-guru show possible contants/types for error value | +| ~SPC m f <~ | go-guru show possible callers | +| ~SPC m f >~ | go-guru show call targets | +| ~SPC m f o~ | go-guru set analysis scope | diff --git a/layers/+lang/go/config.el b/layers/+lang/go/config.el new file mode 100644 index 0000000..0332cb1 --- /dev/null +++ b/layers/+lang/go/config.el @@ -0,0 +1,25 @@ +;;; packages.el --- Go Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; variables + +(spacemacs|defvar-company-backends go-mode) + +(spacemacs|define-jump-handlers go-mode godef-jump) + +(defvar go-use-gocheck-for-testing nil + "If using gocheck for testing when running the tests -check.f will be used instead of -run to specify the test that will be ran. Gocheck is mandatory for testing suites.") + +(defvar go-tab-width 8 + "Set the `tab-width' in Go mode. Default is 8.") + +(defvar go-use-gometalinter nil + "Use gometalinter if the variable has non-nil value.") diff --git a/layers/+lang/go/funcs.el b/layers/+lang/go/funcs.el new file mode 100644 index 0000000..8142536 --- /dev/null +++ b/layers/+lang/go/funcs.el @@ -0,0 +1,32 @@ +;;; funcs.el --- Go Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun load-gopath-file(gopath name) + "Search for NAME file in all paths referenced in GOPATH." + (let* ((sep (if (spacemacs/system-is-mswindows) ";" ":")) + (paths (split-string gopath sep)) + found) + (loop for p in paths + for file = (concat p name) when (file-exists-p file) + do + (load-file file) + (setq found t) + finally return found))) + +(defun spacemacs//go-enable-gometalinter () + "Enable `flycheck-gometalinter' and disable overlapping `flycheck' linters." + (setq flycheck-disabled-checkers '(go-gofmt + go-golint + go-vet + go-build + go-test + go-errcheck)) + (flycheck-gometalinter-setup)) diff --git a/layers/+lang/go/img/go.png b/layers/+lang/go/img/go.png new file mode 100644 index 0000000..4ac1d48 Binary files /dev/null and b/layers/+lang/go/img/go.png differ diff --git a/layers/+lang/go/local/go-rename/go-rename.el b/layers/+lang/go/local/go-rename/go-rename.el new file mode 100644 index 0000000..c871b1c --- /dev/null +++ b/layers/+lang/go/local/go-rename/go-rename.el @@ -0,0 +1,89 @@ +;;; Copyright 2014 The Go Authors. All rights reserved. +;;; Use of this source code is governed by a BSD-style +;;; license that can be found in the LICENSE file. +;;; +;;; Integration of the 'gorename' tool into Emacs. +;;; +;;; To install: +;;; % go get golang.org/x/tools/cmd/gorename +;;; % go build golang.org/x/tools/cmd/gorename +;;; % mv gorename $HOME/bin/ # or elsewhere on $PATH +;;; +;;; The go-rename-command variable can be customized to specify an +;;; alternative location for the installed command. +(defgroup go-rename nil + "Options specific to the Go rename." + :group 'go) + +(defcustom go-rename-command "gorename" + "The `gorename' command; by the default, $PATH is searched." + :type 'string + :group 'go-rename) + +(defun go-rename (new-name) + "Rename the entity denoted by the identifier at point, using +the `gorename' tool." + (interactive (list (read-string "New name: " (thing-at-point 'symbol)))) + (if (not buffer-file-name) + (error "Cannot use go-rename on a buffer without a file name")) + ;; It's not sufficient to save the current buffer if modified, + ;; since if gofmt-before-save is on the before-save-hook, + ;; saving will disturb the selected region. + (if (buffer-modified-p) + (error "Please save the current buffer before invoking go-rename")) + ;; Prompt-save all other modified Go buffers, since they might get written. + (save-some-buffers nil #'(lambda () + (and (buffer-file-name) + (string= (file-name-extension (buffer-file-name)) ".go")))) + (let* ((posflag (format "-offset=%s:#%d" + (expand-file-name buffer-file-truename) + (1- (go--position-bytes (point))))) + (env-vars (go-root-and-paths)) + (goroot-env (concat "GOROOT=" (car env-vars))) + (gopath-env (concat "GOPATH=" (mapconcat #'identity (cdr env-vars) ":"))) + success) + (with-current-buffer (get-buffer-create "*go-rename*") + (setq buffer-read-only nil) + (erase-buffer) + (let ((args (list go-rename-command nil t nil posflag "-to" new-name))) + ;; Log the command to *Messages*, for debugging. + (message "Command: %s:" args) + (message "Running gorename...") + ;; Use dynamic binding to modify/restore the environment + (setq success (zerop (let ((process-environment (list* goroot-env gopath-env process-environment))) + (apply #'call-process args)))) + (insert "\n") + (compilation-mode) + (setq compilation-error-screen-columns nil) + + ;; On success, print the one-line result in the message bar, + ;; and hide the *go-rename* buffer. + (let ((w (display-buffer (current-buffer)))) + (if success + (progn + (message "%s" (go--buffer-string-no-trailing-space)) + (delete-window w)) + ;; failure + (message "gorename exited") + (shrink-window-if-larger-than-buffer w) + (set-window-point w (point-min))))))) + + ;; Reload the modified files, saving line/col. + ;; (Don't restore point since the text has changed.) + ;; + ;; TODO(adonovan): should we also do this for all other files + ;; that were updated (the tool can print them)? + (let ((line (line-number-at-pos)) + (col (current-column))) + (revert-buffer t t t) ; safe, because we just saved it + (goto-char (point-min)) + (forward-line (1- line)) + (forward-char col))) + + +(defun go--buffer-string-no-trailing-space () + (replace-regexp-in-string "[\t\n ]*\\'" + "" + (buffer-substring (point-min) (point-max)))) + +(provide 'go-rename) diff --git a/layers/+lang/go/packages.el b/layers/+lang/go/packages.el new file mode 100644 index 0000000..bb32f88 --- /dev/null +++ b/layers/+lang/go/packages.el @@ -0,0 +1,147 @@ +(setq go-packages + '( + company + (company-go :toggle (configuration-layer/package-usedp 'company)) + flycheck + (flycheck-gometalinter :toggle (and go-use-gometalinter + (configuration-layer/package-usedp + 'flycheck))) + ggtags + helm-gtags + go-eldoc + go-mode + go-guru + (go-rename :location local) + )) + + +(defun go/post-init-company () + (spacemacs|add-company-hook go-mode)) + +(defun go/init-company-go () + (use-package company-go + :defer t + :init + (progn + (setq company-go-show-annotation t) + (push 'company-go company-backends-go-mode)))) + +(defun go/post-init-flycheck () + (spacemacs/add-flycheck-hook 'go-mode)) + +(defun go/init-go-mode() + (when (memq window-system '(mac ns x)) + (dolist (var '("GOPATH" "GO15VENDOREXPERIMENT")) + (unless (getenv var) + (exec-path-from-shell-copy-env var)))) + + (use-package go-mode + :defer t + :init + (progn + (defun spacemacs//go-set-tab-width () + "Set the tab width." + (setq-local tab-width go-tab-width)) + (add-hook 'go-mode-hook 'spacemacs//go-set-tab-width)) + :config + (progn + (add-hook 'before-save-hook 'gofmt-before-save) + + (defun spacemacs/go-run-tests (args) + (interactive) + (save-selected-window + (async-shell-command (concat "go test " args)))) + + (defun spacemacs/go-run-package-tests () + (interactive) + (spacemacs/go-run-tests "")) + + (defun spacemacs/go-run-package-tests-nested () + (interactive) + (spacemacs/go-run-tests "./...")) + + (defun spacemacs/go-run-test-current-function () + (interactive) + (if (string-match "_test\\.go" buffer-file-name) + (let ((test-method (if go-use-gocheck-for-testing + "-check.f" + "-run"))) + (save-excursion + (re-search-backward "^func[ ]+\\(([[:alnum:]]*?[ ]?[*]?[[:alnum:]]+)[ ]+\\)?\\(Test[[:alnum:]_]+\\)(.*)") + (spacemacs/go-run-tests (concat test-method "='" (match-string-no-properties 2) "'")))) + (message "Must be in a _test.go file to run go-run-test-current-function"))) + + (defun spacemacs/go-run-test-current-suite () + (interactive) + (if (string-match "_test\.go" buffer-file-name) + (if go-use-gocheck-for-testing + (save-excursion + (re-search-backward "^func[ ]+\\(([[:alnum:]]*?[ ]?[*]?\\([[:alnum:]]+\\))[ ]+\\)?Test[[:alnum:]_]+(.*)") + (spacemacs/go-run-tests (concat "-check.f='" (match-string-no-properties 2) "'"))) + (message "Gocheck is needed to test the current suite")) + (message "Must be in a _test.go file to run go-test-current-suite"))) + + (defun spacemacs/go-run-main () + (interactive) + (shell-command + (format "go run %s" + (shell-quote-argument (buffer-file-name))))) + + (spacemacs/declare-prefix-for-mode 'go-mode "me" "playground") + (spacemacs/declare-prefix-for-mode 'go-mode "mg" "goto") + (spacemacs/declare-prefix-for-mode 'go-mode "mh" "help") + (spacemacs/declare-prefix-for-mode 'go-mode "mi" "imports") + (spacemacs/declare-prefix-for-mode 'go-mode "mt" "test") + (spacemacs/declare-prefix-for-mode 'go-mode "mx" "execute") + (spacemacs/set-leader-keys-for-major-mode 'go-mode + "hh" 'godoc-at-point + "ig" 'go-goto-imports + "ia" 'go-import-add + "ir" 'go-remove-unused-imports + "eb" 'go-play-buffer + "er" 'go-play-region + "ed" 'go-download-play + "xx" 'spacemacs/go-run-main + "ga" 'ff-find-other-file + "gc" 'go-coverage + "tt" 'spacemacs/go-run-test-current-function + "ts" 'spacemacs/go-run-test-current-suite + "tp" 'spacemacs/go-run-package-tests + "tP" 'spacemacs/go-run-package-tests-nested)))) + +(defun go/init-go-eldoc() + (add-hook 'go-mode-hook 'go-eldoc-setup)) + +(defun go/init-go-guru() + (spacemacs/declare-prefix-for-mode 'go-mode "mf" "guru") + (spacemacs/set-leader-keys-for-major-mode 'go-mode + "fd" 'go-guru-describe + "ff" 'go-guru-freevars + "fi" 'go-guru-implements + "fc" 'go-guru-peers + "fr" 'go-guru-referrers + "fj" 'go-guru-definition + "fp" 'go-guru-pointsto + "fs" 'go-guru-callstack + "fe" 'go-guru-whicherrs + "f<" 'go-guru-callers + "f>" 'go-guru-callees + "fo" 'go-guru-set-scope)) + +(defun go/init-go-rename() + (use-package go-rename + :init + (spacemacs/declare-prefix-for-mode 'go-mode "mr" "rename") + (spacemacs/set-leader-keys-for-major-mode 'go-mode "rn" 'go-rename))) + +(defun go/init-flycheck-gometalinter() + (use-package flycheck-gometalinter + :defer t + :init + (add-hook 'go-mode-hook 'spacemacs//go-enable-gometalinter t))) + +(defun go/post-init-ggtags () + (add-hook 'go-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun go/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'go-mode)) diff --git a/layers/+lang/graphviz/README.org b/layers/+lang/graphviz/README.org new file mode 100644 index 0000000..e09abe8 --- /dev/null +++ b/layers/+lang/graphviz/README.org @@ -0,0 +1,34 @@ +#+TITLE: graphviz layer + +[[file:img/graphviz.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#configuration][Configuration]] + - [[#key-bindings][Key bindings]] + +* Description +This contains a forked version of [[https://github.com/ppareit/graphviz-dot-mode][graphviz-dot-mode]] that enables a live-reload +type work flow for editing `.dot` files. When live-preview is enabled, saving +the file will automatically trigger a compilation and reload of the image buffer +associated with the file. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =graphviz= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Configuration +If the live preview is not always updating the rendered image properly, you can +try to adjust the value of =graphviz-dot-revert-delay= higher to give the +compiler more time to finish generating the file before reverting the buffer. + +* Key bindings + +| Key Binding | Description | +|-------------+--------------------------------------| +| ~SPC m ,~ | Preview file | +| ~SPC m =~ | Indent graph | +| ~SPC m t~ | Toggle live-preview | +| ~SPC m c~ | Set compile command and compile file | diff --git a/layers/+lang/graphviz/img/graphviz.png b/layers/+lang/graphviz/img/graphviz.png new file mode 100644 index 0000000..2d452a4 Binary files /dev/null and b/layers/+lang/graphviz/img/graphviz.png differ diff --git a/layers/+lang/graphviz/packages.el b/layers/+lang/graphviz/packages.el new file mode 100644 index 0000000..d123d49 --- /dev/null +++ b/layers/+lang/graphviz/packages.el @@ -0,0 +1,60 @@ +;;; packages.el --- graphviz layer packages file for Spacemacs. +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: luxbock +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defconst graphviz-packages + '((graphviz-dot-mode :location (recipe :fetcher github + :repo "luxbock/graphviz-dot-mode")) + org + smartparens)) + +(defun graphviz/init-graphviz-dot-mode () + (use-package graphviz-dot-mode + :mode (("\\.diag\\'" . graphviz-dot-mode) + ("\\.blockdiag\\'" . graphviz-dot-mode) + ("\\.nwdiag\\'" . graphviz-dot-mode) + ("\\.rackdiag\\'" . graphviz-dot-mode) + ("\\.dot\\'" . graphviz-dot-mode) + ("\\.gv\\'" . graphviz-dot-mode)) + :config + (progn + (spacemacs|add-toggle graphviz-live-reload + :status graphviz-dot-auto-preview-on-save + :on (graphviz-turn-on-live-preview) + :off (graphviz-turn-off-live-preview) + :documentation "Enable Graphviz live reload.") + (spacemacs/set-leader-keys-for-major-mode 'graphviz-dot-mode + "=" 'graphviz-dot-indent-graph + "c" 'compile + "t" 'spacemacs/toggle-graphviz-live-reload) + (when dotspacemacs-major-mode-emacs-leader-key + (spacemacs/set-leader-keys-for-major-mode 'graphviz-dot-mode + dotspacemacs-major-mode-emacs-leader-key 'graphviz-dot-preview)) + (when dotspacemacs-major-mode-leader-key + (spacemacs/set-leader-keys-for-major-mode 'graphviz-dot-mode + dotspacemacs-major-mode-leader-key 'graphviz-dot-preview))))) + +(defun graphviz/post-init-smartparens () + (spacemacs|use-package-add-hook graphviz-dot-mode + :post-config + (progn + ;; allow smartparens to work properly + (define-key graphviz-dot-mode-map "{" nil) + (define-key graphviz-dot-mode-map "}" nil)))) + +(defun graphviz/post-init-org () + (spacemacs|use-package-add-hook org + :post-config + (progn + (add-to-list 'org-babel-load-languages '(dot . t)) + ;; replace fundamental mode by graphiz one + (setq org-src-lang-modes + (append '(("dot" . graphviz-dot)) + (delete '("dot" . fundamental) org-src-lang-modes)))))) diff --git a/layers/+lang/haskell/README.org b/layers/+lang/haskell/README.org new file mode 100644 index 0000000..6054f09 --- /dev/null +++ b/layers/+lang/haskell/README.org @@ -0,0 +1,522 @@ +#+TITLE: Haskell layer + +[[file:img/haskell.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features:]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#dependencies][Dependencies]] + - [[#setup-path][Setup PATH]] + - [[#completion-support][Completion support]] + - [[#company-ghci][=company-ghci=]] + - [[#intero][=intero=]] + - [[#ghc-mod][=ghc-mod=]] + - [[#optional-extras][Optional extras]] + - [[#structured-haskell-mode][structured-haskell-mode]] + - [[#hindent][hindent]] + - [[#key-bindings][Key bindings]] + - [[#documentation][Documentation]] + - [[#debug][Debug]] + - [[#debug-buffer][Debug Buffer]] + - [[#repl][REPL]] + - [[#intero-repl][Intero REPL]] + - [[#cabal-commands][Cabal commands]] + - [[#cabal-files][Cabal files]] + - [[#refactor][Refactor]] + - [[#ghc-mod-1][Ghc-mod]] + - [[#insert-template][Insert template]] + - [[#syntax-checking][Syntax checking]] + - [[#flycheck][Flycheck]] + - [[#hlint][HLint]] + - [[#ghc-mod-2][ghc-mod]] + - [[#interactive-haskell-mode][Interactive haskell-mode]] + - [[#flymake][Flymake]] + - [[#troubleshooting][Troubleshooting]] + - [[#faq][FAQ]] + - [[#the-repl-doesnt-work][The REPL doesn't work]] + - [[#the-repl-is-stuck][The REPL is stuck]] + - [[#i-am-using-stack-and-ghc-mod-but-ghc-mod-doesnt-work][I am using =stack= and =ghc-mod=, but =ghc-mod= doesn't work]] + - [[#ghc-mod-doesnt-work][=ghc-mod= doesn't work]] + - [[#indentation-doesnt-reset-when-pressing-return-after-an-empty-line][Indentation doesn't reset when pressing return after an empty line]] + - [[#flycheck-displays-hlint-warnings-but-not-errors][Flycheck displays HLint warnings but not errors]] + - [[#i-can-see-highlighted-errors-but-they-dont-appear-in-the-error-list][I can see highlighted errors but they don't appear in the error list]] + - [[#flycheck-doesnt-work][Flycheck doesn't work]] + - [[#flycheck-doesnt-work-with-stack][Flycheck doesn't work with =stack=]] + - [[#the-stack-build-directory-is-wrong][The stack build directory is wrong]] + - [[#the-project-root-directory-is-not-set-properly][The Project root directory is not set properly]] + - [[#haskell-mode-commands-dont-work][haskell-mode commands don't work]] + - [[#ghc-mod-and-haskell-mode-commands-overlap-how-do-i-know-which-command-belongs-to-what][=ghc-mod= and =haskell-mode= commands overlap. How do I know which command belongs to what?]] + - [[#some-commands-start-with-ghc--and-some-with-haskell--what-does-that-mean][Some commands start with =ghc-= and some with =haskell-=. What does that mean?]] + +* Description +This layer adds support for the [[https://www.haskell.org/][Haskell]] language. + +** Features: +- syntax highlighting for [[https://github.com/haskell/haskell-mode][haskell source]], [[https://github.com/haskell/haskell-mode][cabal files]], [[https://github.com/bgamari/cmm-mode][C-- source]], +- auto-completion with one of selected backends (=intero=, =ghci= or =ghc-mod=). + +*This layer is in construction, it needs your contributions and bug reports.* + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =haskell= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Dependencies +This layer requires some [[https://www.haskell.org/cabal/][cabal]] packages: +- =apply-refact= (required by =hlint-refactor=) +- =hlint= (required by =hlint-refactor=) +- =stylish-haskell= (optional for =haskell-mode=) +- =hasktags= (optional) +- =hoogle= (optional for =haskell-mode= and =helm-hoogle=) +- =ghc-mod= (optional for completion) +- =intero= (optional for completion) + +To install them, use following command (or the =stack= equivalent): + +#+BEGIN_SRC sh +$ cabal install apply-refact hlint stylish-haskell hasktags hoogle +#+END_SRC + +** Setup PATH +First of all make sure that your =$PATH= contains the installation path for +Haskell tools like =ghc=, =ghci= etc. It depends on how you have installed +=ghc=, but you can always check it by running =which ghc= in your terminal. +=Stack= users should add only the installation path of =stack= itself. Usually +it's =~/.local/bin=. + +Then make sure that your =$PATH= contains the installation path for =cabal= +packages. If you are using =cabal= it should be =~/.cabal/bin= or +=~/Library/Haskell/bin= (for 'Haskell for Mac' users). If you +are using =stack= then it should be =~/.local/bin=. + +For information about setting up =$PATH=, check out the corresponding section in +the FAQ (~SPC h SPC $PATH RET~). + +** Completion support +This layer provides several completion backends - =intero=, =ghci= and +=ghc-mod=. By default =ghci= (=company-ghci=) is used as it requires no +dependencies and works both with =stack= and pure =cabal= projects. In order to +manually set completion backend set value of =haskell-completion-backend=. Note +that in order to enable completion you have to enable =auto-completion= layer as +well. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers + '(auto-completion + (haskell :variables haskell-completion-backend 'intero))) +#+END_SRC + +*** =company-ghci= +[[https://github.com/juiko/company-ghci][company-ghci]] communicates directly with =ghci= in order to provide completion. In +order to use it you have to call =haskell-process-load-or-reload= (=SPC s b=). + +*** =intero= +=Intero= works only for =stack= users. You can manually install =intero= executable by +calling =stack install intero=, but this step is optional as =Intero= installs +itself. + +*** =ghc-mod= +[[http://www.mew.org/~kazu/proj/ghc-mod/][ghc-mod]] enhances =haskell-mode= with for example code completion, templates, +case-splitting and much more. In order to use it you need to install the +executable with =cabal install ghc-mod= (or =stack= equivalent). + +=Stack= users also should make sure that =dist/setup-config= doesn't exist in the +project root. As it will confuse =ghc-mod=. For more troubleshooting, checkout +this [[https://github.com/kazu-yamamoto/ghc-mod/wiki#known-issues-related-to-stack][document]]. + +Also note that =ghc-mod= works only with =GHC= version that was used to build +=ghc-mod=. You can check which version was used by calling =ghc-mod --version=. + +** Optional extras +The Haskell layer supports some extra features that can be enabled through layer +variables. + +*** structured-haskell-mode +Currently there is no support for [[https://github.com/chrisdone/structured-haskell-mode][structured-haskell-mode]], since it doesn't play +very well with non-emacs editing style ([[https://github.com/chrisdone/structured-haskell-mode/issues/81][structured-haskell-mode/#81]]). Emacs +editing style users might easily enable it by adding =structured-haskell-mode= to +list of =dotspacemacs-additional-packages= in your =.spacemacs= file. For more +installation instructions, please refer to the official documentation at +[[https://github.com/chrisdone/structured-haskell-mode#features][structured-haskell-mode]] page. In case you are non-emacs editing style user and +still want to use =structured-haskell-mode= - use it at your own risk. + +Any contributions that will help to solve issues with =structured-haskell-mode= +are warmly welcome! + +*** hindent +[[https://github.com/chrisdone/hindent][hindent]] is an extensible Haskell pretty printer, which let's you +reformat your code. You need to install the executable with =cabal +install hindent= or =stack install hindent= + +To enable it you have to set the variable =haskell-enable-hindent-style= to a +supported style. The available styles are: +- fundamental +- johan-tibell +- chris-done +- gibiansky + +See examples [[https://github.com/chrisdone/hindent#example][here]]. + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers + '((haskell :variables haskell-enable-hindent-style "johan-tibell"))) +#+END_SRC + +* Key bindings +All Haskell specific bindings are prefixed with the major-mode leader +~SPC m~. + +Top-level commands are prefixed by ~SPC m~: + +| Key Binding | Description | +|-------------+---------------------------------------------------------------------| +| ~SPC m g g~ | go to definition or tag | +| ~SPC m g i~ | cycle the Haskell import lines or return to point (with prefix arg) | +| ~SPC m F~ | format buffer using haskell-stylish | +| ~SPC m f~ | format declaration using hindent (if enabled) | + +** Documentation +Documentation commands are prefixed by ~SPC m h~ + +| Key Binding | Description | +|-------------+----------------------------------------------------------------------------| +| ~SPC m h d~ | find or generate Haddock documentation for the identifier under the cursor | +| ~SPC m h f~ | do a helm-hoogle lookup | +| ~SPC m h h~ | do a Hoogle lookup | +| ~SPC m h H~ | do a local Hoogle lookup | +| ~SPC m h i~ | gets information for the identifier under the cursor | +| ~SPC m h t~ | gets the type of the identifier under the cursor | +| ~SPC m h y~ | do a Hayoo lookup | + +** Debug +Debug commands are prefixed by ~SPC m d~: + +| Key Binding | Description | +|-------------+--------------------------------------------| +| ~SPC m d a~ | abandon current process | +| ~SPC m d b~ | insert breakpoint at function | +| ~SPC m d B~ | delete breakpoint | +| ~SPC m d c~ | continue current process | +| ~SPC m d d~ | start debug process, needs to be run first | +| ~SPC m d n~ | next breakpoint | +| ~SPC m d N~ | previous breakpoint | +| ~SPC m d p~ | previous breakpoint | +| ~SPC m d r~ | refresh process buffer | +| ~SPC m d s~ | step into the next function | +| ~SPC m d t~ | trace the expression | + +** Debug Buffer + +| Key Binding | Description | +|-------------+---------------------------------------------| +| ~RET~ | select object at the point | +| ~a~ | abandon current computation | +| ~b~ | break on function | +| ~c~ | continue the current computation | +| ~d~ | delete object at the point | +| ~n~ | go to next step to inspect bindings | +| ~N~ or ~p~ | go to previous step to inspect the bindings | +| ~r~ | refresh the debugger buffer | +| ~s~ | step into the next function | +| ~t~ | trace the expression | + +** REPL +REPL commands are prefixed by ~SPC m s~: + +| Key Binding | Description | +|-------------+-------------------------------------------------| +| ~SPC m s b~ | load or reload the current buffer into the REPL | +| ~SPC m s c~ | clear the REPL | +| ~SPC m s s~ | show the REPL without switching to it | +| ~SPC m s S~ | show and switch to the REPL | + +** Intero REPL +Intero REPL commands are prefixed by ~SPC m i~: + +| Key Binding | Description | +|-------------+---------------------------------------------------------------| +| ~SPC m i c~ | change directory in the backend process | +| ~SPC m i d~ | reload the module =DevelMain= and then run =DevelMain.update= | +| ~SPC m i k~ | stop the current worker process and kill its associated | +| ~SPC m i l~ | list hidden process buffers created by =intero= | +| ~SPC m i r~ | restart the process with the same configuration as before | +| ~SPC m i t~ | set the targets to use for stack =ghci= | + +** Cabal commands +Cabal commands are prefixed by ~SPC m c~: + +| Key Binding | Description | +|-------------+------------------------------------------------------------| +| ~SPC m c a~ | cabal actions | +| ~SPC m c b~ | build the current cabal project, i.e. invoke =cabal build= | +| ~SPC m c c~ | compile the current project, i.e. invoke =ghc= | +| ~SPC m c v~ | visit the cabal file | + +** Cabal files +This commands are available in a cabal file. + +| Key Binding | Description | +|-------------+---------------------------------------------| +| ~SPC m d~ | add a dependency to the project | +| ~SPC m b~ | go to benchmark section | +| ~SPC m e~ | go to executable section | +| ~SPC m t~ | go to test-suite section | +| ~SPC m m~ | go to exposed modules | +| ~SPC m l~ | go to libary section | +| ~SPC m n~ | go to next subsection | +| ~SPC m p~ | go to previous subsection | +| ~SPC m s c~ | clear the REPL | +| ~SPC m s s~ | show the REPL without switching to it | +| ~SPC m s S~ | show and switch to the REPL | +| ~SPC m N~ | go to next section | +| ~SPC m P~ | go to previous section | +| ~SPC m f~ | find or create source-file under the cursor | + +** Refactor +Refactor commands are prefixed by ~SPC m r~: + +| Key Binding | Description | +|-------------+---------------------------------------------------| +| ~SPC m r b~ | apply all HLint suggestions in the current buffer | +| ~SPC m r r~ | apply the HLint suggestion under the cursor | +| ~SPC m r s~ | list all Intero suggestions | + +Only some of the HLint suggestions can be applied. + +To apply the intero suggestions, press `C-c C-c` when the window is open, which +is also shown in the window that appears. + +** Ghc-mod +These commands are only available when ghc-mod is enabled. + +For more info, see +http://www.mew.org/~kazu/proj/ghc-mod/en/emacs.html + +ghc-mod commands are prefixed by ~SPC m m~: + +| Key Binding | Description | +|-------------+-------------------------------------------| +| ~SPC t~ | insert template | +| ~SPC m m u~ | insert template with holes | +| ~SPC m m a~ | select one of possible cases (~ghc-auto~) | +| ~SPC m m f~ | replace a hole (~ghc-refine~) | +| ~SPC m m e~ | expand template haskell | +| ~SPC m m n~ | go to next type hole | +| ~SPC m m p~ | go to previous type hole | +| ~SPC m m >~ | make indent deeper | +| ~SPC m m <~ | make indent shallower | + +*** Insert template +~SPC m m t~ inserts a template. What this means is that in the beginning of a +buffer, =module Foo where= is inserted. On a function without signature, the +inferred type is inserted. On a symbol =foo= without definition, =foo = +undefined= is inserted or a proper module is imported. ~SPC m m u~ inserts a +hole in this case. On a variable, the case is split. When checking with hlint, +original code is replaced with hlint's suggestion if possible. + +* Syntax checking +At the moment there are four components which can check the syntax and indicates +somehow error and warnings in the code. Those components are + +- flycheck +- hlint (via flycheck) +- ghc-mod +- haskell-mode interactive + +As all these components can be active at the same time, it can be tricky to know +which component is displaying which message, especially when they disagree or +one is not working. Only flycheck errors (ghc and hlint) are displayed in the +error list and can be navigated using the standard spacemacs key bindings (under +~SPC e~) even though errors from other modes might highlight the actual buffer. + +** Flycheck +This is the standard spacemacs way to do syntax checking and the most elaborate. +You need the syntax-checking layer to enable this. Please the documentation for +that layer on how to interact with flycheck. + +Flycheck has different Haskell checkers: =haskell-ghc=, =haskell-stack-ghc= and +=haskell-hlint=. Normally it can automatically detect the best one to use, but +if it doesn't work, you can change it using ~SPC e s~. + +** HLint +HLint is a linter for Haskell. It doesn't detect errors (as long as it can parse +the file) but bad coding style and code smell. The HLint checker is called +*after* the flycheck GHC checker. + +** ghc-mod +Ghc-mod, when enabled, also does syntax checking. It doesn't highlight errors +but instead displays an exclamation point in the fringe. You can navigate +between errors using =ghc-goto-next-error= (~M-n~) and =ghc-goto-prev-error= +(~M-p~). + +** Interactive haskell-mode +Finally, interactive haskell-mode (~SPC m s b~) also displays errors. These +errors can be navigated from the interactive buffer (by clicking on the error) +or using =haskell-goto-next-error= (~M-n~) and =haskell-goto-prev-error= +(~M-p~). + +** Flymake +An alternative to syntax checking is to build your project using +=flymake-compile=. It doesn't highlight error in the buffer but is more +reliable. The error navigation is similar to interactive haskell-mode. + +** Troubleshooting +Flycheck and ghc-mod can fail silently for miscellaneous reasons. See the [[FAQ]] +for troubleshooting. + +* FAQ +** The REPL doesn't work +Usually =haskell-mode= is great at figuring out which interactive process to +bring up. But if you are experiencing problems with it you can help +=haskell-mode= by setting =haskell-process-type= as in following code: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers + '((haskell :variables haskell-process-type 'stack-ghci))) +#+END_SRC + +Available options are: + +- ghci +- cabal-repl +- cabal-dev +- cabal-ghci +- stack-ghci + +** The REPL is stuck +Make sure that when you are typing anything in REPL there is a space between +what you type and =λ>=. When there is no space - REPL will behave as if it's +stuck. Usually, when you enter normal state, cursor is moved back, so there is +no required space when you switch to insert mode. There is possible workaround - +just add following snippet to your =dotspacemacs/user-config= function: + +#+BEGIN_SRC emacs-lisp +(when (configuration-layer/package-usedp 'haskell) + (add-hook 'haskell-interactive-mode-hook + (lambda () + (setq-local evil-move-cursor-back nil)))) +#+END_SRC + +It will make cursor stay at the right place in the REPL buffer when you enter +normal state. Which in most cases helps you to avoid the problem with 'stuck' +REPL. + +Also, some users might want to start REPL in insert mode. For this to happen you +could place following snippet in your =dotspacemacs/user-config= function: + +#+BEGIN_SRC emacs-lisp +(when (configuration-layer/package-usedp 'haskell) + (defadvice haskell-interactive-switch (after spacemacs/haskell-interactive-switch-advice activate) + (when (eq dotspacemacs-editing-style 'vim) + (call-interactively 'evil-insert)))) +#+END_SRC + +** I am using =stack= and =ghc-mod=, but =ghc-mod= doesn't work +Make sure that =dist= directory doesn't exist in your project root. So if it +exists, just remove it and try again. + +** =ghc-mod= doesn't work + +First of all - make sure that the version of =ghc= matches the version of =ghc= that +was used to build =ghc-mod=. To get the latter call =ghc-mod --version= in terminal. +If they don't match you have to rebuild =ghc-mod=. + +=Stack= provides ability to use different =ghc= versions across different projects. +In case you are using this feature you have to rebuild =ghc-mod= quite often. If +you use =ghc-mod= only for completion and don't want to rebuild =ghc-mod= every time +you switch project you'd better disable =ghc-mod= support, so =company-ghci= will be +used for completion. + +The second thing to do if it's still not working - call =ghc-mod debug= in the +root of project you are currently working on. Make sure that it shows no errors. +If there are errors you can't solve - it's better to report them [[https://github.com/DanielG/ghc-mod][upstream]]. + +** Indentation doesn't reset when pressing return after an empty line +This is the intended behavior in =haskell-indentation-mode=. If you want to +reset indentation when pressing return after an empty line, add the following +snippet into your =dotspacemacs/user-config= function. + +#+BEGIN_SRC emacs-lisp +(defun haskell-indentation-advice () + (when (and (< 1 (line-number-at-pos)) + (save-excursion + (forward-line -1) + (string= "" (s-trim (buffer-substring (line-beginning-position) (line-end-position)))))) + (delete-region (line-beginning-position) (point)))) + +(advice-add 'haskell-indentation-newline-and-indent + :after 'haskell-indentation-advice) +#+END_SRC + +** Flycheck displays HLint warnings but not errors +The HLint checker is called *after* normal flycheck checker even if the checker +fails. Check the [[Flycheck doesn't work]] section. + +** I can see highlighted errors but they don't appear in the error list +The error list is only set by flycheck. You are probably seeing errors +highlighted by either ghc-mode or haskell-mode. Check the [[Flycheck doesn't work]] +section. + +** Flycheck doesn't work +You can check what is wrong with flycheck with the =flycheck-compile= command. +This will show you the exact command line used and its output. + +If you are using stack, check the [[Flycheck doesn't work with =stack=]] section. + +** Flycheck doesn't work with =stack= +First check that flycheck uses the correct checker and all the paths are +properly configured using =flycheck-verify-setup= (~SPC e v~). You can force the +checker with =flycheck-select-checker= (~SPC e s~) to ensure it uses +=haskell-stack-ghc=. If it still doesn't work, it could be one of the following +problems: + +- The stack build directory is wrong +- The project root is not set properly + +*** The stack build directory is wrong +The path to the build directory containing some generated files is normally +under =.stack-work/install//Cabal-/build=. + +However, the version of the cabal library used by stack to generate the +directory name is not the version of the cabal library installed by stack, but +the version of cabal associated to the GHC version. This error can happen after +upgrading cabal or cabal-install. To check if this is the problem, compare the +path name of the build path used by flycheck using =flycheck-compile= and +compare it to to the actual path in the =.stack-work= directory. If they are +different you need to reinstall ghc using the command =stack setup +--upgrade-cabal=. + +*** The Project root directory is not set properly +Flycheck launches the GHC command not from the project root directory but from +the the directory of the file being checked. This is normally not a problem as +all the paths are set properly, however it could be a problem if some template +Haskell functions use relative paths (e.g. in Yesod scaffolded projects). + +Until it's fixed in flycheck the workaround is to the wrap the stack command to +run all subcommands from the project root directory. You can do so with the +following script: + +#+BEGIN_SRC bash +#!/bin/bash +cd `stack --project-root` +stack $* +#+END_SRC + +Make sure you set =flycheck-haskell-stack-ghc-executable= to this script. + +** haskell-mode commands don't work +Some (most of) the haskell-mode commands only works when haskell-mode is in +interactive mode, i.e. as a interactive session associated to it. Load it using +~SPC m s b~. + +** =ghc-mod= and =haskell-mode= commands overlap. How do I know which command belongs to what? +ghc-mod commands are prefixed with =ghc-=, haskell-mode ones are prefixed with +=haskell-=. + +** Some commands start with =ghc-= and some with =haskell-=. What does that mean? +Commands starting with =ghc-= are ghc-mod commands. Commands starting with +=haskell-= are haskell-mode commands. diff --git a/layers/+lang/haskell/config.el b/layers/+lang/haskell/config.el new file mode 100644 index 0000000..2a1a107 --- /dev/null +++ b/layers/+lang/haskell/config.el @@ -0,0 +1,28 @@ +;;; config.el --- Haskell Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Bjarke Vad Andersen +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(setq haskell-modes '(haskell-mode literate-haskell-mode)) + +(spacemacs|defvar-company-backends haskell-mode) +(spacemacs|defvar-company-backends haskell-cabal-mode) +(spacemacs|defvar-company-backends intero-repl-mode) + +(spacemacs|define-jump-handlers haskell-mode haskell-mode-jump-to-def-or-tag) + +(defvar haskell-completion-backend 'ghci + "Completion backend used by company. +Available options are `ghci', `intero' and `ghc-mod'. Default is +`ghci'.") + +(defvar haskell-enable-hindent-style nil + "Style to use for formatting with hindent; available are: fundamental johan-tibell chris-done gibiansky. If nil hindent is disabled.") diff --git a/layers/+lang/haskell/funcs.el b/layers/+lang/haskell/funcs.el new file mode 100644 index 0000000..065e812 --- /dev/null +++ b/layers/+lang/haskell/funcs.el @@ -0,0 +1,101 @@ +;;; funcs.el --- Haskell Layer funcs File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spacemacs-haskell//setup-completion-backend () + "Conditionally setup haskell completion backend." + (unless (eq haskell-completion-backend 'ghc-mod) + (add-hook 'haskell-mode-hook 'interactive-haskell-mode)) + (when (configuration-layer/package-usedp 'company) + (pcase haskell-completion-backend + (`ghci (spacemacs-haskell//setup-ghci)) + (`ghc-mod (spacemacs-haskell//setup-ghc-mod)) + (`intero (spacemacs-haskell//setup-intero))))) + +(defun spacemacs-haskell//setup-ghci () + (add-to-list 'company-backends-haskell-mode + '(company-ghci company-dabbrev-code company-yasnippet))) + +(defun spacemacs-haskell//setup-ghc-mod () + (add-to-list 'company-backends-haskell-mode + '(company-ghc company-dabbrev-code company-yasnippet)) + (ghc-init) + (dolist (mode haskell-modes) + (spacemacs/declare-prefix-for-mode mode "mm" "haskell/ghc-mod") + (spacemacs/set-leader-keys-for-major-mode mode + "mt" 'ghc-insert-template-or-signature + "mu" 'ghc-initial-code-from-signature + "ma" 'ghc-auto + "mf" 'ghc-refine + "me" 'ghc-expand-th + "mn" 'ghc-goto-next-hole + "mp" 'ghc-goto-prev-hole + "m>" 'ghc-make-indent-deeper + "m<" 'ghc-make-indent-shallower + "hi" 'ghc-show-info + "ht" 'ghc-show-type)) + (when (configuration-layer/package-usedp 'flycheck) + ;; remove overlays from ghc-check.el if flycheck is enabled + (set-face-attribute 'ghc-face-error nil :underline nil) + (set-face-attribute 'ghc-face-warn nil :underline nil))) + +(defun spacemacs-haskell//setup-intero () + (add-to-list 'company-backends-haskell-mode + '(company-intero company-dabbrev-code company-yasnippet)) + (push 'intero-goto-definition spacemacs-jump-handlers) + (intero-mode) + (dolist (mode haskell-modes) + (spacemacs/set-leader-keys-for-major-mode mode + "hi" 'intero-info + "ht" 'intero-type-at + "hT" 'haskell-intero/insert-type + "rs" 'intero-apply-suggestions + "sb" 'intero-repl-load)) + + (dolist (mode (cons 'haskell-cabal-mode haskell-modes)) + (spacemacs/set-leader-keys-for-major-mode mode + "sc" nil + "ss" 'haskell-intero/display-repl + "sS" 'haskell-intero/pop-to-repl)) + + (dolist (mode (append haskell-modes '(haskell-cabal-mode intero-repl-mode))) + (spacemacs/declare-prefix-for-mode mode "mi" "haskell/intero") + (spacemacs/set-leader-keys-for-major-mode mode + "ic" 'intero-cd + "id" 'intero-devel-reload + "ik" 'intero-destroy + "il" 'intero-list-buffers + "ir" 'intero-restart + "it" 'intero-targets)) + + (evil-define-key '(insert normal) intero-mode-map + (kbd "M-.") 'intero-goto-definition)) + + +;; Intero functions + +(defun haskell-intero/insert-type () + (interactive) + (intero-type-at :insert)) + +(defun haskell-intero/display-repl (&optional prompt-options) + (interactive "P") + (let ((buffer (intero-repl-buffer prompt-options))) + (unless (get-buffer-window buffer 'visible) + (display-buffer buffer)))) + +(defun haskell-intero/pop-to-repl (&optional prompt-options) + (interactive "P") + (pop-to-buffer (intero-repl-buffer prompt-options))) + +(defun haskell-intero//preserve-focus (f &rest args) + (let ((buffer (current-buffer))) + (apply f args) + (pop-to-buffer buffer))) diff --git a/layers/+lang/haskell/img/haskell.png b/layers/+lang/haskell/img/haskell.png new file mode 100644 index 0000000..1a5cb55 Binary files /dev/null and b/layers/+lang/haskell/img/haskell.png differ diff --git a/layers/+lang/haskell/packages.el b/layers/+lang/haskell/packages.el new file mode 100644 index 0000000..919be6c --- /dev/null +++ b/layers/+lang/haskell/packages.el @@ -0,0 +1,288 @@ +;;; packages.el --- Haskell Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq haskell-packages + '( + cmm-mode + company + (company-cabal :toggle (configuration-layer/package-usedp 'company)) + company-ghci + company-ghc + flycheck + (flycheck-haskell :toggle (configuration-layer/package-usedp 'flycheck)) + ggtags + ghc + haskell-mode + haskell-snippets + helm-gtags + (helm-hoogle :toggle (configuration-layer/package-usedp 'helm)) + hindent + hlint-refactor + intero + )) + +(defun haskell/init-cmm-mode () + (use-package cmm-mode + :defer t)) + +(defun haskell/post-init-company () + (spacemacs|add-company-hook haskell-mode) + (spacemacs|add-company-hook haskell-cabal-mode) + (when (eq haskell-completion-backend 'intero) + (spacemacs|add-company-hook intero-repl-mode))) + +(defun haskell/init-company-cabal () + (use-package company-cabal + :if (configuration-layer/package-usedp 'company) + :defer t + :init + (push '(company-cabal) + company-backends-haskell-cabal-mode))) + +(defun haskell/init-company-ghci () + (use-package company-ghci + :defer t)) + +(defun haskell/init-company-ghc () + (use-package company-ghc + :defer t)) + +(defun haskell/post-init-ggtags () + (add-hook 'haskell-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun haskell/init-ghc () + (use-package ghc + :defer t)) + +(defun haskell/init-intero () + (use-package intero + :defer t + :config + (progn + (spacemacs|diminish intero-mode " λ" " \\") + (advice-add 'intero-repl-load + :around #'haskell-intero//preserve-focus)))) + +(defun haskell/init-helm-hoogle () + (use-package helm-hoogle + :defer t + :init + (dolist (mode haskell-modes) + (spacemacs/set-leader-keys-for-major-mode mode "hf" 'helm-hoogle)))) + +(defun haskell/post-init-flycheck () + (spacemacs/add-flycheck-hook 'haskell-mode)) + +(defun haskell/init-flycheck-haskell () + (use-package flycheck-haskell + :commands flycheck-haskell-configure + :init (add-hook 'flycheck-mode-hook 'flycheck-haskell-configure))) + +(defun haskell/init-haskell-mode () + (use-package haskell-mode + :defer t + :init + (progn + (add-hook 'haskell-mode-local-vars-hook + #'spacemacs-haskell//setup-completion-backend) + + (defun spacemacs//force-haskell-mode-loading () + "Force `haskell-mode' loading when visiting cabal file." + (require 'haskell-mode)) + (add-hook 'haskell-cabal-mode-hook + 'spacemacs//force-haskell-mode-loading) + + (setq + ;; Use notify.el (if you have it installed) at the end of running + ;; Cabal commands or generally things worth notifying. + haskell-notify-p t + ;; Remove annoying error popups + haskell-interactive-popup-errors nil + ;; Better import handling + haskell-process-suggest-remove-import-lines t + haskell-process-auto-import-loaded-modules t + ;; Disable haskell-stylish-on-save, as it breaks flycheck highlighting. + ;; NOTE: May not be true anymore - taksuyu 2015-10-06 + haskell-stylish-on-save nil)) + :config + (progn + ;; Haskell main editing mode key bindings. + (defun spacemacs/init-haskell-mode () + ;; use only internal indentation system from haskell + (if (fboundp 'electric-indent-local-mode) + (electric-indent-local-mode -1))) + + (defun spacemacs/haskell-interactive-bring () + "Bring up the interactive mode for this session without + switching to it." + (interactive) + (let* ((session (haskell-session)) + (buffer (haskell-session-interactive-buffer session))) + (display-buffer buffer))) + + ;; hooks + (add-hook 'haskell-mode-hook 'spacemacs/init-haskell-mode) + + ;; prefixes + (dolist (mode haskell-modes) + (spacemacs/declare-prefix-for-mode mode "mg" "haskell/navigation") + (spacemacs/declare-prefix-for-mode mode "ms" "haskell/repl") + (spacemacs/declare-prefix-for-mode mode "mc" "haskell/cabal") + (spacemacs/declare-prefix-for-mode mode "mh" "haskell/documentation") + (spacemacs/declare-prefix-for-mode mode "md" "haskell/debug") + (spacemacs/declare-prefix-for-mode mode "mr" "haskell/refactor")) + (spacemacs/declare-prefix-for-mode 'haskell-interactive-mode "ms" "haskell/repl") + (spacemacs/declare-prefix-for-mode 'haskell-cabal-mode "ms" "haskell/repl") + + ;; key bindings + (defun spacemacs/haskell-process-do-type-on-prev-line () + (interactive) + (haskell-process-do-type 1)) + + (dolist (mode haskell-modes) + (spacemacs/set-leader-keys-for-major-mode mode + "gi" 'haskell-navigate-imports + "F" 'haskell-mode-stylish-buffer + + "sb" 'haskell-process-load-file + "sc" 'haskell-interactive-mode-clear + "ss" 'spacemacs/haskell-interactive-bring + "sS" 'haskell-interactive-switch + + "ca" 'haskell-process-cabal + "cb" 'haskell-process-cabal-build + "cc" 'haskell-compile + "cv" 'haskell-cabal-visit-file + + "hd" 'inferior-haskell-find-haddock + "hh" 'hoogle + "hH" 'haskell-hoogle-lookup-from-local + "hi" 'haskell-process-do-info + "ht" 'haskell-process-do-type + "hT" 'spacemacs/haskell-process-do-type-on-prev-line + "hy" 'hayoo + + "da" 'haskell-debug/abandon + "db" 'haskell-debug/break-on-function + "dB" 'haskell-debug/delete + "dc" 'haskell-debug/continue + "dd" 'haskell-debug + "dn" 'haskell-debug/next + "dN" 'haskell-debug/previous + "dp" 'haskell-debug/previous + "dr" 'haskell-debug/refresh + "ds" 'haskell-debug/step + "dt" 'haskell-debug/trace)) + + (evilified-state-evilify haskell-debug-mode haskell-debug-mode-map + "RET" 'haskell-debug/select + "a" 'haskell-debug/abandon + "b" 'haskell-debug/break-on-function + "c" 'haskell-debug/continue + "d" 'haskell-debug/delete + "n" 'haskell-debug/next + "N" 'haskell-debug/previous + "p" 'haskell-debug/previous + "r" 'haskell-debug/refresh + "s" 'haskell-debug/step + "t" 'haskell-debug/trace) + + ;; configure C-c C-l so it doesn't throw any errors + (bind-key "C-c C-l" 'haskell-process-load-file haskell-mode-map) + + ;; Switch back to editor from REPL + (spacemacs/set-leader-keys-for-major-mode 'haskell-interactive-mode + "sS" 'haskell-interactive-switch-back) + + ;; Compile + (spacemacs/set-leader-keys-for-major-mode 'haskell-cabal + "C" 'haskell-compile) + + ;; Cabal-file bindings + (spacemacs/set-leader-keys-for-major-mode 'haskell-cabal-mode + ;; "=" 'haskell-cabal-subsection-arrange-lines ;; Does a bad job, 'gg=G' works better + "d" 'haskell-cabal-add-dependency + "b" 'haskell-cabal-goto-benchmark-section + "e" 'haskell-cabal-goto-executable-section + "t" 'haskell-cabal-goto-test-suite-section + "m" 'haskell-cabal-goto-exposed-modules + "l" 'haskell-cabal-goto-library-section + "n" 'haskell-cabal-next-subsection + "p" 'haskell-cabal-previous-subsection + "sc" 'haskell-interactive-mode-clear + "ss" 'spacemacs/haskell-interactive-bring + "sS" 'haskell-interactive-switch + "N" 'haskell-cabal-next-section + "P" 'haskell-cabal-previous-section + "f" 'haskell-cabal-find-or-create-source-file) + + ;; Make "RET" behaviour in REPL saner + (evil-define-key 'insert haskell-interactive-mode-map + (kbd "RET") 'haskell-interactive-mode-return) + (evil-define-key 'normal haskell-interactive-mode-map + (kbd "RET") 'haskell-interactive-mode-return)) + + ;; align rules for Haskell + (with-eval-after-load 'align + (add-to-list 'align-rules-list + '(haskell-types + (regexp . "\\(\\s-+\\)\\(::\\|∷\\)\\s-+") + (modes . haskell-modes))) + (add-to-list 'align-rules-list + '(haskell-assignment + (regexp . "\\(\\s-+\\)=\\s-+") + (modes . haskell-modes))) + (add-to-list 'align-rules-list + '(haskell-arrows + (regexp . "\\(\\s-+\\)\\(->\\|→\\)\\s-+") + (modes . haskell-modes))) + (add-to-list 'align-rules-list + '(haskell-left-arrows + (regexp . "\\(\\s-+\\)\\(<-\\|←\\)\\s-+") + (modes . haskell-modes)))))) + +(defun haskell/init-haskell-snippets () + ;; manually load the package since the current implementation is not lazy + ;; loading friendly (funny coming from the haskell mode :-)) + (setq haskell-snippets-dir (spacemacs//get-package-directory + 'haskell-snippets)) + + (defun haskell-snippets-initialize () + (let ((snip-dir (expand-file-name "snippets" haskell-snippets-dir))) + (add-to-list 'yas-snippet-dirs snip-dir t) + (yas-load-directory snip-dir))) + + (with-eval-after-load 'yasnippet (haskell-snippets-initialize))) + +(defun haskell/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'haskell-mode)) + +;; doesn't support literate-haskell-mode :( +(defun haskell/init-hindent () + (use-package hindent + :defer t + :if (stringp haskell-enable-hindent-style) + :init + (add-hook 'haskell-mode-hook #'hindent-mode) + :config + (progn + (setq hindent-style haskell-enable-hindent-style) + (spacemacs/set-leader-keys-for-major-mode 'haskell-mode + "f" 'hindent-reformat-decl)))) + +(defun haskell/init-hlint-refactor () + (use-package hlint-refactor + :defer t + :init + (progn + (spacemacs/set-leader-keys-for-major-mode 'haskell-mode + "rb" 'hlint-refactor-refactor-buffer + "rr" 'hlint-refactor-refactor-at-point)))) diff --git a/layers/+lang/html/README.org b/layers/+lang/html/README.org new file mode 100644 index 0000000..99185db --- /dev/null +++ b/layers/+lang/html/README.org @@ -0,0 +1,81 @@ +#+TITLE: HTML layer + +[[file:img/html.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#install][Install]] + - [[#key-bindings][Key Bindings]] + - [[#web-mode][Web mode]] + - [[#cssscss][CSS/SCSS]] + +* Description +This layer adds support for editing HTML and CSS. + +** Features +- Editing HTML and CSS file using [[http://web-mode.org/][web-mode]] +- Support for Sass/Scss and Less files +- Generate HTML and CSS coding using [[https://github.com/smihica/emmet-mode][emmet-mode]] +- Tags navigation on key ~%~ using [[https://github.com/redguardtoo/evil-matchit][evil-matchit]] +- Support for editing Slim and Pug templates using [[https://github.com/slim-template/emacs-slim][slim-mode]] + and [[https://github.com/hlissner/emacs-pug-mode][pug-mode]] + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =html= to the existing =dotspacemacs-configuration-layers= list in this +file. + +SCSS linting requires SCSS-Lint version >= 0.43.0. You can get it from GitHub: + +#+BEGIN_SRC command-line +gem install specific_install +gem specific_install https://github.com/brigade/scss-lint.git +gem specific_install https://github.com/Sweetchuck/scss_lint_reporter_checkstyle.git +#+END_SRC + +* Key Bindings +** Web mode + +| Key Binding | Description | +|-------------+-----------------------------------------------------------| +| ~SPC m g p~ | quickly navigate CSS rules using =helm= | +| ~SPC m e h~ | highlight DOM errors | +| ~SPC m g b~ | go to the beginning of current element | +| ~SPC m g c~ | go to the first child element | +| ~SPC m g p~ | go to the parent element | +| ~SPC m g s~ | go to next sibling | +| ~SPC m h p~ | show xpath of the current element | +| ~SPC m r c~ | clone the current element | +| ~SPC m r d~ | delete the current element (does not delete the children) | +| ~SPC m r r~ | rename current element | +| ~SPC m r w~ | wrap current element | +| ~SPC m z~ | fold/unfold current element | +| ~%~ | evil-matchit keybinding to jump to closing tag | + +A transient-state is also defined, start it with ~SPC m .~ or ~, .~ + +| Key Binding | Description | +|-------------+----------------------------------------------------------------| +| ~?~ | Toggle full help | +| ~c~ | clone current element | +| ~d~ | delete (vanish) current element (does not delete the children) | +| ~D~ | delete current element and children | +| ~j~ | next element | +| ~J~ / ~gj~ | next sibling element | +| ~h~ | parent element | +| ~k~ | previous element | +| ~K~ / ~gk~ | previous sibling element | +| ~l~ | first child element | +| ~p~ | show xpath of current element | +| ~q~ | leave the transient-state | +| ~r~ | rename current element | +| ~w~ | wrap current element | + +** CSS/SCSS + +| Key Binding | Description | +|-------------+-----------------------------------------| +| ~SPC m g h~ | quickly navigate CSS rules using =helm= | +| ~SPC m z c~ | fold css statement to one line | +| ~SPC m z o~ | unfold css statement to one line | diff --git a/layers/+lang/html/config.el b/layers/+lang/html/config.el new file mode 100644 index 0000000..5a6b051 --- /dev/null +++ b/layers/+lang/html/config.el @@ -0,0 +1,20 @@ +;;; packages.el --- HTML Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(spacemacs|defvar-company-backends css-mode) +(spacemacs|defvar-company-backends jade-mode) +(spacemacs|defvar-company-backends slim-mode) +(spacemacs|defvar-company-backends web-mode) +;;TODO: when this becomes available -- uncomment. -@robbyoconnor +;; (spacemacs|defvar-company-backends haml-mode) + diff --git a/layers/+lang/html/funcs.el b/layers/+lang/html/funcs.el new file mode 100644 index 0000000..52faddb --- /dev/null +++ b/layers/+lang/html/funcs.el @@ -0,0 +1,16 @@ +;;; funcs.el --- HTML Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spacemacs/emmet-expand () + (interactive) + (if (bound-and-true-p yas-minor-mode) + (call-interactively 'emmet-expand-yas) + (call-interactively 'emmet-expand-line))) diff --git a/layers/+lang/html/img/html.png b/layers/+lang/html/img/html.png new file mode 100644 index 0000000..fe74f60 Binary files /dev/null and b/layers/+lang/html/img/html.png differ diff --git a/layers/+lang/html/packages.el b/layers/+lang/html/packages.el new file mode 100644 index 0000000..fe595ed --- /dev/null +++ b/layers/+lang/html/packages.el @@ -0,0 +1,257 @@ +;;; packages.el --- HTML Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq html-packages + '( + company + (company-web :toggle (configuration-layer/package-usedp 'company)) + css-mode + emmet-mode + evil-matchit + flycheck + haml-mode + (helm-css-scss :toggle (configuration-layer/package-usedp 'helm)) + less-css-mode + pug-mode + sass-mode + scss-mode + slim-mode + smartparens + tagedit + web-mode + yasnippet + )) + +;;TODO: whenever company-web makes a backend for haml-mode it should be added here. -- @robbyoconnor +(defun html/post-init-company () + (spacemacs|add-company-hook css-mode) + (spacemacs|add-company-hook jade-mode) + (spacemacs|add-company-hook slim-mode) + (spacemacs|add-company-hook web-mode)) + +(defun html/init-company-web () + (use-package company-web)) + +(defun html/init-css-mode () + (use-package css-mode + :defer t + :init + (progn + (push 'company-css company-backends-css-mode) + + ;; Mark `css-indent-offset' as safe-local variable + (put 'css-indent-offset 'safe-local-variable #'integerp) + + ;; Explicitly run prog-mode hooks since css-mode does not derive from + ;; prog-mode major-mode in Emacs 24 and below. + (when (version< emacs-version "25") + (add-hook 'css-mode-hook 'spacemacs/run-prog-mode-hooks)) + + (defun css-expand-statement () + "Expand CSS block" + (interactive) + (save-excursion + (end-of-line) + (search-backward "{") + (forward-char 1) + (while (or (eobp) (not (looking-at "}"))) + (let ((beg (point))) + (newline) + (search-forward ";") + (indent-region beg (point)) + )) + (newline))) + + (defun css-contract-statement () + "Contract CSS block" + (interactive) + (end-of-line) + (search-backward "{") + (while (not (looking-at "}")) + (join-line -1))) + + (spacemacs/set-leader-keys-for-major-mode 'css-mode + "zc" 'css-contract-statement + "zo" 'css-expand-statement)))) + +(defun html/init-emmet-mode () + (use-package emmet-mode + :defer t + :init (spacemacs/add-to-hooks 'emmet-mode '(css-mode-hook + html-mode-hook + sass-mode-hook + scss-mode-hook + web-mode-hook)) + :config + (progn + (evil-define-key 'insert emmet-mode-keymap (kbd "TAB") 'spacemacs/emmet-expand) + (evil-define-key 'insert emmet-mode-keymap (kbd "") 'spacemacs/emmet-expand) + (evil-define-key 'emacs emmet-mode-keymap (kbd "TAB") 'spacemacs/emmet-expand) + (evil-define-key 'emacs emmet-mode-keymap (kbd "") 'spacemacs/emmet-expand) + (evil-define-key 'hybrid emmet-mode-keymap (kbd "TAB") 'spacemacs/emmet-expand) + (evil-define-key 'hybrid emmet-mode-keymap (kbd "") 'spacemacs/emmet-expand) + (spacemacs|hide-lighter emmet-mode)))) + +(defun html/post-init-evil-matchit () + (add-hook 'web-mode-hook 'turn-on-evil-matchit-mode)) + +(defun html/post-init-flycheck () + (dolist (mode '(haml-mode + less-mode + pug-mode + sass-mode + scss-mode + slim-mode + web-mode)) + (spacemacs/add-flycheck-hook mode))) + +(defun html/init-haml-mode () + (use-package haml-mode + :defer t)) + +(defun html/init-helm-css-scss () + (use-package helm-css-scss + :defer t + :init + (dolist (mode '(css-mode scss-mode)) + (spacemacs/set-leader-keys-for-major-mode mode "gh" 'helm-css-scss)))) + +(defun html/init-less-css-mode () + (use-package less-css-mode + :defer t + :mode ("\\.less\\'" . less-css-mode))) + +(defun html/init-pug-mode () + (use-package pug-mode + :defer t + :mode ("\\.pug$" . pug-mode))) + +(defun html/init-sass-mode () + (use-package sass-mode + :defer t + :mode ("\\.sass\\'" . sass-mode))) + +(defun html/init-scss-mode () + (use-package scss-mode + :defer t + :mode ("\\.scss\\'" . scss-mode))) + +(defun html/init-slim-mode () + (use-package slim-mode + :defer t)) + +(defun html/post-init-smartparens () + (spacemacs/add-to-hooks + (if dotspacemacs-smartparens-strict-mode + 'smartparens-strict-mode + 'smartparens-mode) + '(css-mode-hook scss-mode-hook sass-mode-hook less-css-mode-hook)) + + (add-hook 'web-mode-hook 'spacemacs/toggle-smartparens-off)) + +(defun html/init-tagedit () + (use-package tagedit + :defer t + :config + (progn + (tagedit-add-experimental-features) + (add-hook 'html-mode-hook (lambda () (tagedit-mode 1))) + (spacemacs|diminish tagedit-mode " Ⓣ" " T")))) + +(defun html/init-web-mode () + (use-package web-mode + :defer t + :init + (push '(company-web-html company-css) company-backends-web-mode) + :config + (progn + (spacemacs/declare-prefix-for-mode 'web-mode "me" "errors") + (spacemacs/declare-prefix-for-mode 'web-mode "mg" "goto") + (spacemacs/declare-prefix-for-mode 'web-mode "mh" "dom") + (spacemacs/declare-prefix-for-mode 'web-mode "mr" "refactor") + (spacemacs/set-leader-keys-for-major-mode 'web-mode + "eh" 'web-mode-dom-errors-show + "gb" 'web-mode-element-beginning + "gc" 'web-mode-element-child + "gp" 'web-mode-element-parent + "gs" 'web-mode-element-sibling-next + "hp" 'web-mode-dom-xpath + "rc" 'web-mode-element-clone + "rd" 'web-mode-element-vanish + "rk" 'web-mode-element-kill + "rr" 'web-mode-element-rename + "rw" 'web-mode-element-wrap + "z" 'web-mode-fold-or-unfold + ;; TODO element close would be nice but broken with evil. + ) + + ;; (defvar spacemacs--web-mode-ms-doc-toggle 0 + ;; "Display a short doc when nil, full doc otherwise.") + + ;; (defun spacemacs//web-mode-ms-doc () + ;; (if (equal 0 spacemacs--web-mode-ms-doc-toggle) + ;; "[_?_] for help" + ;; " + ;; [_?_] display this help + ;; [_k_] previous [_j_] next [_K_] previous sibling [_J_] next sibling + ;; [_h_] parent [_l_] child [_c_] clone [_d_] delete [_D_] kill [_r_] rename + ;; [_w_] wrap [_p_] xpath + ;; [_q_] quit")) + + ;; (defun spacemacs//web-mode-ms-toggle-doc () + ;; (interactive) + ;; (setq spacemacs--web-mode-ms-doc-toggle + ;; (logxor spacemacs--web-mode-ms-doc-toggle 1))) + + (spacemacs|define-transient-state web-mode + :title "Web-mode Transient State" + :columns 4 + :foreign-keys run + :evil-leader-for-mode (web-mode . ".") + :bindings + ("j" web-mode-element-next "next") + ("J" web-mode-element-sibling-next "next sibling") + ("gj" web-mode-element-sibling-next) + ("k" web-mode-element-previous "previous") + ("K" web-mode-element-sibling-previous "previous sibling") + ("gk" web-mode-element-sibling-previous) + ("h" web-mode-element-parent "parent") + ("l" web-mode-element-child "child") + ("c" web-mode-element-clone "clone") + ("d" web-mode-element-vanish "delete") + ("D" web-mode-element-kill "kill") + ("r" web-mode-element-rename "rename" :exit t) + ("w" web-mode-element-wrap "wrap") + ("p" web-mode-dom-xpath "xpath") + ("q" nil "quit" :exit t) + ("" nil nil :exit t))) + + :mode + (("\\.phtml\\'" . web-mode) + ("\\.tpl\\.php\\'" . web-mode) + ("\\.twig\\'" . web-mode) + ("\\.html\\'" . web-mode) + ("\\.htm\\'" . web-mode) + ("\\.[gj]sp\\'" . web-mode) + ("\\.as[cp]x?\\'" . web-mode) + ("\\.eex\\'" . web-mode) + ("\\.erb\\'" . web-mode) + ("\\.mustache\\'" . web-mode) + ("\\.handlebars\\'" . web-mode) + ("\\.hbs\\'" . web-mode) + ("\\.eco\\'" . web-mode) + ("\\.ejs\\'" . web-mode) + ("\\.djhtml\\'" . web-mode)))) + +(defun html/post-init-yasnippet () + (spacemacs/add-to-hooks 'spacemacs/load-yasnippet '(css-mode-hook + jade-mode + slim-mode))) diff --git a/layers/+lang/idris/README.org b/layers/+lang/idris/README.org new file mode 100644 index 0000000..5e98a6f --- /dev/null +++ b/layers/+lang/idris/README.org @@ -0,0 +1,108 @@ +#+TITLE: Idris layer + +[[file:img/idris.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#idris][Idris]] + - [[#key-bindings][Key bindings]] + - [[#shorthands][Shorthands]] + - [[#interactive-editing][Interactive editing]] + - [[#documentation][Documentation]] + - [[#repl][REPL]] + - [[#active-term-manipulations][Active term manipulations]] + - [[#build-system][Build system]] + +* Description +This layer adds support for the [[http://www.idris-lang.org/][Idris]] language. + +* Install + +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =idris= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Idris + +Idris can be installed using =Haskell's cabal=: + +#+BEGIN_SRC sh +cabal install idris +#+END_SRC + +Binaries are also available for some platforms at +http://www.idris-lang.org/download/ + +* Key bindings + +** Shorthands +Several (but not all) of the evil-leader shorthands that =idris-mode= provides +are reproduced under the local leader. + +| Key Binding | Description | +|-------------+---------------------------------------------------------------------------------| +| ~SPC m c~ | Case split the pattern variable under point, or make it into a case expression. | +| ~SPC m d~ | Create an initial pattern match clause for a type declaration. | +| ~SPC m l~ | Extract lemma from hole | +| ~SPC m p~ | Attempt to solve a metavariable automatically. | +| ~SPC m r~ | Load current buffer into Idris. | +| ~SPC m t~ | Get the type for the identifier under point. | +| ~SPC m w~ | Add a with block for the pattern-match clause under point. | + +** Interactive editing + +| Key Binding | Description | +|-------------+--------------------------------------------------------------------------------------------| +| ~SPC m i a~ | Attempt to solve a metavariable automatically. | +| ~SPC m i c~ | Case split the pattern variable under point, or make it into a case expression. | +| ~SPC m i e~ | Extract a metavariable or provisional definition name to an explicit top level definition. | +| ~SPC m i m~ | Add missing pattern-match cases to an existing definition. | +| ~SPC m i r~ | Refine by name, without recursive proof search. | +| ~SPC m i s~ | Create an initial pattern match clause for a type declaration. | +| ~SPC m i w~ | Add a with block for the pattern-match clause under point. | + +** Documentation + +| Key Binding | Description | +|-------------+-------------------------------------------------------| +| ~SPC m h a~ | Search the documentation for a string. | +| ~SPC m h d~ | Search the documentation for the name under point. | +| ~SPC m h s~ | Search the documentation regarding a particular type. | +| ~SPC m h t~ | Get the type for the identifier under point. | + +** REPL + +| Key Binding | Description | +|-------------+----------------------------------------------------------------------------------------| +| ~SPC m s b~ | Load the current buffer into Idris. | +| ~SPC m s B~ | Load the current buffer into Idris and switch to REPL in insert state | +| ~SPC m s i~ | Start Idris inferior process | +| ~SPC m s n~ | Extend the region to be loaded one line at a time. | +| ~SPC m s N~ | Extend the region to be loaded one line at a time and switch to REPL in insert state | +| ~SPC m s p~ | Contract the region to be loaded one line at a time | +| ~SPC m s P~ | Contract the region to be loaded one line at a time and switch to REPL in insert state | +| ~SPC m s s~ | Switch to REPL buffer | +| ~SPC m s q~ | Quit the Idris process | + +** Active term manipulations + +| Key Binding | Description | +|-------------+-----------------------------------------------| +| ~SPC m m c~ | Show the core language for the term at point. | +| ~SPC m m i~ | Show implicits for the term at point. | +| ~SPC m m h~ | Hide implicits for the term at point. | +| ~SPC m m n~ | Normalize the term at point. | + +** Build system + +| Key Binding | Description | +|-------------+----------------------------------------------------------------------------| +| ~SPC m b c~ | Build the package. | +| ~SPC m b C~ | Clean the package, removing =.ibc= files | +| ~SPC m b i~ | Install the package to the user's repository, building first if necessary. | +| ~SPC m b p~ | Open package file. | + +When inside a package file, you can insert a field with ~SPC m f~. diff --git a/layers/+lang/idris/config.el b/layers/+lang/idris/config.el new file mode 100644 index 0000000..b4b6cc9 --- /dev/null +++ b/layers/+lang/idris/config.el @@ -0,0 +1,13 @@ +;;; config.el --- Idris Layer config File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Timothy Jones +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(spacemacs|defvar-company-backends idris-mode) +(spacemacs|defvar-company-backends idris-repl-mode) diff --git a/layers/+lang/idris/img/idris.png b/layers/+lang/idris/img/idris.png new file mode 100644 index 0000000..4a3ee35 Binary files /dev/null and b/layers/+lang/idris/img/idris.png differ diff --git a/layers/+lang/idris/packages.el b/layers/+lang/idris/packages.el new file mode 100644 index 0000000..7a9d9e5 --- /dev/null +++ b/layers/+lang/idris/packages.el @@ -0,0 +1,127 @@ +;;; packages.el --- Idris Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Timothy Jones +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq idris-packages '(company + idris-mode + golden-ratio + popwin)) + +(defun idris/post-init-company () + (spacemacs|add-company-hook idris-mode) + (spacemacs|add-company-hook idris-repl-mode) + (push 'company-capf company-backends-idris-mode) + (push 'company-capf company-backends-idris-repl-mode)) + +(defun idris/init-idris-mode () + (use-package idris-mode + :defer t + :init (spacemacs/register-repl 'idris-mode 'idris-repl "idris") + :config + (progn + (defun spacemacs/idris-load-file-and-focus (&optional set-line) + "Pass the current buffer's file to the REPL and switch to it in +`insert state'." + (interactive "p") + (idris-load-file set-line) + (idris-pop-to-repl) + (evil-insert-state)) + + (defun spacemacs/idris-load-forward-line-and-focus () + "Pass the next line to REPL and switch to it in `insert state'." + (interactive) + (idris-load-forward-line) + (idris-pop-to-repl) + (evil-insert-state)) + + (defun spacemacs/idris-load-backward-line-and-focus () + "Pass the previous line to REPL and switch to it in `insert state'." + (interactive) + (idris-load-backward-line) + (idris-pop-to-repl) + (evil-insert-state)) + + ;; prefix + (spacemacs/declare-prefix-for-mode 'idris-mode "mb" "idris/build") + (spacemacs/declare-prefix-for-mode 'idris-mode "mi" "idris/editing") + (spacemacs/declare-prefix-for-mode 'idris-mode "mh" "idris/documentation") + (spacemacs/declare-prefix-for-mode 'idris-mode "ms" "idris/repl") + (spacemacs/declare-prefix-for-mode 'idris-mode "mm" "idris/term") + + (spacemacs/set-leader-keys-for-major-mode 'idris-mode + ;; Shorthands: rebind the standard evil-mode combinations to the local + ;; leader for the keys not used as a prefix below. + "c" 'idris-case-dwim + "d" 'idris-add-clause + "l" 'idris-make-lemma + "p" 'idris-proof-search + "r" 'idris-load-file + "t" 'idris-type-at-point + "w" 'idris-make-with-block + + ;; ipkg. + "bc" 'idris-ipkg-build + "bC" 'idris-ipkg-clean + "bi" 'idris-ipkg-install + "bp" 'idris-open-package-file + + ;; Interactive editing. + "ia" 'idris-proof-search + "ic" 'idris-case-dwim + "ie" 'idris-make-lemma + "im" 'idris-add-missing + "ir" 'idris-refine + "is" 'idris-add-clause + "iw" 'idris-make-with-block + + ;; Documentation. + "ha" 'idris-apropos + "hd" 'idris-docs-at-point + "hs" 'idris-type-search + "ht" 'idris-type-at-point + + ;; Active term manipulations. + "mn" 'idris-normalise-term + "mi" 'idris-show-term-implicits + "mh" 'idris-hide-term-implicits + "mc" 'idris-show-core-term + + ;; REPL + "'" 'idris-repl + "sb" 'idris-load-file + "sB" 'spacemacs/idris-load-file-and-focus + "si" 'idris-repl + "sn" 'idris-load-forward-line + "sN" 'spacemacs/idris-load-forward-line-and-focus + "sp" 'idris-load-backward-line + "sP" 'spacemacs/idris-load-backward-line-and-focus + "ss" 'idris-pop-to-repl + "sq" 'idris-quit))) + + ;; open special buffers in motion state so they can be closed with ~q~ + (evil-set-initial-state 'idris-compiler-notes-mode 'motion) + (evil-set-initial-state 'idris-hole-list-mode 'motion) + (evil-set-initial-state 'idris-info-mode 'motion)) + +(defun idris/pre-init-golden-ratio () + (spacemacs|use-package-add-hook golden-ratio + :post-config + (dolist (x '("*idris-notes*" "*idris-holes*" "*idris-info*")) + (add-to-list 'golden-ratio-exclude-buffer-names x)))) + +(defun idris/pre-init-popwin () + (spacemacs|use-package-add-hook popwin + :post-config + (push '("*idris-notes*" :dedicated t :position bottom :stick t :noselect nil :height 0.4) + popwin:special-display-config) + (push '("*idris-holes*" :dedicated t :position bottom :stick t :noselect nil :height 0.4) + popwin:special-display-config) + (push '("*idris-info*" :dedicated t :position bottom :stick t :noselect nil :height 0.4) + popwin:special-display-config))) diff --git a/layers/+lang/ipython-notebook/README.org b/layers/+lang/ipython-notebook/README.org new file mode 100644 index 0000000..0009d3f --- /dev/null +++ b/layers/+lang/ipython-notebook/README.org @@ -0,0 +1,157 @@ +#+TITLE: IPython Notebook layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#list-of-todos][List of TODOS]] + - [[#maybe-itd-be-better-if-there-was-a-state-for-this][Maybe it'd be better if there was a state for this]] + - [[#make-more-keybinding-to-connect-to-a-python-buffer][Make more keybinding to =connect= to a python buffer]] + - [[#deleting-visual-regions-dont-work-find-out-why][Deleting visual regions don't work, find out why]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#dependencies][Dependencies]] + - [[#what-needs-to-be-run][What needs to be run]] + - [[#using-the-ipython-notebook][Using the IPython notebook]] + - [[#open-notebook-list][Open Notebook List]] + - [[#key-bindings][Key Bindings]] + - [[#transient-state-ipython-notebook][Transient-state: =ipython-notebook=]] + - [[#normal-mode][Normal mode]] + - [[#insert-mode][Insert mode]] + - [[#traceback-mode][Traceback mode]] + - [[#screenshots][Screenshots]] + - [[#light][Light]] + - [[#dark][Dark]] + - [[#bonus][Bonus]] + +* Description +This layer adds support for the package =emacs-ipython-notebook=. + +Do not hesitate to check the original package README [[https://github.com/millejoh/emacs-ipython-notebook][here]]. Also the wiki has +lots of informative stuff. + +* Features +- Keybindings available through transient-state or leader key +- Lazy-loading + +* List of TODOS +This is a WIP, feel free to collaborate. + +** TODO Maybe it'd be better if there was a state for this +** TODO Make more keybinding to =connect= to a python buffer +** TODO Deleting visual regions don't work, find out why + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =ipython-notebook= to the existing =dotspacemacs-configuration-layers= list +in this file. + +** Dependencies +Install IPython Notebook > 3 +#+begin_src sh + pip install ipython[notebook] +#+end_src + +** What needs to be run +Have an IPython notebook running +#+begin_src sh + ipython notebook +#+end_src + +* Using the IPython notebook +** Open Notebook List +This layer is lazy loaded so the transient-state will only work after you summon the +command =ein:notebooklist-open= which is bound to ~SPC a i n~ + +** Key Bindings +The key bindings can be used through a transient state or the usual evil-leader. + +*** Transient-state: =ipython-notebook= +Once you are in the ipython notebook you can activate the transient-state with +~SPC m .~ + +The following table lists the keys. Use them as listed in the transient-state or +prefix with ~SPC m~ to use with your evil-leader. + +| Key | Function | +|---------+-------------------------------------------| +| ~h~ | ein:notebook-worksheet-open-prev-or-last | +| ~j~ | ein:worksheet-goto-next-input | +| ~k~ | ein:worksheet-goto-prev-input | +| ~l~ | ein:notebook-worksheet-open-next-or-first | +| ~H~ | ein:notebook-worksheet-move-prev | +| ~J~ | ein:worksheet-move-cell-down | +| ~K~ | ein:worksheet-move-cell-up | +| ~L~ | ein:notebook-worksheet-move-next | +| ~t~ | ein:worksheet-toggle-output | +| ~d~ | ein:worksheet-kill-cell | +| ~R~ | ein:worksheet-rename-sheet | +| ~y~ | ein:worksheet-copy-cell | +| ~p~ | ein:worksheet-yank-cell | +| ~i~ | ein:worksheet-insert-cell-below | +| ~I~ | ein:worksheet-insert-cell-above | +| ~u~ | ein:worksheet-change-cell-type | +| ~RET~ | ein:worksheet-execute-cell-and-goto-next | +| ~C-l~ | ein:worksheet-clear-output | +| ~C-S-l~ | ein:worksheet-clear-all-output | +| ~C-o~ | ein:console-open | +| ~C-k~ | ein:worksheet-merge-cell | +| ~C-j~ | spacemacs/ein:worksheet-merge-cell-next | +| ~C-s~ | ein:notebook-save-notebook-command | +| ~C-r~ | ein:notebook-rename-command | +| ~1~ | ein:notebook-worksheet-open-1th | +| ~2~ | ein:notebook-worksheet-open-2th | +| ~3~ | ein:notebook-worksheet-open-3th | +| ~4~ | ein:notebook-worksheet-open-4th | +| ~5~ | ein:notebook-worksheet-open-5th | +| ~6~ | ein:notebook-worksheet-open-6th | +| ~7~ | ein:notebook-worksheet-open-7th | +| ~8~ | ein:notebook-worksheet-open-8th | +| ~9~ | ein:notebook-worksheet-open-last | +| ~+~ | ein:notebook-worksheet-insert-next | +| ~-~ | ein:notebook-worksheet-delete | +| ~x~ | ein:notebook-close | + +*** Normal mode +In normal mode the following key bindings are defined: + +| Key | Function | +|---------+------------------------------------------| +| ~gj~ | ein:worksheet-goto-next-input | +| ~gk~ | ein:worksheet-goto-prev-input | +| ~C-RET~ | ein:worksheet-execute-cell | +| ~S-RET~ | ein:worksheet-execute-cell-and-goto-next | + +Also ~SPC f s~ saves the notebook like you would a regular buffer. + +*** Insert mode +In normal mode the following key bindings are defined: + +| Key | Function | +|---------+------------------------------------------| +| ~C-RET~ | ein:worksheet-execute-cell | +| ~S-RET~ | ein:worksheet-execute-cell-and-goto-next | + +*** Traceback mode +In traceback mode the following key bindings are defined: + +| key | Function | +|-------+----------------------------------------| +| ~RET~ | ein:tb-jump-to-source-at-point-command | +| ~n~ | ein:tb-next-item | +| ~p~ | ein:tb-prev-item | +| ~q~ | bury-buffer | + +* Screenshots +** Light +#+attr_html: :width 400px +[[file:img/light.png]] + +** Dark +#+attr_html: :width 400px +[[file:img/dark.png]] + +* Bonus +If you want to have a matplotlibrc that looks good with a dark background try +using [[file:matplotlibrc][this]] =matplotlibrc=. Plot background is always transparent by default so +it will look okay for most dark themes out there. diff --git a/layers/+lang/ipython-notebook/img/dark.png b/layers/+lang/ipython-notebook/img/dark.png new file mode 100644 index 0000000..6daf5b4 Binary files /dev/null and b/layers/+lang/ipython-notebook/img/dark.png differ diff --git a/layers/+lang/ipython-notebook/img/light.png b/layers/+lang/ipython-notebook/img/light.png new file mode 100644 index 0000000..904eb0d Binary files /dev/null and b/layers/+lang/ipython-notebook/img/light.png differ diff --git a/layers/+lang/ipython-notebook/matplotlibrc b/layers/+lang/ipython-notebook/matplotlibrc new file mode 100644 index 0000000..ae7f4e7 --- /dev/null +++ b/layers/+lang/ipython-notebook/matplotlibrc @@ -0,0 +1,27 @@ +# -*- conf-unix -*- + +text.color : dcdccc + +patch.facecolor : 8cd0d3 # blue +patch.edgecolor : eeeeee + +axes.facecolor : 383838 # axes background color +axes.edgecolor : bcbcbc # axes edge color +axes.grid : True # display grid or not +axes.labelcolor : dcdccc +axes.prop_cycle : 8cd0d3, 7f9f7f, cc9393, 93e0e3, dc8cc3, f0dfaf, dcdccc +# (system default) blue, green, red, cyan, magenta, yellow, black + +xtick.color : dcdccc # color of the tick labels +xtick.direction : in # direction: in or out +ytick.color : dcdccc # color of the tick labels +ytick.direction : in # direction: in or out + +legend.fancybox : True # if True, use a rounded box for the + +figure.facecolor : 3f3f3f # figure facecolor; 0.75 is scalar gray +figure.edgecolor : 383838 # figure edgecolor + +# See also: +# * Sane color scheme for Matplotlib +# http://www.huyng.com/posts/sane-color-scheme-for-matplotlib/ diff --git a/layers/+lang/ipython-notebook/packages.el b/layers/+lang/ipython-notebook/packages.el new file mode 100644 index 0000000..7bfe162 --- /dev/null +++ b/layers/+lang/ipython-notebook/packages.el @@ -0,0 +1,160 @@ +;;; packages.el --- ipython Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq ipython-notebook-packages '(ein)) + +(defun ipython-notebook/init-ein () + (use-package ein + :defer t + :commands ein:notebooklist-open + :init + (progn + (spacemacs/set-leader-keys "ain" 'ein:notebooklist-open) + (with-eval-after-load 'ein-notebooklist + (evilified-state-evilify-map ein:notebooklist-mode-map + :mode ein:notebooklist-mode + :bindings + (kbd "o") 'spacemacs/ace-buffer-links) + (define-key ein:notebooklist-mode-map "o" 'spacemacs/ace-buffer-links))) + :config + (progn + (defun spacemacs/ein:worksheet-merge-cell-next () + (interactive) + (ein:worksheet-merge-cell (ein:worksheet--get-ws-or-error) (ein:worksheet-get-current-cell) t t)) + + (defun spacemacs//concat-leader (key) + (if dotspacemacs-major-mode-leader-key + (concat dotspacemacs-major-mode-leader-key key) + (concat "," key))) + + (spacemacs/set-leader-keys-for-major-mode 'ein:notebook-multilang-mode + "y" 'ein:worksheet-copy-cell + "p" 'ein:worksheet-yank-cell + "d" 'ein:worksheet-kill-cell + "h" 'ein:notebook-worksheet-open-prev-or-last + "i" 'ein:worksheet-insert-cell-below + "I" 'ein:worksheet-insert-cell-above + "j" 'ein:worksheet-goto-next-input + "k" 'ein:worksheet-goto-prev-input + "l" 'ein:notebook-worksheet-open-next-or-first + "H" 'ein:notebook-worksheet-move-prev + "J" 'ein:worksheet-move-cell-down + "K" 'ein:worksheet-move-cell-up + "L" 'ein:notebook-worksheet-move-next + "t" 'ein:worksheet-toggle-output + "R" 'ein:worksheet-rename-sheet + "RET" 'ein:worksheet-execute-cell-and-goto-next + ;; Output + " C-l" 'ein:worksheet-clear-output + " C-S-l" 'ein:worksheet-clear-all-output + ;;Console + " C-o" 'ein:console-open + ;; Merge cells + " C-k" 'ein:worksheet-merge-cell + " C-j" 'spacemacs/ein:worksheet-merge-cell-next + ;; Notebook + " C-s" 'ein:notebook-save-notebook-command + " C-r" 'ein:notebook-rename-command + "1" 'ein:notebook-worksheet-open-1th + "2" 'ein:notebook-worksheet-open-2th + "3" 'ein:notebook-worksheet-open-3th + "4" 'ein:notebook-worksheet-open-4th + "5" 'ein:notebook-worksheet-open-5th + "6" 'ein:notebook-worksheet-open-6th + "7" 'ein:notebook-worksheet-open-7th + "8" 'ein:notebook-worksheet-open-8th + "9" 'ein:notebook-worksheet-open-last + "+" 'ein:notebook-worksheet-insert-next + "-" 'ein:notebook-worksheet-delete + "x" 'ein:notebook-close + "u" 'ein:worksheet-change-cell-type + "fs" 'ein:notebook-save-notebook-command) + + ;; keybindings for ipython notebook traceback mode + (spacemacs/set-leader-keys-for-major-mode 'ein:traceback-mode + "RET" 'ein:tb-jump-to-source-at-point-command + "n" 'ein:tb-next-item + "p" 'ein:tb-prev-item + "q" 'bury-buffer) + + ;; keybindings mirror ipython web interface behavior + (evil-define-key 'insert ein:notebook-multilang-mode-map + (kbd "") 'ein:worksheet-execute-cell + (kbd "") 'ein:worksheet-execute-cell-and-goto-next) + + (evil-define-key 'normal ein:notebook-multilang-mode-map + ;; keybindings mirror ipython web interface behavior + (kbd "") 'ein:worksheet-execute-cell + (kbd "") 'ein:worksheet-execute-cell-and-goto-next + "gj" 'ein:worksheet-goto-next-input + "gk" 'ein:worksheet-goto-prev-input) + + ;; if this is not required then the following keygindings fail + (require 'ein-multilang) + (define-key ein:notebook-multilang-mode-map (kbd "M-j") 'ein:worksheet-move-cell-down) + (define-key ein:notebook-multilang-mode-map (kbd "M-k") 'ein:worksheet-move-cell-up) + + (spacemacs|define-transient-state ipython-notebook + :title "iPython Notebook Transient State" + :doc " + Operations on Cells^^^^^^ On Worksheets^^^^ Other + ----------------------------^^^^^^ ------------------------^^^^ ----------------------------------^^^^ + [_k_/_j_]^^ select prev/next [_h_/_l_] select prev/next [_t_]^^ toggle output + [_K_/_J_]^^ move up/down [_H_/_L_] move left/right [_C-l_/_C-S-l_] clear/clear all output + [_C-k_/_C-j_]^^ merge above/below [_1_.._9_] open [1st..last] [_C-o_]^^ open console + [_O_/_o_]^^ insert above/below [_+_/_-_] create/delete [_C-s_/_C-r_] save/rename notebook + [_y_/_p_/_d_] copy/paste ^^^^ [_x_]^^ close notebook + [_u_]^^^^ change type ^^^^ [_q_]^^ quit transient-state + [_RET_]^^^^ execute" + :evil-leader-for-mode (ein:notebook-multilang-mode . ".") + :bindings + ("q" nil :exit t) + ("?" spacemacs//ipython-notebook-ms-toggle-doc) + ("h" ein:notebook-worksheet-open-prev-or-last) + ("j" ein:worksheet-goto-next-input) + ("k" ein:worksheet-goto-prev-input) + ("l" ein:notebook-worksheet-open-next-or-first) + ("H" ein:notebook-worksheet-move-prev) + ("J" ein:worksheet-move-cell-down) + ("K" ein:worksheet-move-cell-up) + ("L" ein:notebook-worksheet-move-next) + ("t" ein:worksheet-toggle-output) + ("d" ein:worksheet-kill-cell) + ("R" ein:worksheet-rename-sheet) + ("y" ein:worksheet-copy-cell) + ("p" ein:worksheet-yank-cell) + ("o" ein:worksheet-insert-cell-below) + ("O" ein:worksheet-insert-cell-above) + ("u" ein:worksheet-change-cell-type) + ("RET" ein:worksheet-execute-cell-and-goto-next) + ;; Output + ("C-l" ein:worksheet-clear-output) + ("C-S-l" ein:worksheet-clear-all-output) + ;;Console + ("C-o" ein:console-open) + ;; Merge cells + ("C-k" ein:worksheet-merge-cell) + ("C-j" spacemacs/ein:worksheet-merge-cell-next) + ;; Notebook + ("C-s" ein:notebook-save-notebook-command) + ("C-r" ein:notebook-rename-command) + ("1" ein:notebook-worksheet-open-1th) + ("2" ein:notebook-worksheet-open-2th) + ("3" ein:notebook-worksheet-open-3th) + ("4" ein:notebook-worksheet-open-4th) + ("5" ein:notebook-worksheet-open-5th) + ("6" ein:notebook-worksheet-open-6th) + ("7" ein:notebook-worksheet-open-7th) + ("8" ein:notebook-worksheet-open-8th) + ("9" ein:notebook-worksheet-open-last) + ("+" ein:notebook-worksheet-insert-next) + ("-" ein:notebook-worksheet-delete) + ("x" ein:notebook-close))))) diff --git a/layers/+lang/java/README.org b/layers/+lang/java/README.org new file mode 100644 index 0000000..17d676b --- /dev/null +++ b/layers/+lang/java/README.org @@ -0,0 +1,174 @@ +#+TITLE: Java layer + +[[file:img/java.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#layer-installation][Layer Installation]] + - [[#layer][Layer]] + - [[#eclim][Eclim]] + - [[#installation][Installation]] + - [[#usage][Usage]] + - [[#key-bindings][Key bindings]] + - [[#java-mode][Java-mode]] + - [[#project-management][Project management]] + - [[#eclimd][Eclimd]] + - [[#maven][Maven]] + - [[#goto][Goto]] + - [[#refactoring][Refactoring]] + - [[#documentation-find][Documentation, Find]] + - [[#problems][Problems]] + - [[#tests][Tests]] + - [[#problems-buffer][Problems buffer]] + - [[#projects-buffer][Projects buffer]] + +* Description +This layer adds support for the Java language using the [[http://eclim.org][Eclim]] client/server. + +* Layer Installation +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =java= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Eclim +Eclim provides the ability to access Eclipse features such as code completion, +searching, code validation, and many more. + +*** Installation +For installation check the [[http://eclim.org/install.html#download][official page]]. + +Then set the =Eclipse= and =Eclim= paths in =dotspacemacs/user-config=, +for instance: + +#+BEGIN_SRC elisp + (setq eclim-eclipse-dirs "~/opt/eclipse" + eclim-executable "~/opt/eclipse/eclim") +#+END_SRC + +You can also configure other options, as shown below: + +#+BEGIN_SRC elisp + (setq + ;; Use another eclimd executable + eclimd-executable "/path/to/another/executable" + ;; Specify the workspace to use by default + eclimd-default-workspace "/path/to/default/eclipse/workspace" + ;; Whether or not to block emacs until eclimd is ready + eclimd-wait-for-process t) +#+END_SRC + +*** Usage +Start the eclim daemon with ~SPC m d s~ and stop it with ~SPC m d k~. (See +below.) + +* Key bindings +** Java-mode +*** Project management + +| Key Binding | Description | +|-------------+--------------------------------| +| ~SPC m p b~ | Build project | +| ~SPC m p c~ | Create project | +| ~SPC m p d~ | Delete project | +| ~SPC m p g~ | Open file in current project | +| ~SPC m p i~ | Import project | +| ~SPC m p j~ | Information about project | +| ~SPC m p k~ | Close project | +| ~SPC m p o~ | Open project | +| ~SPC m p p~ | Open project management buffer | +| ~SPC m p u~ | Update project | + +*** Eclimd + +| Key Binding | Description | +|-------------+--------------| +| ~SPC m d s~ | Start daemon | +| ~SPC m d k~ | Stop daemon | + +*** Maven + +| Key Binding | Description | +|-------------+--------------------------------| +| ~SPC m m i~ | Run maven clean install | +| ~SPC m m I~ | Run maven install | +| ~SPC m m p~ | Run one already goal from list | +| ~SPC m m r~ | Run maven goals | +| ~SPC m m R~ | Run one maven goal | +| ~SPC m m t~ | Run maven test | + +*** Goto + +| Key Binding | Description | +|-------------+---------------------------------------------| +| ~M-​,​~ | jump back from go to declaration/definition | +| ~SPC m g g~ | go to declaration | +| ~SPC m g t~ | go to type definition | + +*** Refactoring + +| Key Binding | Description | +|-------------+------------------| +| ~SPC m r i~ | optimize imports | +| ~SPC m r f~ | Format file | +| ~SPC m r r~ | Rename symbol | + +*** Documentation, Find + +| Key Binding | Description | +|-------------+----------------------------------------| +| ~SPC m f f~ | general find in project | +| ~SPC m h h~ | show documentation for symbol at point | +| ~SPC m h u~ | show usages for symbol at point | + +*** Problems + +| Key Binding | Description | +|-------------+--------------------------------------------| +| ~SPC m e a~ | set all problems for next/prev action | +| ~SPC m e b~ | open buffer with problems | +| ~SPC m e c~ | show options with problem corrections | +| ~SPC m e e~ | set only errors for next/prev action | +| ~SPC m e f~ | set only current file for next/prev action | +| ~SPC m e n~ | go to next problem | +| ~SPC m e o~ | open buffer with problems | +| ~SPC m e p~ | go to previous problem | +| ~SPC m e w~ | set warnings for next/prev action | + +*** Tests + +| Key Binding | Description | +|-------------+---------------------------------------------------------------| +| ~SPC m t t~ | run JUnit tests for current method or current file or project | + +** Problems buffer + +| Key Binding | Description | +|-------------+-------------------------------------| +| ~RET~ | go to problem place | +| ~a~ | show all problems | +| ~e~ | show only errors | +| ~f~ | show problems only for current file | +| ~g~ | refresh problems | +| ~q~ | quit | +| ~w~ | show only warnings | + +** Projects buffer + +| Key Binding | Description | +|-------------+--------------------------------------------| +| ~RET~ | go to current project | +| ~c~ | go to problem place | +| ~D~ | delete project | +| ~g~ | refresh buffer | +| ~i~ | info about current project | +| ~I~ | import existing project into the workspace | +| ~m~ | mark current project | +| ~M~ | mark all projects | +| ~N~ | create new project | +| ~o~ | open project | +| ~p~ | update project | +| ~q~ | quit | +| ~R~ | rename current project | +| ~u~ | unmark current project | +| ~U~ | unmark all projects | diff --git a/layers/+lang/java/config.el b/layers/+lang/java/config.el new file mode 100644 index 0000000..170fc00 --- /dev/null +++ b/layers/+lang/java/config.el @@ -0,0 +1,13 @@ +;;; packages.el --- Java configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Lukasz Klich +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(spacemacs|defvar-company-backends java-mode) + +(spacemacs|define-jump-handlers java-mode) diff --git a/layers/+lang/java/funcs.el b/layers/+lang/java/funcs.el new file mode 100644 index 0000000..4f10940 --- /dev/null +++ b/layers/+lang/java/funcs.el @@ -0,0 +1,43 @@ +;;; packages.el --- Java functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Lukasz Klich +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spacemacs/java-completing-dot () + "Insert a period and show company completions." + (interactive "*") + (spacemacs//java-delete-horizontal-space) + (insert ".") + (company-emacs-eclim 'interactive)) + +(defun spacemacs/java-completing-double-colon () + "Insert double colon and show company completions." + (interactive "*") + (spacemacs//java-delete-horizontal-space) + (insert ":") + (let ((curr (point))) + (when (s-matches? (buffer-substring (- curr 2) (- curr 1)) ":") + (company-emacs-eclim 'interactive)))) + +(defun spacemacs//java-delete-horizontal-space () + (when (s-matches? (rx (+ (not space))) + (buffer-substring (line-beginning-position) (point))) + (delete-horizontal-space t))) + +(defun spacemacs/java-maven-test () + (interactive) + (eclim-maven-run "test")) + +(defun spacemacs/java-maven-clean-install () + (interactive) + (eclim-maven-run "clean install")) + +(defun spacemacs/java-maven-install () + (interactive) + (eclim-maven-run "install")) diff --git a/layers/+lang/java/img/java.png b/layers/+lang/java/img/java.png new file mode 100644 index 0000000..97e234e Binary files /dev/null and b/layers/+lang/java/img/java.png differ diff --git a/layers/+lang/java/packages.el b/layers/+lang/java/packages.el new file mode 100644 index 0000000..b15ff46 --- /dev/null +++ b/layers/+lang/java/packages.el @@ -0,0 +1,163 @@ +;;; packages.el --- Java Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Lukasz Klich +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq java-packages + '( + company + (company-emacs-eclim :toggle (configuration-layer/package-usedp 'company)) + eclim + ggtags + helm-gtags + (java-mode :location built-in) + )) + +(defun java/post-init-company () + (spacemacs|add-company-hook java-mode)) + +(defun java/init-company-emacs-eclim () + (use-package company-emacs-eclim + :defer t + :init (push 'company-emacs-eclim company-backends-java-mode))) + +(defun java/init-eclim () + (use-package eclim + :defer t + :diminish eclim-mode + :init + (progn + (add-hook 'java-mode-hook 'eclim-mode) + (add-to-list 'spacemacs-jump-handlers-java-mode 'eclim-java-find-declaration)) + :config + (progn + (require 'eclimd) + (setq help-at-pt-display-when-idle t + help-at-pt-timer-delay 0.1) + (help-at-pt-set-timer) + + (add-to-list 'minor-mode-alist + '(eclim-mode (:eval (eclim-modeline-string)))) + + (evil-define-key 'insert java-mode-map + (kbd ".") 'spacemacs/java-completing-dot + (kbd ":") 'spacemacs/java-completing-double-colon + (kbd "M-.") 'eclim-java-find-declaration + (kbd "M-,") 'pop-tag-mark + (kbd "M-") 'eclim-java-find-declaration + (kbd "") 'pop-tag-mark) + + (evil-define-key 'normal java-mode-map + (kbd "M-.") 'eclim-java-find-declaration + (kbd "M-,") 'pop-tag-mark + (kbd "M-") 'eclim-java-find-declaration + (kbd "") 'pop-tag-mark) + + (evil-define-key 'normal eclim-problems-mode-map + (kbd "a") 'eclim-problems-show-all + (kbd "e") 'eclim-problems-show-errors + (kbd "g") 'eclim-problems-buffer-refresh + (kbd "q") 'eclim-quit-window + (kbd "w") 'eclim-problems-show-warnings + (kbd "f") 'eclim-problems-toggle-filefilter + (kbd "c") 'eclim-problems-correct + (kbd "RET") 'eclim-problems-open-current) + + (evil-define-key 'normal eclim-project-mode-map + (kbd "N") 'eclim-project-create + (kbd "m") 'eclim-project-mark-current + (kbd "M") 'eclim-project-mark-all + (kbd "u") 'eclim-project-unmark-current + (kbd "U") 'eclim-project-unmark-all + (kbd "o") 'eclim-project-open + (kbd "c") 'eclim-project-close + (kbd "i") 'eclim-project-info-mode + (kbd "I") 'eclim-project-import + (kbd "RET") 'eclim-project-goto + (kbd "D") 'eclim-project-delete + (kbd "p") 'eclim-project-update + (kbd "g") 'eclim-project-mode-refresh + (kbd "R") 'eclim-project-rename + (kbd "q") 'eclim-quit-window) + + (spacemacs/set-leader-keys-for-major-mode 'java-mode + "ea" 'eclim-problems-show-all + "eb" 'eclim-problems + "ec" 'eclim-problems-correct + "ee" 'eclim-problems-show-errors + "ef" 'eclim-problems-toggle-filefilter + "en" 'eclim-problems-next-same-window + "eo" 'eclim-problems-open + "ep" 'eclim-problems-previous-same-window + "ew" 'eclim-problems-show-warnings + + "ds" 'start-eclimd + "dk" 'stop-eclimd + + "ff" 'eclim-java-find-generic + + "gt" 'eclim-java-find-type + + "rc" 'eclim-java-constructor + "rg" 'eclim-java-generate-getter-and-setter + "rf" 'eclim-java-format + "ri" 'eclim-java-import-organize + "rj" 'eclim-java-implement + "rr" 'eclim-java-refactor-rename-symbol-at-point + + "hc" 'eclim-java-call-hierarchy + "hh" 'eclim-java-show-documentation-for-current-element + "hi" 'eclim-java-hierarchy + "hu" 'eclim-java-find-references + + "mi" 'spacemacs/java-maven-clean-install + "mI" 'spacemacs/java-maven-install + "mp" 'eclim-maven-lifecycle-phases + "mr" 'eclim-maven-run + "mR" 'eclim-maven-lifecycle-phase-run + "mt" 'spacemacs/java-maven-test + + "aa" 'eclim-ant-run + "ac" 'eclim-ant-clear-cache + "ar" 'eclim-ant-run + "av" 'eclim-ant-validate + + "pb" 'eclim-project-build + "pc" 'eclim-project-create + "pd" 'eclim-project-delete + "pg" 'eclim-project-goto + "pi" 'eclim-project-import + "pj" 'eclim-project-info-mode + "pk" 'eclim-project-close + "po" 'eclim-project-open + "pp" 'eclim-project-mode + "pu" 'eclim-project-update + + "tt" 'eclim-run-junit)))) + +(defun java/post-init-ggtags () + (add-hook 'java-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun java/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'java-mode)) + +(defun java/init-java-mode () + (setq java/key-binding-prefixes '(("me" . "errors") + ("md" . "eclimd") + ("mf" . "find") + ("mg" . "goto") + ("mr" . "refactor") + ("mh" . "documentation") + ("mm" . "maven") + ("ma" . "ant") + ("mp" . "project") + ("mt" . "test"))) + (mapc (lambda(x) (spacemacs/declare-prefix-for-mode + 'java-mode (car x) (cdr x))) + java/key-binding-prefixes)) diff --git a/layers/+lang/javascript/README.org b/layers/+lang/javascript/README.org new file mode 100644 index 0000000..b6e3659 --- /dev/null +++ b/layers/+lang/javascript/README.org @@ -0,0 +1,212 @@ +#+TITLE: JavaScript layer + +[[file:img/javascript.png]] [[file:img/coffee.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features:]] + - [[#install][Install]] + - [[#configuration][Configuration]] + - [[#tern][Tern]] + - [[#indentation][Indentation]] + - [[#repl][REPL]] + - [[#key-bindings][Key Bindings]] + - [[#js2-mode][js2-mode]] + - [[#folding-js2-mode][Folding (js2-mode)]] + - [[#refactoring-js2-refactor][Refactoring (js2-refactor)]] + - [[#formatting-web-beautify][Formatting (web-beautify)]] + - [[#documentation-js-doc][Documentation (js-doc)]] + - [[#auto-complete-and-documentation-tern][Auto-complete and documentation (tern)]] + - [[#json][JSON]] + - [[#repl-skewer-mode][REPL (skewer-mode)]] + +* Description + +This layer adds support for the JavaScript language using [[https://github.com/mooz/js2-mode][js2-mode]]. + +** Features: +- Smart code folding +- Refactoring: done using [[https://github.com/magnars/js2-refactor.el][js2-refactor]]. +- Auto-completion and documentation: provided by [[http://ternjs.net/][tern]] +- CoffeeScript support +- Formatting with [[https://github.com/yasuyk/web-beautify][web-beautify]] +- Get the path to a JSON value with [[https://github.com/Sterlingg/json-snatcher][json-snatcher]] +- REPL available via [[https://github.com/skeeto/skewer-mode][skewer-mode]] and [[https://github.com/pandeiro/livid-mode][livid-mode]] + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =javascript= to the existing =dotspacemacs-configuration-layers= list in +this file. + +You will also need to install =tern= to use the auto-completion and +documentation features: +#+BEGIN_SRC sh + $ npm install -g tern +#+END_SRC + +To use the formatting features, install =js-beautify=: +#+BEGIN_SRC sh + $ npm install -g js-beautify +#+END_SRC + +To activate error checking using flycheck, install one of the [[http://www.flycheck.org/en/latest/languages.html#javascript][available linters]] +such as =ESLint= or =JSHint=: +#+BEGIN_SRC sh + $ npm install -g eslint + # or + $ npm install -g jshint +#+END_SRC + +* Configuration +** Tern +To make tern re-use the server across multiple different editing sessions (thus +creating multiple =.tern-port= files for each document you have open [[http://ternjs.net/doc/manual.html][see here +for more details]]): + +The variables provided below can be set when adding the =javascript= +configuration layer, as detailed in [[file:../../../doc/DOCUMENTATION.org::Setting%20configuration%20layers%20variables][this]] section of the documentation. + +#+BEGIN_SRC emacs-lisp + (javascript :variables javascript-disable-tern-port-files nil) +#+END_SRC + +Windows users may need to set the variable =tern-command= in order for emacs to +locate and launch tern server successfully. See [[https://github.com/syl20bnr/spacemacs/issues/5733][this open issue for more +details]]. The variable can be set when adding the =javascript= configuration +layer: + +#+BEGIN_SRC emacs-lisp + (javascript :variables tern-command '("node" "/path/to/tern/bin/tern")) +#+END_SRC + +** Indentation +To change how js2-mode indents code, set the variable =js2-basic-offset=, as +such: + +#+BEGIN_SRC emacs-lisp + (setq-default js2-basic-offset 2) +#+END_SRC + +Similarly, to change how js-mode indents JSON files, set the variable +=js-indent-level=, as such: + +#+BEGIN_SRC emacs-lisp + (setq-default js-indent-level 2) +#+END_SRC + +** REPL +To use the available JS repl, you need a running httpd server and a page loaded +with skewer. If a blank page serves your needs, just use the run-skewer command +in your javascript buffer. If you want to inject it in your own page, follow +[[https://github.com/skeeto/skewer-mode#skewering-with-cors][these instructions]] (install the Greasemonkey script and then click the triangle +in the top-right corner - if it turns green, you're good to go). + +* Key Bindings + +** js2-mode + +| Key Binding | Description | +|-------------+--------------------------------------| +| ~SPC m w~ | toggle js2-mode warnings and errors | +| ~%~ | jump between blockswith [[https://github.com/redguardtoo/evil-matchit][evil-matchit]] | + +** Folding (js2-mode) + +| Key Binding | Description | +|-------------+--------------------------| +| ~SPC m z c~ | hide element | +| ~SPC m z o~ | show element | +| ~SPC m z r~ | show all element | +| ~SPC m z e~ | toggle hide/show element | +| ~SPC m z F~ | toggle hide functions | +| ~SPC m z C~ | toggle hide comments | + +** Refactoring (js2-refactor) + +Bindings should match the plain emacs assignments. + +| Key Binding | Description | +|---------------+----------------------------------------------------------------------------------------------------------------| +| ~SPC m k~ | deletes to the end of the line, but does not cross semantic boundaries | +| ~SPC m r 3 i~ | converts ternary operator to if-statement | +| ~SPC m r a g~ | creates a =/* global */= annotation if it is missing, and adds var to point to it | +| ~SPC m r a o~ | replaces arguments to a function call with an object literal of named arguments | +| ~SPC m r b a~ | moves the last child out of current function, if-statement, for-loop or while-loop | +| ~SPC m r c a~ | converts a multiline array to one line | +| ~SPC m r c o~ | converts a multiline object literal to one line | +| ~SPC m r c u~ | converts a multiline function to one line (expecting semicolons as statement delimiters) | +| ~SPC m r e a~ | converts a one line array to multiline | +| ~SPC m r e f~ | extracts the marked expressions into a new named function | +| ~SPC m r e m~ | extracts the marked expressions out into a new method in an object literal | +| ~SPC m r e o~ | converts a one line object literal to multiline | +| ~SPC m r e u~ | converts a one line function to multiline (expecting semicolons as statement delimiters) | +| ~SPC m r e v~ | takes a marked expression and replaces it with a var | +| ~SPC m r i g~ | creates a shortcut for a marked global by injecting it in the wrapping immediately invoked function expression | +| ~SPC m r i p~ | changes the marked expression to a parameter in a local function | +| ~SPC m r i v~ | replaces all instances of a variable with its initial value | +| ~SPC m r l p~ | changes a parameter to a local var in a local function | +| ~SPC m r l t~ | adds a console.log statement for what is at point (or region) | +| ~SPC m r r v~ | renames the variable on point and all occurrences in its lexical scope | +| ~SPC m r s l~ | moves the next statement into current function, if-statement, for-loop, while-loop | +| ~SPC m r s s~ | splits a =String= | +| ~SPC m r s v~ | splits a =var= with multiple vars declared into several =var= statements | +| ~SPC m r t f~ | toggle between function declaration and function expression | +| ~SPC m r u w~ | replaces the parent statement with the selected region | +| ~SPC m r v t~ | changes local =var a= to be =this.a= instead | +| ~SPC m r w i~ | wraps the entire buffer in an immediately invoked function expression | +| ~SPC m r w l~ | wraps the region in a for-loop | +| ~SPC m x m j~ | move line down, while keeping commas correctly placed | +| ~SPC m x m k~ | move line up, while keeping commas correctly placed | + +** Formatting (web-beautify) + +| Key Binding | Description | +|-------------+--------------------------------------------------------------| +| ~SPC m =~ | beautify code in js2-mode, json-mode, web-mode, and css-mode | + +*** Documentation (js-doc) + +You can check more [[https://github.com/mooz/js-doc/][here]] + +| Key Binding | Description | +|---------------+---------------------------------------| +| ~SPC m r d b~ | insert JSDoc comment for current file | +| ~SPC m r d f~ | insert JSDoc comment for function | +| ~SPC m r d t~ | insert tag to comment | +| ~SPC m r d h~ | show list of available jsdoc tags | + +** Auto-complete and documentation (tern) + +| Key Binding | Description | +|---------------+------------------------------------------------------------------------------------------| +| ~SPC m C-g~ | brings you back to last place you were when you pressed M-.. | +| ~SPC m g g~ | jump to the definition of the thing under the cursor | +| ~SPC m g G~ | jump to definition for the given name | +| ~SPC m h d~ | find docs of the thing under the cursor. Press again to open the associated URL (if any) | +| ~SPC m h t~ | find the type of the thing under the cursor | +| ~SPC m r r V~ | rename variable under the cursor using tern | + +** JSON + +| Key Binding | Description | +|-------------+------------------------------------| +| ~SPC m h p~ | Get the path of the value at point | + +** REPL (skewer-mode) + +| Key Binding | Description | +|-------------+------------------------------------------------------------------| +| ~SPC m e e~ | evaluates the last expression | +| ~SPC m e E~ | evaluates and inserts the result of the last expression at point | + +| Key Binding | Description | +|-------------+------------------------------------------------------------------------------------| +| ~SPC m s a~ | Toggle live evaluation of whole buffer in REPL on buffer changes | +| ~SPC m s b~ | send current buffer contents to the skewer REPL | +| ~SPC m s B~ | send current buffer contents to the skewer REPL and switch to it in insert state | +| ~SPC m s f~ | send current function at point to the skewer REPL | +| ~SPC m s F~ | send current function at point to the skewer REPL and switch to it in insert state | +| ~SPC m s i~ | starts/switch to the skewer REPL | +| ~SPC m s r~ | send current region to the skewer REPL | +| ~SPC m s R~ | send current region to the skewer REPL and switch to it in insert state | +| ~SPC m s s~ | switch to REPL | diff --git a/layers/+lang/javascript/config.el b/layers/+lang/javascript/config.el new file mode 100644 index 0000000..184e760 --- /dev/null +++ b/layers/+lang/javascript/config.el @@ -0,0 +1,19 @@ +;;; config.el --- Javascript Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(spacemacs|defvar-company-backends js2-mode) + +(spacemacs|define-jump-handlers js2-mode) + +(defvar javascript-disable-tern-port-files t + "Stops tern from creating tern port files.") diff --git a/layers/+lang/javascript/funcs.el b/layers/+lang/javascript/funcs.el new file mode 100644 index 0000000..f1b2a60 --- /dev/null +++ b/layers/+lang/javascript/funcs.el @@ -0,0 +1,31 @@ +;;; funcs.el --- Javascript Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Muneeb Shaikh +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + +;; tern + +(defun spacemacs//set-tern-key-bindings (mode) + "Set the key bindings for tern and the given MODE." + (add-to-list (intern (format "spacemacs-jump-handlers-%S" mode)) + 'tern-find-definition) + (spacemacs/set-leader-keys-for-major-mode mode + "rrV" 'tern-rename-variable + "hd" 'tern-get-docs + "gG" 'tern-find-definition-by-name + (kbd "C-g") 'tern-pop-find-definition + "ht" 'tern-get-type)) + +(defun spacemacs//tern-detect () + "Detect tern binary and warn if not found." + (let ((found (executable-find "tern"))) + (unless found + (spacemacs-buffer/warning "tern binary not found!")) + found)) diff --git a/layers/+lang/javascript/img/coffee.png b/layers/+lang/javascript/img/coffee.png new file mode 100644 index 0000000..e86758f Binary files /dev/null and b/layers/+lang/javascript/img/coffee.png differ diff --git a/layers/+lang/javascript/img/javascript.png b/layers/+lang/javascript/img/javascript.png new file mode 100644 index 0000000..26409d5 Binary files /dev/null and b/layers/+lang/javascript/img/javascript.png differ diff --git a/layers/+lang/javascript/packages.el b/layers/+lang/javascript/packages.el new file mode 100644 index 0000000..ba1d102 --- /dev/null +++ b/layers/+lang/javascript/packages.el @@ -0,0 +1,284 @@ +;;; packages.el --- Javascript Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq javascript-packages + '( + coffee-mode + company + (company-tern :toggle (configuration-layer/package-usedp 'company)) + evil-matchit + flycheck + ggtags + helm-gtags + js-doc + js2-mode + js2-refactor + json-mode + json-snatcher + (tern :toggle (spacemacs//tern-detect)) + web-beautify + skewer-mode + livid-mode + )) + +(defun javascript/init-coffee-mode () + (use-package coffee-mode + :defer t + :init + (progn + (defun javascript/coffee-indent () + (if (coffee-line-wants-indent) + ;; We need to insert an additional tab because the last line was special. + (coffee-insert-spaces (+ (coffee-previous-indent) coffee-tab-width)) + ;; otherwise keep at the same indentation level + (coffee-insert-spaces (coffee-previous-indent))) + ) + ;; indent to right position after `evil-open-below' and `evil-open-above' + (add-hook 'coffee-mode-hook '(lambda () + (setq indent-line-function 'javascript/coffee-indent + evil-shift-width coffee-tab-width)))))) + +(defun javascript/post-init-company () + (spacemacs|add-company-hook js2-mode)) + +(defun javascript/init-company-tern () + (use-package company-tern + :if (and (configuration-layer/package-usedp 'company) + (configuration-layer/package-usedp 'tern)) + :defer t + :init + (push 'company-tern company-backends-js2-mode))) + +(defun javascript/post-init-flycheck () + (dolist (mode '(coffee-mode js2-mode json-mode)) + (spacemacs/add-flycheck-hook mode))) + +(defun javascript/post-init-ggtags () + (add-hook 'js2-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun javascript/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'js2-mode)) + +(defun javascript/init-js-doc () + (use-package js-doc + :defer t + :init + (progn + (defun spacemacs/js-doc-require () + "Lazy load js-doc" + (require 'js-doc)) + (add-hook 'js2-mode-hook 'spacemacs/js-doc-require) + + (defun spacemacs/js-doc-set-key-bindings (mode) + "Setup the key bindings for `js2-doc' for the given MODE." + (spacemacs/declare-prefix-for-mode mode "mrd" "documentation") + (spacemacs/set-leader-keys-for-major-mode mode "rdb" 'js-doc-insert-file-doc) + (spacemacs/set-leader-keys-for-major-mode mode "rdf" 'js-doc-insert-function-doc) + (spacemacs/set-leader-keys-for-major-mode mode "rdt" 'js-doc-insert-tag) + (spacemacs/set-leader-keys-for-major-mode mode "rdh" 'js-doc-describe-tag)) + (spacemacs/js-doc-set-key-bindings 'js2-mode)))) + +(defun javascript/init-js2-mode () + (use-package js2-mode + :defer t + :init + (progn + (add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode)) + ;; Required to make imenu functions work correctly + (add-hook 'js2-mode-hook 'js2-imenu-extras-mode)) + :config + (progn + (spacemacs/declare-prefix-for-mode 'js2-mode "mh" "documentation") + (spacemacs/declare-prefix-for-mode 'js2-mode "mg" "goto") + (spacemacs/declare-prefix-for-mode 'js2-mode "mr" "refactor") + (spacemacs/declare-prefix-for-mode 'js2-mode "mz" "folding") + (spacemacs/set-leader-keys-for-major-mode 'js2-mode + "w" 'js2-mode-toggle-warnings-and-errors + "zc" 'js2-mode-hide-element + "zo" 'js2-mode-show-element + "zr" 'js2-mode-show-all + "ze" 'js2-mode-toggle-element + "zF" 'js2-mode-toggle-hide-functions + "zC" 'js2-mode-toggle-hide-comments)))) + +(defun javascript/post-init-evil-matchit () + (add-hook `js2-mode `turn-on-evil-matchit-mode)) + +(defun javascript/init-js2-refactor () + (use-package js2-refactor + :defer t + :init + (progn + (defun spacemacs/js2-refactor-require () + "Lazy load js2-refactor" + (require 'js2-refactor)) + (add-hook 'js2-mode-hook 'spacemacs/js2-refactor-require) + + (defun spacemacs/js2-refactor-set-key-bindings (mode) + (spacemacs/declare-prefix-for-mode mode "mr3" "ternary") + (spacemacs/set-leader-keys-for-major-mode mode "r3i" 'js2r-ternary-to-if) + + (spacemacs/declare-prefix-for-mode mode "mra" "add/args") + (spacemacs/set-leader-keys-for-major-mode mode "rag" 'js2r-add-to-globals-annotation) + (spacemacs/set-leader-keys-for-major-mode mode "rao" 'js2r-arguments-to-object) + + (spacemacs/declare-prefix-for-mode mode "mrb" "barf") + (spacemacs/set-leader-keys-for-major-mode mode "rba" 'js2r-forward-barf) + + (spacemacs/declare-prefix-for-mode mode "mrc" "contract") + (spacemacs/set-leader-keys-for-major-mode mode "rca" 'js2r-contract-array) + (spacemacs/set-leader-keys-for-major-mode mode "rco" 'js2r-contract-object) + (spacemacs/set-leader-keys-for-major-mode mode "rcu" 'js2r-contract-function) + + (spacemacs/declare-prefix-for-mode mode "mre" "expand/extract") + (spacemacs/set-leader-keys-for-major-mode mode "rea" 'js2r-expand-array) + (spacemacs/set-leader-keys-for-major-mode mode "ref" 'js2r-extract-function) + (spacemacs/set-leader-keys-for-major-mode mode "rem" 'js2r-extract-method) + (spacemacs/set-leader-keys-for-major-mode mode "reo" 'js2r-expand-object) + (spacemacs/set-leader-keys-for-major-mode mode "reu" 'js2r-expand-function) + (spacemacs/set-leader-keys-for-major-mode mode "rev" 'js2r-extract-var) + + (spacemacs/declare-prefix-for-mode mode "mri" "inline/inject/introduct") + (spacemacs/set-leader-keys-for-major-mode mode "rig" 'js2r-inject-global-in-iife) + (spacemacs/set-leader-keys-for-major-mode mode "rip" 'js2r-introduce-parameter) + (spacemacs/set-leader-keys-for-major-mode mode "riv" 'js2r-inline-var) + + (spacemacs/declare-prefix-for-mode mode "mrl" "localize/log") + (spacemacs/set-leader-keys-for-major-mode mode "rlp" 'js2r-localize-parameter) + (spacemacs/set-leader-keys-for-major-mode mode "rlt" 'js2r-log-this) + + (spacemacs/declare-prefix-for-mode mode "mrr" "rename") + (spacemacs/set-leader-keys-for-major-mode mode "rrv" 'js2r-rename-var) + + (spacemacs/declare-prefix-for-mode mode "mrs" "split/slurp") + (spacemacs/set-leader-keys-for-major-mode mode "rsl" 'js2r-forward-slurp) + (spacemacs/set-leader-keys-for-major-mode mode "rss" 'js2r-split-string) + (spacemacs/set-leader-keys-for-major-mode mode "rsv" 'js2r-split-var-declaration) + + (spacemacs/declare-prefix-for-mode mode "mrt" "toggle") + (spacemacs/set-leader-keys-for-major-mode mode "rtf" 'js2r-toggle-function-expression-and-declaration) + + (spacemacs/declare-prefix-for-mode mode "mru" "unwrap") + (spacemacs/set-leader-keys-for-major-mode mode "ruw" 'js2r-unwrap) + + (spacemacs/declare-prefix-for-mode mode "mrv" "var") + (spacemacs/set-leader-keys-for-major-mode mode "rvt" 'js2r-var-to-this) + + (spacemacs/declare-prefix-for-mode mode "mrw" "wrap") + (spacemacs/set-leader-keys-for-major-mode mode "rwi" 'js2r-wrap-buffer-in-iife) + (spacemacs/set-leader-keys-for-major-mode mode "rwl" 'js2r-wrap-in-for-loop) + + (spacemacs/set-leader-keys-for-major-mode mode "k" 'js2r-kill) + + (spacemacs/declare-prefix-for-mode mode "mx" "text") + (spacemacs/declare-prefix-for-mode mode "mxm" "move") + (spacemacs/set-leader-keys-for-major-mode mode "xmj" 'js2r-move-line-down) + (spacemacs/set-leader-keys-for-major-mode mode "xmk" 'js2r-move-line-up)) + + (spacemacs/js2-refactor-set-key-bindings 'js2-mode)))) + +(defun javascript/init-json-mode () + (use-package json-mode + :defer t)) + +(defun javascript/init-json-snatcher () + (use-package json-snatcher + :defer t + :config + (spacemacs/set-leader-keys-for-major-mode 'json-mode + "hp" 'jsons-print-path) + )) + +(defun javascript/init-tern () + (use-package tern + :defer t + :diminish tern-mode + :init (add-hook 'js2-mode-hook 'tern-mode) + :config + (progn + (when javascript-disable-tern-port-files + (add-to-list 'tern-command "--no-port-file" 'append)) + (spacemacs//set-tern-key-bindings 'js2-mode)))) + +(defun javascript/init-web-beautify () + (use-package web-beautify + :defer t + :init + (progn + (spacemacs/set-leader-keys-for-major-mode 'js2-mode "=" 'web-beautify-js) + (spacemacs/set-leader-keys-for-major-mode 'json-mode "=" 'web-beautify-js) + (spacemacs/set-leader-keys-for-major-mode 'web-mode "=" 'web-beautify-html) + (spacemacs/set-leader-keys-for-major-mode 'css-mode "=" 'web-beautify-css)))) + +(defun javascript/init-skewer-mode () + (use-package skewer-mode + :defer t + :diminish skewer-mode + :init + (progn + (spacemacs/register-repl 'skewer-mode 'spacemacs/skewer-start-repl "skewer") + (add-hook 'js2-mode-hook 'skewer-mode)) + :config + (progn + (defun spacemacs/skewer-start-repl () + "Attach a browser to Emacs and start a skewer REPL." + (interactive) + (run-skewer) + (skewer-repl)) + + (defun spacemacs/skewer-load-buffer-and-focus () + "Execute whole buffer in browser and switch to REPL in insert state." + (interactive) + (skewer-load-buffer) + (skewer-repl) + (evil-insert-state)) + + (defun spacemacs/skewer-eval-defun-and-focus () + "Execute function at point in browser and switch to REPL in insert state." + (interactive) + (skewer-eval-defun) + (skewer-repl) + (evil-insert-state)) + + (defun spacemacs/skewer-eval-region (beg end) + "Execute the region as JavaScript code in the attached browser." + (interactive "r") + (skewer-eval (buffer-substring beg end) #'skewer-post-minibuffer)) + + (defun spacemacs/skewer-eval-region-and-focus (beg end) + "Execute the region in browser and swith to REPL in insert state." + (interactive "r") + (spacemacs/skewer-eval-region beg end) + (skewer-repl) + (evil-insert-state)) + + (spacemacs/declare-prefix-for-mode 'js2-mode "ms" "skewer") + (spacemacs/declare-prefix-for-mode 'js2-mode "me" "eval") + (spacemacs/set-leader-keys-for-major-mode 'js2-mode + "'" 'spacemacs/skewer-start-repl + "ee" 'skewer-eval-last-expression + "eE" 'skewer-eval-print-last-expression + "sb" 'skewer-load-buffer + "sB" 'spacemacs/skewer-load-buffer-and-focus + "si" 'spacemacs/skewer-start-repl + "sf" 'skewer-eval-defun + "sF" 'spacemacs/skewer-eval-defun-and-focus + "sr" 'spacemacs/skewer-eval-region + "sR" 'spacemacs/skewer-eval-region-and-focus + "ss" 'skewer-repl)))) + +(defun javascript/init-livid-mode () + (use-package livid-mode + :defer t + :init (spacemacs|add-toggle javascript-repl-live-evaluation + :mode livid-mode + :documentation "Live evaluation of JS buffer change." + :evil-leader-for-mode (js2-mode . "sa")))) diff --git a/layers/+lang/latex/README.org b/layers/+lang/latex/README.org new file mode 100644 index 0000000..5d0d8f3 --- /dev/null +++ b/layers/+lang/latex/README.org @@ -0,0 +1,165 @@ +#+TITLE: LaTeX layer + +[[file:img/latex.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#bibtex][BibTeX]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#auto-completion][Auto-completion]] + - [[#previewing][Previewing]] + - [[#build-command][Build command]] + - [[#auto-fill][Auto-fill]] + - [[#folding][Folding]] + - [[#keybindings][Keybindings]] + - [[#folding][Folding]] + - [[#reftex][RefTeX]] + +* Description +This layer adds support for LaTeX files with [[https://savannah.gnu.org/projects/auctex/][AucTeX]]. + +** Features +- Auto-build with [[https://github.com/tom-tan/auctex-latexmk/][auctex-latexmk]] +- Auto-completion with [[https://github.com/alexeyr/company-auctex][company-auctex]] +- Tags navigation on ~%~ with [[https://github.com/redguardtoo/evil-matchit][evil-matchit]] +- Labels, references, citations and index entries management with [[http://www.gnu.org/software/emacs/manual/html_node/reftex/index.html][RefTeX]] + +** BibTeX +For more extensive support of BibTeX files than RefTeX provides, have a look at +the [[../bibtex][BibTeX layer]]. + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =latex= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Auto-completion +Add the layer =auto-completion= to the variable +=dotspacemacs-configuration-layers= of your dotfile =~/.spacemacs=. + +** Previewing +To perform full-document previews (that is, aside from the inline previewing +under ~SPC m p~), add the following to your =.spacemacs= +under =dotspacemacs/user-config=: + +#+BEGIN_SRC emacs-lisp + (add-hook 'doc-view-mode-hook 'auto-revert-mode) +#+END_SRC + +Then when you open up a compiled PDF, the preview will update automatically +when you recompile. + +** Build command +A build command can be specified via the layer variable =latex-build-command=. + +If =LatexMk= is specified, the appropriate =LatexMk= configuration +will be applied. (the default on systems with =latexmk= in the path) +This variable can be set to any of the entities in =TeX-command-list=, +including any custom entries you may have added there. To use the +regular =AucTeX= command set =latex-build-command= to =LaTeX= as shown +below. + +#+BEGIN_SRC emacs-lisp + dotspacemacs-configuration-layers '( + (latex :variables latex-build-command "LaTeX")) +#+END_SRC + +** Auto-fill +To enable auto-fill set the variable =latex-enable-auto-fill= to =t=. + +The variable =latex-nofill-env= provide the list of environment names where +=auto-fill-mode= will be inhibited. + +#+BEGIN_SRC emacs-lisp + dotspacemacs-configuration-layers '( + (latex :variables latex-enable-auto-fill t)) +#+END_SRC + +** Folding +Enable folding of text by setting =latex-enable-folding= to =t=. Default value +is nil. + +#+BEGIN_SRC emacs-lisp + dotspacemacs-configuration-layers '( + (latex :variables latex-enable-folding t)) +#+END_SRC + +* Keybindings + +| Key Binding | Description | +|---------------+--------------------------------------------| +| ~SPC m -~ | recenter output buffer | +| ~SPC m ​,​~ | TeX command on master file | +| ~SPC m .~ | mark LaTeX environment | +| ~SPC m *~ | mark LaTeX section | +| ~SPC m %~ | comment or uncomment a paragraph | +| ~SPC m ;~ | comment or uncomment a region | +| ~SPC m a~ | run all commands (compile and open viewer) | +| ~SPC m b~ | build | +| ~SPC m c~ | close LaTeX environment | +| ~SPC m e~ | insert LaTeX environment | +| ~SPC m i i~ | insert =\item= | +| ~SPC m k~ | kill TeX job | +| ~SPC m l~ | recenter output buffer | +| ~SPC m m~ | insert LaTeX macro | +| ~SPC m s~ | insert LaTeX section | +| ~SPC m v~ | view output | +| ~SPC m h d~ | TeX documentation, can be very slow | +| ~SPC m f e~ | fill LaTeX environment | +| ~SPC m f p~ | fill LaTeX paragraph | +| ~SPC m f r~ | fill LaTeX region | +| ~SPC m f s~ | fill LaTeX section | +| ~SPC m p r~ | preview region | +| ~SPC m p b~ | preview buffer | +| ~SPC m p d~ | preview document | +| ~SPC m p e~ | preview environment | +| ~SPC m p s~ | preview section | +| ~SPC m p p~ | preview at point | +| ~SPC m p f~ | cache preamble for preview | +| ~SPC m p c~ | clear previews | +| ~SPC m v~ | view | +| ~SPC m x b~ | make font bold | +| ~SPC m x B~ | make font medium weight | +| ~SPC m x c~ | make font monospaced (for code) | +| ~SPC m x e~ | make font emphasised | +| ~SPC m x i~ | make font italic | +| ~SPC m x o~ | make font oblique | +| ~SPC m x r~ | remove font properties | +| ~SPC m x f a~ | use calligraphic font | +| ~SPC m x f c~ | use small-caps font | +| ~SPC m x f f~ | use sans serif font | +| ~SPC m x f n~ | use normal font | +| ~SPC m x f r~ | use serif font | +| ~SPC m x f u~ | use upright font | + +** Folding +Available only when =latex-enable-folding= is non nil. + +| Key Binding | Description | +|-------------+----------------------| +| ~SPC m z =~ | fold TeX math | +| ~SPC m z b~ | fold TeX buffer | +| ~SPC m z e~ | fold TeX environment | +| ~SPC m z m~ | fold TeX macro | +| ~SPC m z r~ | fold TeX region | + +** RefTeX + +| Key Binding | Description | +|---------------+---------------------------------------| +| ~SPC m r c~ | reftex-citation | +| ~SPC m r g~ | reftex-grep-document | +| ~SPC m r i~ | reftex-index-selection-or-word | +| ~SPC m r I~ | reftex-display-index | +| ~SPC m r TAB~ | reftex-index | +| ~SPC m r l~ | reftex-label | +| ~SPC m r p~ | reftex-index-phrase-selection-or-word | +| ~SPC m r P~ | reftex-index-visit-phrases-buffer | +| ~SPC m r r~ | reftex-reference | +| ~SPC m r s~ | reftex-search-document | +| ~SPC m r t~ | reftex-toc | +| ~SPC m r T~ | reftex-toc-recenter | +| ~SPC m r v~ | reftex-view-crossref | diff --git a/layers/+lang/latex/config.el b/layers/+lang/latex/config.el new file mode 100644 index 0000000..68f1ac4 --- /dev/null +++ b/layers/+lang/latex/config.el @@ -0,0 +1,33 @@ +;;; packages.el --- Latex Layer Configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; variables + +(spacemacs|defvar-company-backends LaTeX-mode) + +(spacemacs|define-jump-handlers latex-mode) + +(defvar latex-build-command (if (executable-find "latexmk") "LatexMk" "LaTeX") + "The default command to use with `SPC m b'") + +(defvar latex-enable-auto-fill t + "Whether to use auto-fill-mode or not in tex files.") + +(defvar latex-enable-folding nil + "Whether to use `TeX-fold-mode' or not in tex/latex buffers.") + +(defvar latex-nofill-env '("equation" + "equation*" + "align" + "align*" + "tabular" + "tikzpicture") + "List of environment names in which `auto-fill-mode' will be inhibited.") diff --git a/layers/+lang/latex/funcs.el b/layers/+lang/latex/funcs.el new file mode 100644 index 0000000..84649de --- /dev/null +++ b/layers/+lang/latex/funcs.el @@ -0,0 +1,61 @@ +;;; funcs.el --- Auctex Layer Functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun latex/build () + (interactive) + (progn + (let ((TeX-save-query nil)) + (TeX-save-document (TeX-master-file))) + (TeX-command latex-build-command 'TeX-master-file -1))) + ;; (setq build-proc (TeX-command latex-build-command 'TeX-master-file -1)) + ;; ;; Sometimes, TeX-command returns nil causing an error in set-process-sentinel + ;; (when build-proc + ;; (set-process-sentinel build-proc 'latex//build-sentinel)))) + +(defun latex//build-sentinel (process event) + (if (string= event "finished\n") + (TeX-view) + (message "Errors! Check with C-`"))) + +(defun latex//autofill () + "Check whether the pointer is currently inside one of the +environments described in `latex-nofill-env' and if so, inhibits +the automatic filling of the current paragraph." + (let ((do-auto-fill t) + (current-environment "") + (level 0)) + (while (and do-auto-fill (not (string= current-environment "document"))) + (setq level (1+ level) + current-environment (LaTeX-current-environment level) + do-auto-fill (not (member current-environment latex-nofill-env)))) + (when do-auto-fill + (do-auto-fill)))) + +(defun latex/auto-fill-mode () + "Toggle auto-fill-mode using the custom auto-fill function." + (interactive) + (auto-fill-mode) + (setq auto-fill-function 'latex//autofill)) + +;; Rebindings for TeX-font +(defun latex/font-bold () (interactive) (TeX-font nil ?\C-b)) +(defun latex/font-medium () (interactive) (TeX-font nil ?\C-m)) +(defun latex/font-code () (interactive) (TeX-font nil ?\C-t)) +(defun latex/font-emphasis () (interactive) (TeX-font nil ?\C-e)) +(defun latex/font-italic () (interactive) (TeX-font nil ?\C-i)) +(defun latex/font-clear () (interactive) (TeX-font nil ?\C-d)) +(defun latex/font-calligraphic () (interactive) (TeX-font nil ?\C-a)) +(defun latex/font-small-caps () (interactive) (TeX-font nil ?\C-c)) +(defun latex/font-sans-serif () (interactive) (TeX-font nil ?\C-f)) +(defun latex/font-normal () (interactive) (TeX-font nil ?\C-n)) +(defun latex/font-serif () (interactive) (TeX-font nil ?\C-r)) +(defun latex/font-oblique () (interactive) (TeX-font nil ?\C-s)) +(defun latex/font-upright () (interactive) (TeX-font nil ?\C-u)) diff --git a/layers/+lang/latex/img/latex.png b/layers/+lang/latex/img/latex.png new file mode 100644 index 0000000..af5d0f9 Binary files /dev/null and b/layers/+lang/latex/img/latex.png differ diff --git a/layers/+lang/latex/packages.el b/layers/+lang/latex/packages.el new file mode 100644 index 0000000..ab970d5 --- /dev/null +++ b/layers/+lang/latex/packages.el @@ -0,0 +1,196 @@ +;;; packages.el --- Latex Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq latex-packages + '( + auctex + (auctex-latexmk :toggle (string= "LatexMk" latex-build-command)) + company + (company-auctex :toggle (configuration-layer/package-usedp 'company)) + evil-matchit + (reftex :location built-in) + flycheck + flyspell + ggtags + helm-gtags + smartparens + typo + yasnippet + which-key + )) + +(defun latex/init-auctex () + (use-package tex + :defer t + :init + (progn + (setq TeX-command-default latex-build-command + TeX-auto-save t + TeX-parse-self t + TeX-syntactic-comment t + ;; Synctex support + TeX-source-correlate-start-server nil + ;; Don't insert line-break at inline math + LaTeX-fill-break-at-separators nil) + (when latex-enable-auto-fill + (add-hook 'LaTeX-mode-hook 'latex/auto-fill-mode)) + (when latex-enable-folding + (add-hook 'LaTeX-mode-hook 'TeX-fold-mode)) + (add-hook 'LaTeX-mode-hook 'LaTeX-math-mode) + (add-hook 'LaTeX-mode-hook 'TeX-source-correlate-mode) + (add-hook 'LaTeX-mode-hook 'TeX-PDF-mode)) + :config + (progn + ;; Key bindings for plain TeX + (dolist (mode '(tex-mode latex-mode)) + (spacemacs/set-leader-keys-for-major-mode mode + "\\" 'TeX-insert-macro ;; C-c C-m + "-" 'TeX-recenter-output-buffer ;; C-c C-l + "%" 'TeX-comment-or-uncomment-paragraph ;; C-c % + ";" 'TeX-comment-or-uncomment-region ;; C-c ; or C-c : + ;; TeX-command-run-all runs compile and open the viewer + "a" 'TeX-command-run-all ;; C-c C-a + "b" 'latex/build + "k" 'TeX-kill-job ;; C-c C-k + "l" 'TeX-recenter-output-buffer ;; C-c C-l + "m" 'TeX-insert-macro ;; C-c C-m + "v" 'TeX-view ;; C-c C-v + ;; TeX-doc is a very slow function + "hd" 'TeX-doc + "xb" 'latex/font-bold + "xc" 'latex/font-code + "xe" 'latex/font-emphasis + "xi" 'latex/font-italic + "xr" 'latex/font-clear + "xo" 'latex/font-oblique + "xfc" 'latex/font-small-caps + "xff" 'latex/font-sans-serif + "xfr" 'latex/font-serif) + (when dotspacemacs-major-mode-emacs-leader-key + (spacemacs/set-leader-keys-for-major-mode mode + dotspacemacs-major-mode-emacs-leader-key 'TeX-command-master)) + (when dotspacemacs-major-mode-leader-key + (spacemacs/set-leader-keys-for-major-mode mode + dotspacemacs-major-mode-leader-key 'TeX-command-master)) + (when latex-enable-folding + (spacemacs/set-leader-keys-for-major-mode mode + "z=" 'TeX-fold-math + "zb" 'TeX-fold-buffer + "ze" 'TeX-fold-env + "zm" 'TeX-fold-macro + "zr" 'TeX-fold-region)) + (spacemacs/declare-prefix-for-mode mode "mh" "help") + (spacemacs/declare-prefix-for-mode mode "mx" "text/fonts") + (spacemacs/declare-prefix-for-mode mode "mz" "fold")) + + ;; Key bindings specific to LaTeX + (spacemacs/set-leader-keys-for-major-mode 'latex-mode + "*" 'LaTeX-mark-section ;; C-c * + "." 'LaTeX-mark-environment ;; C-c . + "c" 'LaTeX-close-environment ;; C-c ] + "e" 'LaTeX-environment ;; C-c C-e + "ii" 'LaTeX-insert-item ;; C-c C-j + "s" 'LaTeX-section ;; C-c C-s + "fe" 'LaTeX-fill-environment ;; C-c C-q C-e + "fp" 'LaTeX-fill-paragraph ;; C-c C-q C-p + "fr" 'LaTeX-fill-region ;; C-c C-q C-r + "fs" 'LaTeX-fill-section ;; C-c C-q C-s + "pb" 'preview-buffer + "pc" 'preview-clearout + "pd" 'preview-document + "pe" 'preview-environment + "pf" 'preview-cache-preamble + "pp" 'preview-at-point + "pr" 'preview-region + "ps" 'preview-section + "xB" 'latex/font-medium + "xr" 'latex/font-clear + "xfa" 'latex/font-calligraphic + "xfn" 'latex/font-normal + "xfu" 'latex/font-upright) + (spacemacs/declare-prefix-for-mode 'latex-mode "mi" "insert") + (spacemacs/declare-prefix-for-mode 'latex-mode "mp" "preview") + (spacemacs/declare-prefix-for-mode 'latex-mode "mf" "fill")))) + +(defun latex/init-auctex-latexmk () + (use-package auctex-latexmk + :defer t + :init + (progn + (setq auctex-latexmk-inherit-TeX-PDF-mode t) + (spacemacs|use-package-add-hook tex + :post-config + (auctex-latexmk-setup))))) + +(defun latex/post-init-company () + (spacemacs|add-company-hook LaTeX-mode)) + +(defun latex/init-company-auctex () + (use-package company-auctex + :defer t + :init + (progn + (push 'company-auctex-labels company-backends-LaTeX-mode) + (push 'company-auctex-bibs company-backends-LaTeX-mode) + (push '(company-auctex-macros + company-auctex-symbols + company-auctex-environments) company-backends-LaTeX-mode)))) + +(defun latex/post-init-evil-matchit () + (add-hook 'LaTeX-mode-hook 'evil-matchit-mode)) + +(defun latex/post-init-flycheck () + (spacemacs/add-flycheck-hook 'LaTeX-mode)) + +(defun latex/post-init-flyspell () + (spell-checking/add-flyspell-hook 'LaTeX-mode-hook)) + +(defun latex/init-reftex () + (add-hook 'LaTeX-mode-hook 'turn-on-reftex) + (setq reftex-plug-into-AUCTeX '(nil nil t t t) + reftex-use-fonts t) + (spacemacs/declare-prefix-for-mode 'latex-mode "mr" "reftex") + (spacemacs/set-leader-keys-for-major-mode 'latex-mode + "rc" 'reftex-citation + "rg" 'reftex-grep-document + "ri" 'reftex-index-selection-or-word + "rI" 'reftex-display-index + "r TAB" 'reftex-index + "rl" 'reftex-label + "rp" 'reftex-index-phrase-selection-or-word + "rP" 'reftex-index-visit-phrases-buffer + "rr" 'reftex-reference + "rs" 'reftex-search-document + "rt" 'reftex-toc + "rT" 'reftex-toc-recenter + "rv" 'reftex-view-crossref)) + +(defun latex/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'latex-mode)) + +(defun latex/post-init-ggtags () + (add-hook 'latex-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun latex/post-init-smartparens () + (add-hook 'LaTeX-mode-hook 'smartparens-mode)) + +(defun latex/post-init-typo () + ;; Typo mode isn't useful for LaTeX. + (defun spacemacs//disable-typo-mode () + (typo-mode -1)) + (add-hook 'LaTeX-mode-hook 'spacemacs//disable-typo-mode)) + +(defun latex/post-init-yasnippet () + (add-hook 'LaTeX-mode-hook 'spacemacs/load-yasnippet)) + +(defun latex/post-init-which-key () + (push '("\\`latex/font-\\(.+\\)\\'" . "\\1") + which-key-description-replacement-alist)) diff --git a/layers/+lang/lua/README.org b/layers/+lang/lua/README.org new file mode 100644 index 0000000..ec9023c --- /dev/null +++ b/layers/+lang/lua/README.org @@ -0,0 +1,36 @@ +#+TITLE: Lua contribution layer for Spacemacs + +[[file:img/lua.gif]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features:]] + - [[#install][Install]] + - [[#key-bindings][Key Bindings]] + - [[#commands][Commands]] + +* Description +This layer adds support for editing Lua. + +** Features: +- Editing lua files using [[https://github.com/immerrr/lua-mode][lua-mode]] +- Sending code to a lua REPL +- Code linting using [[https://github.com/mpeterv/luacheck][Luacheck]] + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =lua= to the existing =dotspacemacs-configuration-layers= list in this +file. + +In order to enable code linting, install [[https://github.com/mpeterv/luacheck][Luacheck]]. + +* Key Bindings +** Commands + +| Key Binding | Description | +|-------------+--------------------------------------------| +| ~SPC m d~ | lookup thing at point in lua documentation | +| ~SPC m s b~ | send buffer contents to REPL | +| ~SPC m s f~ | send current function to REPL | +| ~SPC m s l~ | send current line to REPL | +| ~SPC m s r~ | send current region to REPL | diff --git a/layers/+lang/lua/config.el b/layers/+lang/lua/config.el new file mode 100644 index 0000000..c13d28d --- /dev/null +++ b/layers/+lang/lua/config.el @@ -0,0 +1,14 @@ +;;; packages.el --- Lua Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; variables + +(spacemacs|define-jump-handlers lua-mode) diff --git a/layers/+lang/lua/img/lua.gif b/layers/+lang/lua/img/lua.gif new file mode 100644 index 0000000..73f09bf Binary files /dev/null and b/layers/+lang/lua/img/lua.gif differ diff --git a/layers/+lang/lua/packages.el b/layers/+lang/lua/packages.el new file mode 100644 index 0000000..f48b106 --- /dev/null +++ b/layers/+lang/lua/packages.el @@ -0,0 +1,36 @@ +(setq lua-packages + '( + company + flycheck + ggtags + helm-gtags + lua-mode + )) + +(defun lua/post-init-flycheck () + (spacemacs/add-flycheck-hook 'lua-mode)) + +(defun lua/init-lua-mode () + (use-package lua-mode + :defer t + :mode ("\\.lua\\'" . lua-mode) + :interpreter ("lua" . lua-mode) + :init + (progn + (setq lua-indent-level 2 + lua-indent-string-contents t) + (spacemacs/set-leader-keys-for-major-mode 'lua-mode + "d" 'lua-search-documentation + "sb" 'lua-send-buffer + "sf" 'lua-send-defun + "sl" 'lua-send-current-line + "sr" 'lua-send-region)))) + +(defun lua/post-init-company () + (add-hook 'lua-mode-hook 'company-mode)) + +(defun lua/post-init-ggtags () + (add-hook 'lua-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun lua/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'lua-mode)) diff --git a/layers/+lang/markdown/README.org b/layers/+lang/markdown/README.org new file mode 100644 index 0000000..e955ae9 --- /dev/null +++ b/layers/+lang/markdown/README.org @@ -0,0 +1,174 @@ +#+TITLE: Markdown layer + +[[file:img/markdown.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#bibtex][BibTeX]] + - [[#install][Install]] + - [[#configuration][Configuration]] + - [[#live-preview][Live preview]] + - [[#usage][Usage]] + - [[#generate-a-toc][Generate a TOC]] + - [[#key-bindings][Key bindings]] + - [[#element-insertion][Element insertion]] + - [[#element-removal][Element removal]] + - [[#completion][Completion]] + - [[#following-and-jumping][Following and Jumping]] + - [[#indentation][Indentation]] + - [[#header-navigation][Header navigation]] + - [[#buffer-wide-commands][Buffer-wide commands]] + - [[#list-editing][List editing]] + - [[#movement][Movement]] + - [[#promotion-demotion][Promotion, Demotion]] + +* Description +This layer adds markdown support to Spacemacs. + +** Features +- markdown files support via [[http://jblevins.org/git/markdown-mode.git/][markdown-mode]] +- Fast Github-flavored live preview via [[https://github.com/blak3mill3r/vmd-mode][vmd-mode]] +- TOC generation via [[https://github.com/ardumont/markdown-toc][markdown-toc]] +- Completion of Emojis using [[https://github.com/dunn/company-emoji][company-emoji]] (still needs a way of showing, either + using the =emoji= layer or having a proper font) :clap: + +** BibTeX +For more extensive support of references with BibTeX files, have a look at the +[[../bibtex][BibTeX layer]]. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =markdown= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Configuration +** Live preview +By default the built-in Emacs web browser is used to live preview a markdown +buffer. + +To use =vmd= (Github-flavored live preview) instead set the value of the +variable =markdown-live-preview-engine= to =vmd=: + +#+BEGIN_SRC emacs-lisp + dotspacemacs-configuration-layers '( + (markdown :variables markdown-live-preview-engine 'vmd)) +#+END_SRC + +And install the executable with: + +#+BEGIN_SRC shell +npm install -g vmd +#+END_SRC + +* Usage +** Generate a TOC +To generate a table of contents type on top of the buffer: +~SPC SPC markdown-toc-generate-toc RET~ + +* Key bindings +** Element insertion + +| Key Binding | Description | +|-------------+-------------------------------------------------------------------| +| ~SPC m -~ | insert horizontal line | +| ~SPC m h i~ | insert header dwim | +| ~SPC m h I~ | insert header setext dwim | +| ~SPC m h 1~ | insert header atx 1 | +| ~SPC m h 2~ | insert header atx 2 | +| ~SPC m h 3~ | insert header atx 3 | +| ~SPC m h 4~ | insert header atx 4 | +| ~SPC m h 5~ | insert header atx 5 | +| ~SPC m h 6~ | insert header atx 6 | +| ~SPC m h !~ | insert header setext 1 | +| ~SPC m h @~ | insert header setext 2 | +| ~SPC m i l~ | insert link | +| ~SPC m i L~ | insert reference link dwim | +| ~SPC m i u~ | insert uri | +| ~SPC m i f~ | insert footnote | +| ~SPC m i w~ | insert wiki link | +| ~SPC m i i~ | insert image | +| ~SPC m i I~ | insert reference image | +| ~SPC m x b~ | make region bold or insert bold | +| ~SPC m x i~ | make region italic or insert italic | +| ~SPC m x c~ | make region code or insert code | +| ~SPC m x C~ | make region code or insert code (Github Flavored Markdown format) | +| ~SPC m x q~ | make region blockquote or insert blockquote | +| ~SPC m x Q~ | blockquote region | +| ~SPC m x p~ | make region or insert pre | +| ~SPC m x P~ | pre region | + +** Element removal + +| Key Binding | Description | +|-------------+---------------------| +| ~SPC m k~ | kill thing at point | + +** Completion + +| Key Binding | Description | +|-------------+-------------| +| ~SPC m ]~ | complete | + +** Following and Jumping + +| Key Binding | Description | +|-------------+-----------------------| +| ~SPC m o~ | follow thing at point | +| ~SPC m j~ | jump | + +** Indentation + +| Key Binding | Description | +|-------------+---------------| +| ~SPC m \>~ | indent region | +| ~SPC m \<~ | exdent region | + +** Header navigation + +| Key Binding | Description | +|-------------+------------------------------| +| ~gj~ | outline forward same level | +| ~gk~ | outline backward same level | +| ~gh~ | outline up one level | +| ~gl~ | outline next visible heading | + +** Buffer-wide commands + +| Key Binding | Description | +|-------------+--------------------------------------------------------------------------------------| +| ~SPC m c ]~ | complete buffer | +| ~SPC m c m~ | other window | +| ~SPC m c p~ | preview | +| ~SPC m c P~ | live preview using engine defined with layer variable =markdown-live-preview-engine= | +| ~SPC m c e~ | export | +| ~SPC m c v~ | export and preview | +| ~SPC m c o~ | open | +| ~SPC m c w~ | kill ring save | +| ~SPC m c c~ | check refs | +| ~SPC m c n~ | cleanup list numbers | +| ~SPC m c r~ | render buffer | + +** List editing + +| Key Binding | Description | +|-------------+------------------| +| ~SPC m l i~ | insert list item | + +** Movement + +| Key Binding | Description | +|-------------+--------------------| +| ~SPC m {~ | backward paragraph | +| ~SPC m }~ | forward paragraph | +| ~SPC m N~ | next link | +| ~SPC m P~ | previous link | + +** Promotion, Demotion + +| Key Binding | Description | +|-------------+--------------------| +| ~M-k~ | markdown-move-up | +| ~M-j~ | markdown-move-down | +| ~M-h~ | markdown-promote | +| ~M-l~ | markdown-demote | diff --git a/layers/+lang/markdown/config.el b/layers/+lang/markdown/config.el new file mode 100644 index 0000000..3326b8e --- /dev/null +++ b/layers/+lang/markdown/config.el @@ -0,0 +1,17 @@ +;;; config.el --- Markdown Layer Configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; variables + +(spacemacs|defvar-company-backends markdown-mode) + +(defvar markdown-live-preview-engine 'eww + "Possibe values are `eww' (built-in browser) or `vmd' (installed with `npm').") diff --git a/layers/+lang/markdown/img/markdown.png b/layers/+lang/markdown/img/markdown.png new file mode 100644 index 0000000..22b4439 Binary files /dev/null and b/layers/+lang/markdown/img/markdown.png differ diff --git a/layers/+lang/markdown/packages.el b/layers/+lang/markdown/packages.el new file mode 100644 index 0000000..4048317 --- /dev/null +++ b/layers/+lang/markdown/packages.el @@ -0,0 +1,236 @@ +;;; packages.el --- Markdown Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq markdown-packages + '( + company + company-emoji + emoji-cheat-sheet-plus + gh-md + markdown-mode + markdown-toc + mmm-mode + smartparens + (vmd-mode :toggle (eq 'vmd markdown-live-preview-engine)) + )) + +(defun markdown/post-init-company () + (spacemacs|add-company-hook markdown-mode) + (push 'company-capf company-backends-markdown-mode)) + +(defun markdown/post-init-company-emoji () + (push 'company-emoji company-backends-markdown-mode)) + +(defun markdown/post-init-emoji-cheat-sheet-plus () + (add-hook 'markdown-mode-hook 'emoji-cheat-sheet-plus-display-mode)) + +(defun markdown/init-gh-md () + (use-package gh-md + :defer t + :init + (spacemacs/set-leader-keys-for-major-mode 'markdown-mode + "cr" 'gh-md-render-buffer))) + +(defun markdown/post-init-smartparens () + (add-hook 'markdown-mode-hook 'smartparens-mode)) + +(defun markdown/init-markdown-mode () + (use-package markdown-mode + :mode ("\\.m[k]d" . markdown-mode) + :defer t + :config + (progn + ;; stolen from http://stackoverflow.com/a/26297700 + ;; makes markdown tables saner via orgtbl-mode + (require 'org-table) + (defun cleanup-org-tables () + (save-excursion + (goto-char (point-min)) + (while (search-forward "-+-" nil t) (replace-match "-|-")))) + (add-hook 'markdown-mode-hook 'orgtbl-mode) + (add-hook 'markdown-mode-hook + (lambda() + (add-hook 'after-save-hook 'cleanup-org-tables nil 'make-it-local))) + ;; Insert key for org-mode and markdown a la C-h k + ;; from SE endless http://emacs.stackexchange.com/questions/2206/i-want-to-have-the-kbd-tags-for-my-blog-written-in-org-mode/2208#2208 + (defun spacemacs/insert-keybinding-markdown (key) + "Ask for a key then insert its description. +Will work on both org-mode and any mode that accepts plain html." + (interactive "kType key sequence: ") + (let* ((tag "~%s~")) + (if (null (equal key "\r")) + (insert + (format tag (help-key-description key nil))) + (insert (format tag "")) + (forward-char -6)))) + + ;; Declare prefixes and bind keys + (dolist (prefix '(("mc" . "markdown/command") + ("mh" . "markdown/header") + ("mi" . "markdown/insert") + ("ml" . "markdown/lists") + ("mx" . "markdown/text"))) + (spacemacs/declare-prefix-for-mode + 'markdown-mode (car prefix) (cdr prefix))) + (spacemacs/set-leader-keys-for-major-mode 'markdown-mode + ;; Movement + "{" 'markdown-backward-paragraph + "}" 'markdown-forward-paragraph + ;; Completion, and Cycling + "]" 'markdown-complete + ;; Indentation + ">" 'markdown-indent-region + "<" 'markdown-exdent-region + ;; Buffer-wide commands + "c]" 'markdown-complete-buffer + "cc" 'markdown-check-refs + "ce" 'markdown-export + "cm" 'markdown-other-window + "cn" 'markdown-cleanup-list-numbers + "co" 'markdown-open + "cp" 'markdown-preview + "cv" 'markdown-export-and-preview + "cw" 'markdown-kill-ring-save + ;; headings + "hi" 'markdown-insert-header-dwim + "hI" 'markdown-insert-header-setext-dwim + "h1" 'markdown-insert-header-atx-1 + "h2" 'markdown-insert-header-atx-2 + "h3" 'markdown-insert-header-atx-3 + "h4" 'markdown-insert-header-atx-4 + "h5" 'markdown-insert-header-atx-5 + "h6" 'markdown-insert-header-atx-6 + "h!" 'markdown-insert-header-setext-1 + "h@" 'markdown-insert-header-setext-2 + ;; Insertion of common elements + "-" 'markdown-insert-hr + "if" 'markdown-insert-footnote + "ii" 'markdown-insert-image + "ik" 'spacemacs/insert-keybinding-markdown + "iI" 'markdown-insert-reference-image + "il" 'markdown-insert-link + "iL" 'markdown-insert-reference-link-dwim + "iw" 'markdown-insert-wiki-link + "iu" 'markdown-insert-uri + ;; Element removal + "k" 'markdown-kill-thing-at-point + ;; List editing + "li" 'markdown-insert-list-item + ;; region manipulation + "xb" 'markdown-insert-bold + "xi" 'markdown-insert-italic + "xc" 'markdown-insert-code + "xC" 'markdown-insert-gfm-code-block + "xq" 'markdown-insert-blockquote + "xQ" 'markdown-blockquote-region + "xp" 'markdown-insert-pre + "xP" 'markdown-pre-region + ;; Following and Jumping + "N" 'markdown-next-link + "f" 'markdown-follow-thing-at-point + "P" 'markdown-previous-link + "" 'markdown-jump) + (when (eq 'eww markdown-live-preview-engine) + (spacemacs/set-leader-keys-for-major-mode 'markdown-mode + "cP" 'markdown-live-preview-mode)) + ;; Header navigation in normal state movements + (evil-define-key 'normal markdown-mode-map + "gj" 'outline-forward-same-level + "gk" 'outline-backward-same-level + "gh" 'outline-up-heading + ;; next visible heading is not exactly what we want but close enough + "gl" 'outline-next-visible-heading) + ;; Promotion, Demotion + (define-key markdown-mode-map (kbd "M-h") 'markdown-promote) + (define-key markdown-mode-map (kbd "M-j") 'markdown-move-down) + (define-key markdown-mode-map (kbd "M-k") 'markdown-move-up) + (define-key markdown-mode-map (kbd "M-l") 'markdown-demote)))) + +(defun markdown/init-markdown-toc () + (use-package markdown-toc + :defer t)) + +(defun markdown/init-mmm-mode () + (use-package mmm-mode + :commands mmm-parse-buffer + :init + (spacemacs/set-leader-keys-for-major-mode 'markdown-mode + ;; Highlight code blocks + "cs" 'mmm-parse-buffer) + :config + (progn + (mmm-add-classes '((markdown-python + :submode python-mode + :face mmm-declaration-submode-face + :front "^```python[\n\r]+" + :back "^```$"))) + (mmm-add-classes '((markdown-html + :submode web-mode + :face mmm-declaration-submode-face + :front "^```html[\n\r]+" + :back "^```$"))) + (mmm-add-classes '((markdown-java + :submode java-mode + :face mmm-declaration-submode-face + :front "^```java[\n\r]+" + :back "^```$"))) + (mmm-add-classes '((markdown-ruby + :submode ruby-mode + :face mmm-declaration-submode-face + :front "^```ruby[\n\r]+" + :back "^```$"))) + (mmm-add-classes '((markdown-c + :submode c-mode + :face mmm-declaration-submode-face + :front "^```c[\n\r]+" + :back "^```$"))) + (mmm-add-classes '((markdown-c++ + :submode c++-mode + :face mmm-declaration-submode-face + :front "^```c\+\+[\n\r]+" + :back "^```$"))) + (mmm-add-classes '((markdown-elisp + :submode emacs-lisp-mode + :face mmm-declaration-submode-face + :front "^```elisp[\n\r]+" + :back "^```$"))) + (mmm-add-classes '((markdown-javascript + :submode javascript-mode + :face mmm-declaration-submode-face + :front "^```javascript[\n\r]+" + :back "^```$"))) + (mmm-add-classes '((markdown-ess + :submode R-mode + :face mmm-declaration-submode-face + :front "^```{?r.*}?[\n\r]+" + :back "^```$"))) + (mmm-add-classes '((markdown-rust + :submode rust-mode + :face mmm-declaration-submode-face + :front "^```rust[\n\r]+" + :back "^```$"))) + (setq mmm-global-mode t) + (mmm-add-mode-ext-class 'markdown-mode nil 'markdown-python) + (mmm-add-mode-ext-class 'markdown-mode nil 'markdown-java) + (mmm-add-mode-ext-class 'markdown-mode nil 'markdown-ruby) + (mmm-add-mode-ext-class 'markdown-mode nil 'markdown-c) + (mmm-add-mode-ext-class 'markdown-mode nil 'markdown-c++) + (mmm-add-mode-ext-class 'markdown-mode nil 'markdown-elisp) + (mmm-add-mode-ext-class 'markdown-mode nil 'markdown-html) + (mmm-add-mode-ext-class 'markdown-mode nil 'markdown-javascript) + (mmm-add-mode-ext-class 'markdown-mode nil 'markdown-ess) + (mmm-add-mode-ext-class 'markdown-mode nil 'markdown-rust)))) + +(defun markdown/init-vmd-mode () + (use-package vmd-mode + :defer t + :init (spacemacs/set-leader-keys-for-major-mode 'markdown-mode + "cP" 'vmd-mode))) diff --git a/layers/+lang/nim/README.org b/layers/+lang/nim/README.org new file mode 100644 index 0000000..e96ba8e --- /dev/null +++ b/layers/+lang/nim/README.org @@ -0,0 +1,37 @@ +#+TITLE: Nim layer + +[[file:img/logo.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#working-with-nim][Working with Nim]] + - [[#nim-commands-start-with-m][Nim commands (start with =m=):]] + +* Description +This layer provides the following features for Nim: + +- Code completion. +- Jump to definition. +- Syntax checking. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =nim= to the existing =dotspacemacs-configuration-layers= list in this +file. + +For syntax checking, the =syntax-checking= layer must also be added. + +For all the features to work properly, =nimsuggest= must be installed properly +and =nimsuggest= binary must be in $PATH. + +* Working with Nim + +** Nim commands (start with =m=): + +| Key Binding | Description | +|----------------------+----------------------------| +| ~SPC m c r~ | nim compile --run main.nim | +| ~SPC m g g~ or ~M-.~ | Jump to definition | +| ~SPC m g b~ or ~M-,~ | Jump back | +|----------------------+----------------------------| diff --git a/layers/+lang/nim/config.el b/layers/+lang/nim/config.el new file mode 100644 index 0000000..ac78366 --- /dev/null +++ b/layers/+lang/nim/config.el @@ -0,0 +1,17 @@ +;;; packages.el --- Nim Configuration Layer for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Max Gonzih +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(spacemacs|defvar-company-backends nim-mode) +(spacemacs|defvar-company-backends nimscript-mode) + +(spacemacs|define-jump-handlers nim-mode) diff --git a/layers/+lang/nim/img/logo.png b/layers/+lang/nim/img/logo.png new file mode 100644 index 0000000..9cd41df Binary files /dev/null and b/layers/+lang/nim/img/logo.png differ diff --git a/layers/+lang/nim/packages.el b/layers/+lang/nim/packages.el new file mode 100644 index 0000000..04450d4 --- /dev/null +++ b/layers/+lang/nim/packages.el @@ -0,0 +1,35 @@ +(setq nim-packages + '(company + flycheck + flycheck-nim + nim-mode)) + +(defun nim/post-init-company () + (spacemacs|add-company-hook nim-mode) + (spacemacs|add-company-hook nimscript-mode)) + +(defun nim/post-init-flycheck () + (spacemacs/add-flycheck-hook 'nim-mode)) + +(defun nim/init-flycheck-nim () + (use-package flycheck-nim + :if (configuration-layer/package-usedp 'flycheck))) + +(defun nim/init-nim-mode () + (use-package nim-mode + :defer t + :init + (progn + (when (configuration-layer/package-usedp 'company) + (push 'company-capf company-backends-nim-mode)) + (add-hook 'nim-mode-hook 'nimsuggest-mode) + (push 'nimsuggest-find-definition spacemacs-jump-handlers-nim-mode)) + :config + (progn + (defun spacemacs/nim-compile-run () + (interactive) + (shell-command "nim compile --run main.nim")) + + (spacemacs/set-leader-keys-for-major-mode 'nim-mode + "cr" 'spacemacs/nim-compile-run + "gb" 'pop-tag-mark)))) diff --git a/layers/+lang/ocaml/README.org b/layers/+lang/ocaml/README.org new file mode 100644 index 0000000..7e2c0c5 --- /dev/null +++ b/layers/+lang/ocaml/README.org @@ -0,0 +1,95 @@ +#+TITLE: Ocaml layer + +[[file:img/ocaml.png]] + +* Table of Content :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features:]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#opam-packages][OPAM packages]] + - [[#key-bindings][Key Bindings]] + - [[#repl-utop][REPL (utop)]] + - [[#todos][TODOS]] + - [[#add-more-proper-spacemacs-key-bindings-for-basic-merlin-tasks][Add more proper spacemacs key-bindings for basic merlin tasks]] + - [[#add-proper-keybindings-for-ocamldebug][Add proper keybindings for ocamldebug]] + - [[#add-more-keybindings-for-tuareg-mode][Add more keybindings for tuareg-mode]] + +* Description +This is a very basic layer for editing ocaml files. + +** Features: +- Syntax highlighting (major-mode) via [[https://github.com/ocaml/tuareg][tuareg-mode]] +- Error reporting, completion and type display via [[https://github.com/the-lambda-church/merlin][merlin]] +- auto-completion with company mode via [[https://github.com/the-lambda-church/merlin][merlin]] +- syntax-checking via [[https://github.com/diml/utop][flycheck-ocaml]] + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =ocaml= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** OPAM packages +This layer requires some [[http://opam.ocaml.org][opam]] packages: + +- =merlin= for auto-completion +- =utop= +- =ocp-indent= + +To install them, use the following command: + +#+BEGIN_SRC sh + opam install merlin utop ocp-indent +#+END_SRC + +Make sure opam is initialized and configured. + +#+begin_src sh + opam init + opam config setup -a +#+end_src + +* Key Bindings + +| Key Binding | Description | +|-------------+----------------------------------------------------------| +| ~SPC m =~ | Indent buffer. | +| ~SPC m c c~ | Compile | +| ~SPC m c p~ | Check .merlin for errors | +| ~SPC m c r~ | Refresh changed .cmis in merlin | +| ~SPC m e C~ | Check for errors in current buffer | +| ~SPC m e n~ | Jump to next error | +| ~SPC m e N~ | Jump back to previous error | +| ~SPC m g a~ | Switch ML <-> MLI | +| ~SPC m g b~ | Go back to the last position where the user did a locate | +| ~SPC m g g~ | Locate the identifier under point (same window) | +| ~SPC m g G~ | Locate the identifier under point (different window) | +| ~SPC m g o~ | List occurrences for identifier under point | +| ~SPC m g l~ | Prompt for identifier and locate | +| ~SPC m g i~ | Prompt for module name and switch to ML file | +| ~SPC m g I~ | Prompt for module name and switch to MLI file | +| ~SPC m h h~ | Document the identifier under point | +| ~SPC m h t~ | Highlight identifier under cursor and print its type | +| ~SPC m h T~ | Prompt for expression and show its type | +| ~SPC m r d~ | Case analyze the current enclosing | + +** REPL (utop) + +| Key Binding | Description | +|-------------+------------------------------------------------------------------| +| ~SPC m s b~ | Send buffer to the REPL | +| ~SPC m s B~ | Send buffer to the REPL and switch to the REPL in =insert state= | +| ~SPC m s i~ | Start a REPL | +| ~SPC m s p~ | Send phrase to the REPL | +| ~SPC m s P~ | Send phrase to the REPL and switch to the REPL in =insert state= | +| ~SPC m s r~ | Send region to the REPL | +| ~SPC m s R~ | Send region to the REPL and switch to the REPL in =insert state= | +| ~C-j~ | (in REPL) next item in history | +| ~C-k~ | (in REPL) previous item in history | + +* TODOS + +** TODO Add more proper spacemacs key-bindings for basic merlin tasks +** TODO Add proper keybindings for ocamldebug +** TODO Add more keybindings for tuareg-mode diff --git a/layers/+lang/ocaml/config.el b/layers/+lang/ocaml/config.el new file mode 100644 index 0000000..845829a --- /dev/null +++ b/layers/+lang/ocaml/config.el @@ -0,0 +1,14 @@ +;;; config.el --- ocaml Layer Configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(spacemacs|defvar-company-backends merlin-mode) + +(spacemacs|define-jump-handlers tuareg-mode) diff --git a/layers/+lang/ocaml/funcs.el b/layers/+lang/ocaml/funcs.el new file mode 100644 index 0000000..88ed66d --- /dev/null +++ b/layers/+lang/ocaml/funcs.el @@ -0,0 +1,34 @@ +;;; funcs.el --- ocaml Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spacemacs//init-ocaml-opam () + (if (executable-find "opam") + (let* ((output (shell-command-to-string + "opam config var share 2> /dev/null")) + (share (when (< 0 (length output)) + (substring output 0 -1)))) + (when share + (setq opam-share share + opam-load-path (concat share "/emacs/site-lisp"))) + (add-to-list 'load-path opam-load-path)) + (spacemacs-buffer/warning + (concat "Cannot find \"opam\" executable. " + "The ocaml layer won't work properly.")))) + +(defun spacemacs/merlin-locate () + (interactive) + (let ((merlin-locate-in-new-window 'never)) + (merlin-locate))) + +(defun spacemacs/merlin-locate-other-window () + (interactive) + (let ((merlin-locate-in-new-window 'always)) + (merlin-locate))) diff --git a/layers/+lang/ocaml/img/ocaml.png b/layers/+lang/ocaml/img/ocaml.png new file mode 100644 index 0000000..2b0d2ea Binary files /dev/null and b/layers/+lang/ocaml/img/ocaml.png differ diff --git a/layers/+lang/ocaml/packages.el b/layers/+lang/ocaml/packages.el new file mode 100644 index 0000000..311e599 --- /dev/null +++ b/layers/+lang/ocaml/packages.el @@ -0,0 +1,158 @@ +;;; packages.el --- ocaml Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq ocaml-packages + '( + ;; auto-complete + company + ;; flycheck + ;; flycheck-ocaml + ggtags + helm-gtags + merlin + ocp-indent + smartparens + tuareg + utop + )) + +(defun ocaml/post-init-company () + (spacemacs|add-company-hook merlin-mode)) + +(when (configuration-layer/layer-usedp 'syntax-checking) + (defun ocaml/post-init-flycheck () + (spacemacs/add-flycheck-hook 'merlin-mode)) + (defun ocaml/init-flycheck-ocaml () + (use-package flycheck-ocaml + :if (configuration-layer/package-usedp 'flycheck) + :defer t + :init + (progn + (with-eval-after-load 'merlin + (setq merlin-error-after-save nil) + (flycheck-ocaml-setup)))))) + +(defun ocaml/post-init-ggtags () + (add-hook 'ocaml-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun ocaml/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'ocaml-mode)) + +(defun ocaml/init-merlin () + (use-package merlin + :defer t + :init + (progn + (add-to-list 'spacemacs-jump-handlers-tuareg-mode + 'spacemacs/merlin-locate) + (add-hook 'tuareg-mode-hook 'merlin-mode) + (setq merlin-completion-with-doc t) + (push 'merlin-company-backend company-backends-merlin-mode) + (spacemacs/set-leader-keys-for-major-mode 'tuareg-mode + "cp" 'merlin-project-check + "cv" 'merlin-goto-project-file + "eC" 'merlin-error-check + "en" 'merlin-error-next + "eN" 'merlin-error-prev + "gb" 'merlin-pop-stack + "gG" 'spacemacs/merlin-locate-other-window + "gl" 'merlin-locate-ident + "gi" 'merlin-switch-to-ml + "gI" 'merlin-switch-to-mli + "go" 'merlin-occurrences + "hh" 'merlin-document + "ht" 'merlin-type-enclosing + "hT" 'merlin-type-expr + "rd" 'merlin-destruct) + (spacemacs/declare-prefix-for-mode 'tuareg-mode "mc" "compile/check") + (spacemacs/declare-prefix-for-mode 'tuareg-mode "me" "errors") + (spacemacs/declare-prefix-for-mode 'tuareg-mode "mg" "goto") + (spacemacs/declare-prefix-for-mode 'tuareg-mode "mh" "help") + (spacemacs/declare-prefix-for-mode 'tuareg-mode "mr" "refactor")))) + +(defun ocaml/init-ocp-indent () + (use-package ocp-indent + :defer t + :init + (add-hook 'tuareg-mode-hook 'ocp-indent-caml-mode-setup) + (spacemacs/set-leader-keys-for-major-mode 'tuareg-mode + "=" 'ocp-indent-buffer))) + +(defun ocaml/post-init-smartparens () + (with-eval-after-load 'smartparens + ;; don't auto-close apostrophes (type 'a = foo) and backticks (`Foo) + (sp-local-pair 'tuareg-mode "'" nil :actions nil) + (sp-local-pair 'tuareg-mode "`" nil :actions nil))) + +(defun ocaml/init-tuareg () + (use-package tuareg + :mode (("\\.ml[ily]?$" . tuareg-mode) + ("\\.topml$" . tuareg-mode)) + :defer t + :init + (progn + (spacemacs//init-ocaml-opam) + (spacemacs/set-leader-keys-for-major-mode 'tuareg-mode + "ga" 'tuareg-find-alternate-file + "cc" 'compile) + ;; Make OCaml-generated files invisible to filename completion + (dolist (ext '(".cmo" ".cmx" ".cma" ".cmxa" ".cmi" ".cmxs" ".cmt" ".cmti" ".annot")) + (add-to-list 'completion-ignored-extensions ext))))) + +(defun ocaml/init-utop () + (use-package utop + :defer t + :init + (progn + (add-hook 'tuareg-mode-hook 'utop-minor-mode) + (spacemacs/register-repl 'utop 'utop "ocaml")) + :config + (progn + (if (executable-find "opam") + (setq utop-command "opam config exec -- utop -emacs") + (spacemacs-buffer/warning "Cannot find \"opam\" executable.")) + + (defun spacemacs/utop-eval-phrase-and-go () + "Send phrase to REPL and evaluate it and switch to the REPL in +`insert state'" + (interactive) + (utop-eval-phrase) + (utop) + (evil-insert-state)) + + (defun spacemacs/utop-eval-buffer-and-go () + "Send buffer to REPL and evaluate it and switch to the REPL in +`insert state'" + (interactive) + (utop-eval-buffer) + (utop) + (evil-insert-state)) + + (defun spacemacs/utop-eval-region-and-go (start end) + "Send region to REPL and evaluate it and switch to the REPL in +`insert state'" + (interactive "r") + (utop-eval-region start end) + (utop) + (evil-insert-state)) + + (spacemacs/set-leader-keys-for-major-mode 'tuareg-mode + "'" 'utop + "sb" 'utop-eval-buffer + "sB" 'spacemacs/utop-eval-buffer-and-go + "si" 'utop + "sp" 'utop-eval-phrase + "sP" 'spacemacs/utop-eval-phrase-and-go + "sr" 'utop-eval-region + "sR" 'spacemacs/utop-eval-region-and-go) + (spacemacs/declare-prefix-for-mode 'tuareg-mode "ms" "send")) + (define-key utop-mode-map (kbd "C-j") 'utop-history-goto-next) + (define-key utop-mode-map (kbd "C-k") 'utop-history-goto-prev))) diff --git a/layers/+lang/octave/README.org b/layers/+lang/octave/README.org new file mode 100644 index 0000000..6f3e7bf --- /dev/null +++ b/layers/+lang/octave/README.org @@ -0,0 +1,42 @@ +#+TITLE: Octave layer + +[[file:img/octave.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + - [[#inferior-repl-process][Inferior REPL process]] + - [[#helpers][Helpers]] + +* Description +This layer activates [[info:octave-mode][octave-mode]] for files with =.m= +extensions and configures spacemacs-style key bindings. + +* Install +Make sure that [[https://gnu.org/software/octave/][GNU Octave]] is installed and +in your PATH. For information about setting up $PATH, check out the +corresponding section in the FAQ (=SPC h SPC $PATH RET=). + +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =octave= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key bindings +** Inferior REPL process +Send code to inferior process with these commands: + +| Key | Description | +|-------------+---------------------------------------| +| ~SPC m s b~ | send buffer | +| ~SPC m s f~ | send function | +| ~SPC m s i~ | start/switch to REPL inferior process | +| ~SPC m s l~ | send line | +| ~SPC m s r~ | send region | + +** Helpers + +| Key Binding | Description | +|-------------+------------------------------------------| +| ~SPC m h h~ | view documentation for function at point | +| ~SPC m h i~ | read octave info documentation | diff --git a/layers/+lang/octave/config.el b/layers/+lang/octave/config.el new file mode 100644 index 0000000..d49504c --- /dev/null +++ b/layers/+lang/octave/config.el @@ -0,0 +1,14 @@ +;;; packages.el --- Octave Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; variables + +(spacemacs|define-jump-handlers octave-mode) diff --git a/layers/+lang/octave/img/octave.png b/layers/+lang/octave/img/octave.png new file mode 100644 index 0000000..d08046e Binary files /dev/null and b/layers/+lang/octave/img/octave.png differ diff --git a/layers/+lang/octave/packages.el b/layers/+lang/octave/packages.el new file mode 100644 index 0000000..648fc47 --- /dev/null +++ b/layers/+lang/octave/packages.el @@ -0,0 +1,40 @@ +;;; packages.el --- Octave Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq octave-packages + '( + ggtags + helm-gtags + (octave :location built-in) + )) + +(defun octave/init-octave () + (use-package octave + :mode ("\\.m\\'" . octave-mode) + :commands (run-octave) + :init (spacemacs/register-repl 'octave 'run-octave "octave") + :config (spacemacs/set-leader-keys-for-major-mode 'octave-mode + ;; helpers + "hh" 'octave-help + "hi" 'octave-lookfor + ;; REPL + "'" 'run-octave + "sb" 'octave-send-buffer + "sf" 'octave-send-defun + "si" 'run-octave + "sl" 'octave-send-line + "sr" 'octave-send-region))) + +(defun octave/post-init-ggtags () + (add-hook 'octave-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun octave/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'octave-mode)) diff --git a/layers/+lang/php/README.org b/layers/+lang/php/README.org new file mode 100644 index 0000000..b06407e --- /dev/null +++ b/layers/+lang/php/README.org @@ -0,0 +1,31 @@ +#+TITLE: PHP layer + +[[file:img/php.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features:]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + +* Description + +This layer adds PHP language support to Spacemacs. + +** Features: +- Edit PHP files using [[https://github.com/ejmr/php-mode][php-mode]] +- Edit Drupal files +- Run tests with PHPUnit +- Reformat code with PHP CBF + +The =gtags= layer is recommended to benefit from better =eldoc= and +=helm-gtags=. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =php= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key bindings + +TODO ! :-) diff --git a/layers/+lang/php/config.el b/layers/+lang/php/config.el new file mode 100644 index 0000000..6cfefb4 --- /dev/null +++ b/layers/+lang/php/config.el @@ -0,0 +1,16 @@ +;;; config.el --- PHP Layer config File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Kosta Harlan +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; variables + +(spacemacs|defvar-company-backends php-mode) + +(spacemacs|define-jump-handlers php-mode) diff --git a/layers/+lang/php/img/php.png b/layers/+lang/php/img/php.png new file mode 100644 index 0000000..8385a08 Binary files /dev/null and b/layers/+lang/php/img/php.png differ diff --git a/layers/+lang/php/packages.el b/layers/+lang/php/packages.el new file mode 100644 index 0000000..3fa6b42 --- /dev/null +++ b/layers/+lang/php/packages.el @@ -0,0 +1,65 @@ +;;; packages.el --- PHP Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq php-packages + '( + company + drupal-mode + eldoc + flycheck + ggtags + helm-gtags + php-auto-yasnippets + (php-extras :location (recipe :fetcher github :repo "arnested/php-extras")) + php-mode + phpcbf + phpunit + )) + +(defun php/post-init-company () + (spacemacs|add-company-hook php-mode)) + +(defun php/init-drupal-mode () + (use-package drupal-mode + :defer t)) + +(defun php/post-init-eldoc () + (add-hook 'php-mode-hook 'eldoc-mode)) + +(defun php/post-init-flycheck () + (spacemacs/add-flycheck-hook 'php-mode)) + +(defun php/post-init-ggtags () + (add-hook 'php-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun php/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'php-mode)) + +(defun php/init-php-auto-yasnippets () + (use-package php-auto-yasnippets + :defer t)) + +(defun php/init-php-extras () + (use-package php-extras + :defer t)) + +(defun php/init-php-mode () + (use-package php-mode + :defer t + :mode ("\\.php\\'" . php-mode))) + +(defun php/init-phpcbf () + (use-package phpcbf + :defer t)) + +(defun php/init-phpunit () + (use-package phpunit + :defer t)) diff --git a/layers/+lang/plantuml/README.org b/layers/+lang/plantuml/README.org new file mode 100644 index 0000000..8f00f2c --- /dev/null +++ b/layers/+lang/plantuml/README.org @@ -0,0 +1,51 @@ +#+TITLE: plantuml layer +[[file:img/logo.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#org-babel-integration][Org-Babel Integration]] + - [[#key-bindings][Key bindings]] + +* Description +This layer enables support for [[https://github.com/skuro/plantuml-mode][plantuml-mode]], which provides +a major-mode for [[http://plantuml.com][plantuml]]. PlantUML is a tool to generate [[https://en.wikipedia.org/wiki/Unified_Modeling_Language][UML diagrams]] from plain-text. + +For help with how to use plantuml, see the [[http://plantuml.com][plantuml website]] and the [[http://plantuml.com/PlantUML_Language_Reference_Guide.pdf][reference guide]]. + +The official file extension supported by this layer is =.pum=. If you want something else, +set it in your =user-config= function of your =~/.spacemacs= file. + +For example, the following diagram can be defined as follows: + +#+BEGIN_SRC plantuml +@startuml +JAremko->robbyoconnor : I think the docs can benefit from some kind of illustration +JAremko<-robbyoconnor : I'm too lazy -- I have actual work to do. I link to the docs. If you can write me a diagram in plantuml, I'll gladly compile and add it. +JAremko->robbyoconnor : *gives ths diagram* +robbyoconnor<-JAremko : *robbyoconnor adds it and JAremko is happy* +... +robbyoconnor->theOtherPerson : And they thinks it's funny? Yup, they definitely finds it funny. Right? +@enduml +#+END_SRC + +[[file:img/dia.png]] + +* Install +To use this contribution add it to your =~/.spacemacs= + +#+begin_src emacs-lisp + (setq-default dotspacemacs-configuration-layers '(plantuml)) +#+end_src + +* Org-Babel Integration + +To enable the execution of embedded plantuml code blocks within [[http://orgmode.org/][Org-Mode]] +documents, define a value for =org-plantuml-jar-path= in your =~/.spacemacs=. + +* Key bindings + +| Key Binding | Description | +|--------------------------+-------------------------------------------------------| +| ~SPC m c c~ or ~C-c C-c~ | Build diagram from the text in the current buffer | +| ~SPC m c o~ | Set the output type (~unicode text~, ~svg~, or ~png~) | diff --git a/layers/+lang/plantuml/img/dia.png b/layers/+lang/plantuml/img/dia.png new file mode 100644 index 0000000..c1a8e70 Binary files /dev/null and b/layers/+lang/plantuml/img/dia.png differ diff --git a/layers/+lang/plantuml/img/logo.png b/layers/+lang/plantuml/img/logo.png new file mode 100644 index 0000000..214b4ed Binary files /dev/null and b/layers/+lang/plantuml/img/logo.png differ diff --git a/layers/+lang/plantuml/packages.el b/layers/+lang/plantuml/packages.el new file mode 100644 index 0000000..9972389 --- /dev/null +++ b/layers/+lang/plantuml/packages.el @@ -0,0 +1,32 @@ +;;; packages.el --- plantuml layer packages file for Spacemacs. +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Robert O'Connor +;; Contributor: Carlo Sciolla +;; URL: https://github.com/robbyoconnor +;; +;;; Commentary: +;; +;; Adds PlantUML support to Spacemacs using plantuml-mode. +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + +;;; Code: +(defconst plantuml-packages + '(org + plantuml-mode)) + +(defun plantuml/post-init-org () + (spacemacs|use-package-add-hook org + :post-config (add-to-list 'org-babel-load-languages '(plantuml . t)))) + +(defun plantuml/init-plantuml-mode () + (use-package plantuml-mode + :defer t + :mode ("\\.pum\\'" . plantuml-mode) + :config (spacemacs/set-leader-keys-for-major-mode 'plantuml-mode + "cc" 'plantuml-preview + "co" 'plantuml-set-output-type))) diff --git a/layers/+lang/purescript/README.org b/layers/+lang/purescript/README.org new file mode 100644 index 0000000..bfe7961 --- /dev/null +++ b/layers/+lang/purescript/README.org @@ -0,0 +1,81 @@ +#+TITLE: Purescript layer + +[[file:img/purescript-logo.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#configuration][Configuration]] + - [[#add-import-on-completion][Add import on completion]] + - [[#error-popup][Error popup]] + - [[#key-bindings][Key bindings]] + - [[#purescript][Purescript]] + - [[#imports][Imports]] + - [[#psc-ide][psc-ide]] + - [[#repl][REPL]] + +* Description + +This layer provides basic Purescript editing support for spacemacs +thanks to the following packages: +- [[https://github.com/dysinger/purescript-mode][purescript-mode]] +- [[https://github.com/ardumont/emacs-psci][psci]] +- [[https://github.com/epost/psc-ide-emacs][psc-ide-emacs]] + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =purescript= to the existing =dotspacemacs-configuration-layers= list in +this file. + +You'll also need to make sure the PureScript compiler and its associated +binaries (psc-ide-server, psci,...) are on your path. Installation instructions +can be found [[http://www.purescript.org/download/][here]]. + +* Configuration +** Add import on completion +Set =purescript-add-import-on-completion= to nil to make =psc-ide= stop adding +imports on completion. Default value it =t=. + +** Error popup +If you set =purescript-enable-rebuild-on-save= to non-nil, you will get a popup +buffer showing you your current warnings/errors one at a time. This is primarily +meant as an alternative to using flycheck. Default value is nil. + +* Key bindings +** Purescript +*** Imports + +| Key Binding | Description | +|-------------+---------------------------------------------------------------| +| ~SPC m i =~ | Format imports | +| ~SPC m i \~ | Return to where you were editing before navigating to imports | +| ~SPC m i a~ | Align imports | +| ~SPC m i n~ | Navigate to the imports | + +*** psc-ide +=psc-ide= command are available under ~SPC m m~: + +| Key Binding | Description | +|---------------+---------------------------------------------------------------------------| +| ~SPC m m s~ | Start psc-ide-server | +| ~SPC m m l~ | Load definitions for the modules inside your project | +| ~SPC m h t~ | Show type at point | +| ~SPC m g g~ | Goto definition for identifier at point | +| ~SPC m m b~ | Rebuilds the current file and displays any warnings or errors | +| ~SPC m m i a~ | Add an import for the identifier at the current cursor position | +| ~SPC m m i s~ | Inserts a suggestion for the warning/error at the current cursor position | +| ~SPC m m t~ | Add a new clause for the function signature at point | +| ~SPC m m c s~ | Casesplits on the identifier at the current cursor position | +| ~SPC m m q~ | Quit the current psc-ide-server | +| ~SPC m m L~ | Load a specific module (This is mostly used for troubleshooting) | + +** REPL +[[https://github.com/ardumont/emacs-psci][psci]] provides a very basic REPL for purescript. The following key +bindings are available: + +| Key Binding | Description | +|-------------+----------------------------------------------------------------------------------| +| ~SPC m s b~ | Equivalent of =:m /path/to/current/module/file.purs= - Load for importing | +| ~SPC m s i~ | Launch a psci console buffer | +| ~SPC m s m~ | Equivalent of =:i your.current.module.name= - Import for use in PSCI | +| ~SPC m s p~ | Load or reload files defined in the project file .psci | diff --git a/layers/+lang/purescript/config.el b/layers/+lang/purescript/config.el new file mode 100644 index 0000000..0eaeea0 --- /dev/null +++ b/layers/+lang/purescript/config.el @@ -0,0 +1,20 @@ +;;; config.el --- Purescript Layer config File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Ryan L. Bell +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(spacemacs|defvar-company-backends purescript-mode) + +(spacemacs|define-jump-handlers purescript-mode) + +(defvar purescript-add-import-on-completion t + "If non-nil adds imports for completed identifiers") + +(defvar purescript-enable-rebuild-on-save nil + "If non-nil rebuild on save is enabled") diff --git a/layers/+lang/purescript/img/purescript-logo.png b/layers/+lang/purescript/img/purescript-logo.png new file mode 100644 index 0000000..092b11c Binary files /dev/null and b/layers/+lang/purescript/img/purescript-logo.png differ diff --git a/layers/+lang/purescript/packages.el b/layers/+lang/purescript/packages.el new file mode 100644 index 0000000..55c9e88 --- /dev/null +++ b/layers/+lang/purescript/packages.el @@ -0,0 +1,81 @@ +;;; packages.el --- Purescript Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Ryan L. Bell +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + +(setq purescript-packages + '(company + flycheck + purescript-mode + psci + psc-ide + popwin)) + +(defun purescript/post-init-company () + (spacemacs|add-company-hook purescript-mode)) + +(defun purescript/post-init-flycheck () + (spacemacs/add-flycheck-hook 'purescript-mode)) + +(defun purescript/init-purescript-mode () + (use-package purescript-mode + :defer t + :init + (progn + (add-hook 'purescript-mode-hook 'turn-on-purescript-indentation) + (spacemacs/set-leader-keys-for-major-mode 'purescript-mode + "i=" 'purescript-mode-format-imports + "i`" 'purescript-navigate-imports-return + "ia" 'purescript-align-imports + "in" 'purescript-navigate-imports)))) + +(defun purescript/init-psci () + (use-package psci + :defer t + :init + (progn + (spacemacs/register-repl 'psci 'psci "purescript") + (add-hook 'purescript-mode-hook 'inferior-psci-mode) + (spacemacs/set-leader-keys-for-major-mode 'purescript-mode + "'" 'psci + "sb" 'psci/load-current-file! + "si" 'psci + "sm" 'psci/load-module! + "sp" 'psci/load-project-modules!)))) + +(defun purescript/init-psc-ide () + (use-package psc-ide + :defer t + :init + (progn + (add-hook 'purescript-mode-hook 'psc-ide-mode) + (spacemacs/declare-prefix-for-mode 'purescript-mode "mm" "purescript/psc-ide") + (push 'company-psc-ide-backend company-backends-purescript-mode) + + (customize-set-variable 'psc-ide-add-import-on-completion purescript-add-import-on-completion) + (customize-set-variable 'psc-ide-rebuild-on-save purescript-enable-rebuild-on-save) + + (add-to-list 'spacemacs-jump-handlers-purescript-mode 'psc-ide-goto-definition) + (spacemacs/set-leader-keys-for-major-mode 'purescript-mode + "mt" 'psc-ide-add-clause + "mcs" 'psc-ide-case-split + "ms" 'psc-ide-server-start + "mb" 'psc-ide-rebuild + "mq" 'psc-ide-server-quit + "ml" 'psc-ide-load-all + "mL" 'psc-ide-load-module + "mia" 'psc-ide-add-import + "mis" 'psc-ide-flycheck-insert-suggestion + "ht" 'psc-ide-show-type)))) + +(defun purescript/pre-init-popwin () + (spacemacs|use-package-add-hook popwin + :post-config + (push '("*psc-ide-rebuild*" :tail t :noselect t) popwin:special-display-config))) diff --git a/layers/+lang/python/README.org b/layers/+lang/python/README.org new file mode 100644 index 0000000..9827c20 --- /dev/null +++ b/layers/+lang/python/README.org @@ -0,0 +1,312 @@ +#+TITLE: Python layer + +[[file:img/python.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#dependencies][Dependencies]] + - [[#auto-completion-anaconda-dependencies][Auto-completion: Anaconda dependencies]] + - [[#syntax-checking][Syntax checking]] + - [[#test-runner][Test runner]] + - [[#automatic-buffer-formatting-on-save][Automatic buffer formatting on save]] + - [[#autoflake][autoflake]] + - [[#pylookup][pylookup]] + - [[#hy-mode][Hy-mode]] + - [[#management-of-python-versions-and-virtual-environments][Management of Python versions and virtual environments]] + - [[#manage-virtual-environments-with-pyvenv][Manage virtual environments with pyvenv]] + - [[#manage-multiple-python-versions-with-pyenv][Manage multiple Python versions with pyenv]] + - [[#automatic-activation-of-local-pyenv-version][Automatic activation of local pyenv version]] + - [[#key-bindings][Key Bindings]] + - [[#inferior-repl-process][Inferior REPL process]] + - [[#running-python-script-in-shell][Running Python Script in shell]] + - [[#testing][Testing]] + - [[#refactoring][Refactoring]] + - [[#live-coding][Live coding]] + - [[#hy-repl-process][Hy REPL process]] + - [[#other-python-commands][Other Python commands]] + - [[#configuration][Configuration]] + - [[#fill-column][Fill column]] + - [[#sort-imports][Sort imports]] + +* Description +This layer adds support for the Python language. + +** Features +- Auto-completion using [[https://github.com/proofit404/anaconda-mode][anaconda-mode]] +- Code Navigation using [[https://github.com/proofit404/anaconda-mode][anaconda-mode]] +- Documentation Lookup using [[https://github.com/proofit404/anaconda-mode][anaconda-mode]] and [[https://github.com/tsgates/pylookup][pylookup]] +- Test Runners using [[https://github.com/syl20bnr/nose.el][nose.el]] or [[https://github.com/ionrock/pytest-el][pytest]] +- Virtual Environment using [[https://github.com/jorgenschaefer/pyvenv][pyvenv]] and [[https://github.com/yyuu/pyenv][pyenv]] +- semantic mode is enabled +- PEP8 compliant formatting via [[https://github.com/google/yapf][YAPF]] +- PEP8 checks with [[https://pypi.python.org/pypi/flake8][flake8]] or [[https://pypi.python.org/pypi/pylint/1.6.4][pylint]] +- Suppression of unused import with [[https://github.com/myint/autoflake][autoflake]] +- Use the ~%~ key to jump between blocks with [[https://github.com/redguardtoo/evil-matchit][evil-matchit]] +- Sort imports with [[https://pypi.python.org/pypi/isort][isort]] + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =python= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Dependencies +*** Auto-completion: Anaconda dependencies +=anaconda-mode= tries to install the dependencies itself but sometimes +it does not work and you may encounter the following message when +opening a python buffer: + +#+begin_example + Blocking call to accept-process-output with quit inhibited!! +#+end_example + +To fix this, install the =anaconda-mode= [[https://github.com/proofit404/anaconda-mode/blob/master/requirements.txt][anaconda-deps]] by hand: + +#+begin_src sh + pip install --upgrade "jedi>=0.9.0" "json-rpc>=1.8.1" "service_factory>=0.1.5" +#+end_src + +Source: https://github.com/proofit404/anaconda-mode#issues + +If you are facing errors such as "Unable to run anaconda-mode server", try +setting your ~PYTHONPATH~ as explained at +https://github.com/proofit404/anaconda-mode#pythonpath + +*** Syntax checking +Syntax checking uses `flake8` package: + +#+begin_src sh + pip install flake8 +#+end_src + +** Test runner +Both =nose= and =pytest= are supported. By default =nose= is used. +To choose your test runner set the layer variable =python-test-runner= to +either =nose= or =pytest=. + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers + '((python :variables python-test-runner 'pytest))) +#+END_SRC + +If you need both then you can set =python-test-runner= to a list like this: +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers + '((python :variables python-test-runner '(pytest nose)))) +#+END_SRC + +This means that =pytest= is your primary test runner. To use the secondary test +runner you can call the test functions with a prefix argument e.g. ~SPC u SPC m +t t~ to run one test with =nose=. + +To set project specific test runners you can set =python-test-runner= in a +directory local variable in your project root. ~SPC f v d~ in Spacemacs. See +[[https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html][the official documentation]] for more information. + +The root of the project is detected with a =.git= directory or a =setup.cfg= file. + +** Automatic buffer formatting on save +To enable automatic buffer formatting on save with [[https://github.com/google/yapf][YAPF]] set the variable +=python-enable-yapf-format-on-save= to =t=. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '( + (python :variables python-enable-yapf-format-on-save t))) +#+END_SRC + +** autoflake +To be able to suppress unused imports easily, install [[https://github.com/myint/autoflake][autoflake]]: + +#+BEGIN_SRC sh + pip install autoflake +#+END_SRC + +** pylookup +To use =pylookup= on ~SPC m h H~, make sure you update the database first, using +~SPC SPC pylookup-update~. + +** Hy-mode +To be able to connect to an inferior lisp repl in =hy-mode=, you need to make sure +that hy is installed. + +#+BEGIN_SRC sh + pip install hy +#+END_SRC + +* Management of Python versions and virtual environments + +** Manage virtual environments with pyvenv +A virtual environment provides isolation of your Python package versions. For a +general overview see [[http://docs.python-guide.org/en/latest/dev/virtualenvs/][this site]]. [[http://virtualenvwrapper.readthedocs.org/en/latest/index.html][Virtualenvwrapper]] which is also explained in the +previous link, is a program which manages your virtual environments in a central +location set by the ~WORKON_HOME~ environment variable. + +Spacemacs integration of virtual environments and virtualenvwrapper is provided +by the [[https://github.com/jorgenschaefer/pyvenv][pyvenv]] package. It provides the following keybindings: + +| Key Binding | Description | +|-------------+-------------------------------------------------| +| ~SPC m V a~ | activate a virtual environment in any directory | +| ~SPC m V d~ | deactivate active virtual environment | +| ~SPC m V w~ | work on virtual environment in ~WORKON_HOME~ | + +** Manage multiple Python versions with pyenv +If you need multiple Python versions (e.g. Python 2 and Python 3) then take a +look at [[https://github.com/yyuu/pyenv][pyenv]]. It enables the installation and managment of multiple +Python versions. +[[https://www.brianthicks.com/post/2015/04/15/automate-your-python-environment-with-pyenv/][This blogpost]] gives a good overview on how to use the tool. Spacemacs +integration is provided by [[https://github.com/proofit404/pyenv-mode][pyenv mode]] which has the following keybindings. + +| Key Binding | Description | +|-------------+--------------------------------------| +| ~SPC m v s~ | set a pyenv environment with [[https://github.com/yyuu/pyenv][pyenv]] | +| ~SPC m v u~ | unset a pyenv environment with [[https://github.com/yyuu/pyenv][pyenv]] | + +Pyenv can also manage virtual environments for each of the Python versions it +has installed. Those will be listed alongside your Python versions. + +*** Automatic activation of local pyenv version +A project-specific pyenv version may be written to a file called +=.python-version= using the [[https://github.com/yyuu/pyenv/blob/master/COMMANDS.md#pyenv-local][pyenv local]] command. + +Spacemacs can search in parent directories for this file, and automatically set +the pyenv version. The behavior can be set with the variable +=python-auto-set-local-pyenv-version= to: +- =on-visit= (default) set the version when you visit a python buffer, +- =on-project-switch= set the version when you switch projects, +- =nil= to disable. + +* Key Bindings + +** Inferior REPL process +Start a Python or iPython inferior REPL process with ~SPC m s i~. +If =ipython= is available in system executable search paths, =ipython= +will be used to launch python shell; otherwise, default =python= +interpreter will be used. You may change your system executable +search path by activating a virtual environment. + +Send code to inferior process commands: + +| Key Binding | Description | +|-------------+-------------------------------------------------| +| ~SPC m s b~ | send buffer and keep code buffer focused | +| ~SPC m s B~ | send buffer and switch to REPL in insert mode | +| ~SPC m s f~ | send function and keep code buffer focused | +| ~SPC m s F~ | send function and switch to REPL in insert mode | +| ~SPC m s i~ | start inferior REPL process | +| ~SPC m s r~ | send region and keep code buffer focused | +| ~SPC m s R~ | send region and switch to REPL in insert mode | +| ~CTRL+j~ | next item in REPL history | +| ~CTRL+k~ | previous item in REPL history | + +** Running Python Script in shell +To run a Python script like you would in the shell press ~SPC m c c~ +to start the Python script in comint mode. This is useful when working with +multiple Python files since the REPL does not reload changes made in other +modules. + +| Key Binding | Description | +|-------------+---------------------------------------------------------------------------| +| ~SPC m c c~ | Execute current file in a comint shell | +| ~SPC m c C~ | Execute current file in a comint shell and switch to it in =insert state= | + +*Note:* With the universal argument ~SPC u~ you can enter a new +compilation command. + +** Testing +Test commands start with ~m t~. To use the secondary test runner call the +function with a prefix argument, for example ~SPC u SPC m t a~. + +| No Debug | Description | +|-------------+----------------------------------------------------------| +| ~SPC m t a~ | launch all tests of the project | +| ~SPC m t b~ | launch all tests of the current buffer (same as module) | +| ~SPC m t m~ | launch all tests of the current module | +| ~SPC m t s~ | launch all tests of the current suite (only with =nose=) | +| ~SPC m t t~ | launch the current test (function) | + +| Debug | Description | +|-------------+------------------------------------------------------------------------| +| ~SPC m t A~ | launch all tests of the project in debug mode | +| ~SPC m t B~ | launch all tests of the current buffer (module) in debug mode | +| ~SPC m t M~ | launch all tests of the current module in debug mode | +| ~SPC m t S~ | launch all tests of the current suite in debug mode (only with =nose=) | +| ~SPC m t T~ | launch the current test (function) in debug mode | + +** Refactoring + +| Key Binding | Description | +|-------------+--------------------------------------| +| ~SPC m r i~ | remove unused imports with [[https://github.com/myint/autoflake][autoflake]] | +| ~SPC m r I~ | sort imports with [[https://pypi.python.org/pypi/isort][isort]] | + +** Live coding + +Live coding is provided by the [[https://github.com/donkirkby/live-py-plugin][live-py-plugin.]] + +| Key Binding | Description | +|-------------+---------------------| +| ~SPC m l~ | Toggle live-py-mode | + +** Hy REPL process +Start a Hy inferior repel process with ~SPC m s i~. If =hy= is +available in system executable search paths, =hy= will be used to +launch the shell. You may change your system executable search path +by activating a virtual enviornment. + +Send code to hy REPL commands: + +| Key Binding | Description | +|-------------+-----------------------------------------------------------| +| ~SPC m s b~ | send buffer and keep code buffer focused | +| ~SPC m s B~ | switch to REPL | +| ~SPC m s e~ | send sexp in front of the cursor to the REPL | +| ~SPC m s f~ | send function to REPL and stay in buffer | +| ~SPC m s F~ | send function to REPL and switch to repl buffer | +| ~SPC m s i~ | start inferior hy repl | +| ~SPC m s r~ | send current region to the REPL and stay in buffer | +| ~SPC m s R~ | send current region to the REPL and switch to repl buffer | + +** Other Python commands + +| Key Binding | Description | +|-------------+------------------------------------------------------------------------------| +| ~SPC m =~ | Reformat the buffer according to PEP8 using [[https://github.com/google/yapf][YAPF]] | +| ~SPC m d b~ | toggle a breakpoint using =wdb=, =ipdb=, =pudb= or =pdb= | +| ~SPC m g g~ | go to definition using =anaconda-mode-find-definitions= (~C-o~ to jump back) | +| ~SPC m g a~ | go to assignment using =anaconda-mode-find-assignments= (~C-o~ to jump back) | +| ~SPC m g b~ | jump back | +| ~SPC m g u~ | navigate between usages with =anaconda-mode-find-references= | +| ~SPC m h d~ | look for documentation using =helm-pydoc= | +| ~SPC m h h~ | quick documentation using anaconda | +| ~SPC m h H~ | open documentation in =firefox= using [[https://github.com/tsgates/pylookup][pylookup]] | +| ~SPC m v s~ | set a pyenv environment with [[https://github.com/yyuu/pyenv][pyenv]] | +| ~SPC m v u~ | unset a pyenv environment with [[https://github.com/yyuu/pyenv][pyenv]] | +| ~SPC m V w~ | work on virtual environment in ~WORKON_HOME~ | +| ~SPC m V a~ | activate a virtual environment in any directory | +| ~SPC m V d~ | deactivate active virtual environment | + +* Configuration +** Fill column +If you want to customize the fill column value, use something like this inside +the ~user-init~ function in your ~.spacemacs~: + +#+BEGIN_SRC elisp +(setq-default dotspacemacs-configuration-layers '( + (python :variables python-fill-column 99))) +#+END_SRC + +** Sort imports +If you want imports to be automatically sorted when you save a file (using +[[https://pypi.python.org/pypi/isort][isort]]), set the =python-sort-imports-on-save= variable in the python layer +config section: + +#+BEGIN_SRC elisp +(setq-default dotspacemacs-configuration-layers + '((python :variables python-sort-imports-on-save t))) +#+END_SRC + +or as a directory-local variable (for per-project settings). diff --git a/layers/+lang/python/config.el b/layers/+lang/python/config.el new file mode 100644 index 0000000..3185c07 --- /dev/null +++ b/layers/+lang/python/config.el @@ -0,0 +1,39 @@ +;;; config.el --- Python Layer Configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; variables + +(spacemacs|defvar-company-backends python-mode) +(spacemacs|defvar-company-backends inferior-python-mode) +(spacemacs|defvar-company-backends pip-requirements-mode) + +(spacemacs|define-jump-handlers python-mode) +(spacemacs|define-jump-handlers cython-mode anaconda-mode-goto) + +(defvar python-enable-yapf-format-on-save nil + "If non-nil, automatically format code with YAPF on save.") + +(defvar python-test-runner 'nose + "Test runner to use. Possible values are `nose' or `pytest'.") + +(defvar python-fill-column 79 + "Fill column value for python buffers") + +(defvar python-tab-width 4 + "Tab width value for python buffers") + +(defvar python-auto-set-local-pyenv-version 'on-visit + "Automatically set pyenv version from \".python-version\". + +Possible values are `on-visit', `on-project-switch' or `nil'.") + +(defvar python-sort-imports-on-save nil + "If non-nil, automatically sort imports on save.") diff --git a/layers/+lang/python/funcs.el b/layers/+lang/python/funcs.el new file mode 100644 index 0000000..f0aea5c --- /dev/null +++ b/layers/+lang/python/funcs.el @@ -0,0 +1,179 @@ +;;; funcs.el --- Python Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; from http://pedrokroger.net/2010/07/configuring-emacs-as-a-python-ide-2/ +(defun spacemacs/python-annotate-pdb () + "Highlight break point lines." + (interactive) + (highlight-lines-matching-regexp "import i?pu?db") + (highlight-lines-matching-regexp "i?pu?db.set_trace()")) + +(defun spacemacs/pyenv-executable-find (command) + "Find executable taking pyenv shims into account." + (if (executable-find "pyenv") + (progn + (let ((pyenv-string (shell-command-to-string (concat "pyenv which " command)))) + (unless (string-match "not found" pyenv-string) + pyenv-string))) + (executable-find command))) + +(defun spacemacs/python-setup-shell (&rest args) + (if (spacemacs/pyenv-executable-find "ipython") + (progn (setq python-shell-interpreter "ipython") + (if (version< (replace-regexp-in-string "\n$" "" (shell-command-to-string "ipython --version")) "5") + (setq python-shell-interpreter-args "-i") + (setq python-shell-interpreter-args "--simple-prompt -i"))) + (progn + (setq python-shell-interpreter-args "-i") + (setq python-shell-interpreter "python")))) + +(defun spacemacs/python-toggle-breakpoint () + "Add a break point, highlight it." + (interactive) + (let ((trace (cond ((spacemacs/pyenv-executable-find "wdb") "import wdb; wdb.set_trace()") + ((spacemacs/pyenv-executable-find "ipdb") "import ipdb; ipdb.set_trace()") + ((spacemacs/pyenv-executable-find "pudb") "import pudb; pudb.set_trace()") + (t "import pdb; pdb.set_trace()"))) + (line (thing-at-point 'line))) + (if (and line (string-match trace line)) + (kill-whole-line) + (progn + (back-to-indentation) + (insert-string trace) + (insert-string "\n") + (python-indent-line))))) + +;; from https://www.snip2code.com/Snippet/127022/Emacs-auto-remove-unused-import-statemen +(defun spacemacs/python-remove-unused-imports() + "Use Autoflake to remove unused function" + "autoflake --remove-all-unused-imports -i unused_imports.py" + (interactive) + (if (executable-find "autoflake") + (progn + (shell-command (format "autoflake --remove-all-unused-imports -i %s" + (shell-quote-argument (buffer-file-name)))) + (revert-buffer t t t)) + (message "Error: Cannot find autoflake executable."))) + +(defun spacemacs//pyenv-mode-set-local-version () + "Set pyenv version from \".python-version\" by looking in parent directories." + (interactive) + (let ((root-path (locate-dominating-file default-directory + ".python-version"))) + (when root-path + (let* ((file-path (expand-file-name ".python-version" root-path)) + (version + (with-temp-buffer + (insert-file-contents-literally file-path) + (buffer-substring-no-properties (line-beginning-position) + (line-end-position))))) + (if (member version (pyenv-mode-versions)) + (pyenv-mode-set version) + (message "pyenv: version `%s' is not installed (set by %s)" + version file-path)))))) + + +;; Tests + +(defun spacemacs//disable-semantic-idle-summary-mode () + "Disable semantic-idle-summary in Python mode. +Anaconda provides more useful information but can not do it properly +when this mode is enabled since the minibuffer is cleared all the time." + (semantic-idle-summary-mode 0)) + +(defun spacemacs//python-imenu-create-index-use-semantic-maybe () + "Use semantic if the layer is enabled." + (setq imenu-create-index-function 'spacemacs/python-imenu-create-index)) + +;; fix for issue #2569 (https://github.com/syl20bnr/spacemacs/issues/2569) and +;; Emacs 24.5 and older. use `semantic-create-imenu-index' only when +;; `semantic-mode' is enabled, otherwise use `python-imenu-create-index' +(defun spacemacs/python-imenu-create-index () + (if (bound-and-true-p semantic-mode) + (semantic-create-imenu-index) + (python-imenu-create-index))) + +(defun spacemacs//python-get-main-testrunner () + "Get the main test runner." + (if (listp python-test-runner) (car python-test-runner) python-test-runner)) + +(defun spacemacs//python-get-secondary-testrunner () + "Get the secondary test runner" + (cdr (assoc (spacemacs//python-get-main-testrunner) '((pytest . nose) + (nose . pytest))))) + +(defun spacemacs//python-call-correct-test-function (arg funcalist) + "Call a test function based on the chosen test framework. +ARG is the universal-argument which chooses between the main and +the secondary test runner. FUNCALIST is an alist of the function +to be called for each testrunner. " + (let ((test-runner (if arg + (spacemacs//python-get-secondary-testrunner) + (spacemacs//python-get-main-testrunner)))) + (funcall (cdr (assoc test-runner funcalist))))) + +(defun spacemacs/python-test-all (arg) + "Run all tests." + (interactive "P") + (spacemacs//python-call-correct-test-function arg '((pytest . pytest-all) + (nose . nosetests-all)))) + +(defun spacemacs/python-test-pdb-all (arg) + "Run all tests in debug mode." + (interactive "P") + (spacemacs//python-call-correct-test-function arg '((pytest . pytest-pdb-all) + (nose . nosetests-pdb-all)))) + +(defun spacemacs/python-test-module (arg) + "Run all tests in the current module." + (interactive "P") + (spacemacs//python-call-correct-test-function arg '((pytest . pytest-module) + (nose . nosetests-module)))) + +(defun spacemacs/python-test-pdb-module (arg) + "Run all tests in the current module in debug mode." + (interactive "P") + (spacemacs//python-call-correct-test-function + arg + '((pytest . pytest-pdb-module) + (nose . nosetests-pdb-module)))) + +(defun spacemacs/python-test-one (arg) + "Run current test." + (interactive "P") + (spacemacs//python-call-correct-test-function arg '((pytest . pytest-one) + (nose . nosetests-one)))) + +(defun spacemacs/python-test-pdb-one (arg) + "Run current test in debug mode." + (interactive "P") + (spacemacs//python-call-correct-test-function arg '((pytest . pytest-pdb-one) + (nose . nosetests-pdb-one)))) + +(defun spacemacs//bind-python-testing-keys () + "Bind the keys for testing in Python." + (spacemacs/declare-prefix-for-mode 'python-mode "mt" "test") + (spacemacs/set-leader-keys-for-major-mode 'python-mode + "tA" 'spacemacs/python-test-pdb-all + "ta" 'spacemacs/python-test-all + "tB" 'spacemacs/python-test-pdb-module + "tb" 'spacemacs/python-test-module + "tT" 'spacemacs/python-test-pdb-one + "tt" 'spacemacs/python-test-one + "tM" 'spacemacs/python-test-pdb-module + "tm" 'spacemacs/python-test-module)) + +(defun spacemacs//python-sort-imports () + ;; py-isort-before-save checks the major mode as well, however we can prevent + ;; it from loading the package unnecessarily by doing our own check + (when (and python-sort-imports-on-save + (derived-mode-p 'python-mode)) + (py-isort-before-save))) diff --git a/layers/+lang/python/img/python.png b/layers/+lang/python/img/python.png new file mode 100644 index 0000000..a676c42 Binary files /dev/null and b/layers/+lang/python/img/python.png differ diff --git a/layers/+lang/python/local/nose/README.md b/layers/+lang/python/local/nose/README.md new file mode 100644 index 0000000..0f1da73 --- /dev/null +++ b/layers/+lang/python/local/nose/README.md @@ -0,0 +1,81 @@ +nose.el +======= + +This gives a bunch of functions that handle running nosetests on a +particular buffer or part of a buffer. + +This is a fork from the [bitbucket repository][fork]. + +What's different ? +------------------ + +This fork: +- brings Windows compatibility. +- calls python with an inline script to launch nose. +- can launch test suites (require to install the nose fixes via +`easy_install nose-fixes`) +- is compatible with virtualenv + +Install +------- + +You'll need to add the directory containing `nose.el` to your `load-path`, +and then + + (require 'nose) + +Usage +------- + +By default, the root of a project is found by looking for any of the files +`setup.cfg`, `.hg`, `.git` and `.projectile`. You can add files to check +for to the file list: + + (add-to-list 'nose-project-root-files "something") + +or you can change the project root test to detect in some other way +whether a directory is the project root: + + (setq nose-project-root-test (lambda (dirname) (equal dirname "foo"))) + +If you want dots as output, rather than the verbose output: + + (defvar nose-use-verbose nil) ; default is t + +Probably also want some key bindings: + + (add-hook 'python-mode-hook + (lambda () + (local-set-key "\C-ca" 'nosetests-all) + (local-set-key "\C-cm" 'nosetests-module) + (local-set-key "\C-cs" 'nosetests-suite) + (local-set-key "\C-c." 'nosetests-one) + (local-set-key "\C-cpa" 'nosetests-pdb-all) + (local-set-key "\C-cpm" 'nosetests-pdb-module) + (local-set-key "\C-cps" 'nosetests-pdb-suite) + (local-set-key "\C-cp." 'nosetests-pdb-one))) + +Notes +------ + +To be able to launch a test suite, your suite must define a function with +the name `load_tests`. + +For instance (typical example to make `PyDev` *and* `nose.el` happy): + + import unittest + + ALL_TESTS = unittest.TestSuite([my_suites_go_here]) + + def load_tests(loader=None, tests=None, pattern=None): + return ALL_TESTS + + if __name__ == '__main__': + unittest.TextTestRunner(verbosity=2).run(ALL_TESTS) + +Thanks +------ + +To the original authors of nose.el: `Jason Pellerin` and `Augie Fackler` + +[fork]: https://bitbucket.org/durin42/nosemacs/overview diff --git a/layers/+lang/python/local/nose/nose.el b/layers/+lang/python/local/nose/nose.el new file mode 100644 index 0000000..5afaf1a --- /dev/null +++ b/layers/+lang/python/local/nose/nose.el @@ -0,0 +1,186 @@ +;;; nose.el --- Easy Python test running in Emacs + +;; Copyright (C) 2009 Jason Pellerin, Augie Fackler +;; Copyright (C) 2013-2015 Sylvain Benner + +;; Created: 04 Apr 2009 +;; Version: 0.3 +;; Keywords: nose python testing + +;; This file is NOT part of GNU Emacs. + +;; Licensed under the same terms as Emacs. + +;;; Commentary: +;; This gives a bunch of functions that handle running nosetests on a +;; particular buffer or part of a buffer. + +;;; Installation + +;; In your emacs config: +;; +;; (require 'nose) + +;; This version is compatible with Windows. +;; It does not call directly the nosetests script. Instead it calls +;; python with an inline script to call nose. +;; It can launch test suites (require to install the nose fixes via +;; `easy_install nose-fixes`). +;; It is also compatible with virtualenv. + +;; By default, the root of a project is found by looking for any of the files +;; '.projectile', 'setup.cfg', '.hg' and '.git'. You can add files to check for +;; to the file list: +;; +;; (add-to-list 'nose-project-root-files "something") + +;; or you can change the project root test to detect in some other way +;; whether a directory is the project root: +;; +;; (setq nose-project-root-test (lambda (dirname) (equal dirname "foo"))) + +;; If you want dots as output, rather than the verbose output: +;; +;; (defvar nose-use-verbose nil) ; default is t + +;; Probably also want some keybindings: +;; (add-hook 'python-mode-hook +;; (lambda () +;; (local-set-key "\C-ca" 'nosetests-all) +;; (local-set-key "\C-cm" 'nosetests-module) +;; (local-set-key "\C-c." 'nosetests-one) +;; (local-set-key "\C-cpa" 'nosetests-pdb-all) +;; (local-set-key "\C-cpm" 'nosetests-pdb-module) +;; (local-set-key "\C-cp." 'nosetests-pdb-one))) + +(require 'cl) ;; for "reduce" + +(defvar nose-project-root-files '(".projectile" + "setup.cfg" + ".hg" + ".git")) +(defvar nose-project-root-test 'nose-project-root) +(defvar nose-use-verbose t) + +(defun run-nose (&optional tests suite debug failed) + "run nosetests by calling python instead of nosetests script. +To be able to debug on Windows platform python output must be not buffered. +For more details: http://pswinkels.blogspot.ca/2010/04/debugging-python-code-from-within-emacs.html +" + (let* ((nose (nosetests-nose-command)) + (where (nose-find-project-root)) + (args (concat (if debug "--pdb" "") + " " + (if failed "--failed" "") + " " + (if suite "--test-suite-func=load_tests" ""))) + (tnames (if tests tests ""))) + (if (not where) + (error + (format (concat "abort: nosemacs couldn't find a project root, " + "looked for any of %S") nose-project-root-files))) + (funcall (if debug + 'pdb + '(lambda (command) + (compilation-start command + nil + (lambda (mode) (concat "*nosetests*"))))) + (format + (concat "%s " + (if nose-use-verbose "-v " "") + "%s -s -w \"%s\" -c \"%ssetup.cfg\" \"%s\"") + nose args where where tnames))) + ) + +(defun nosetests-nose-command () + (let ((nose "python -u -c \"import nose; nose.run()\"")) + (if python-shell-virtualenv-path + (format "%s/bin/%s" python-shell-virtualenv-path nose) + nose))) + +(defun nosetests-all (&optional debug failed) + "run all tests" + (interactive) + (run-nose nil nil debug failed)) + +(defun nosetests-failed (&optional debug) + (interactive) + (nosetests-all debug t)) + +(defun nosetests-pdb-all () + (interactive) + (nosetests-all t)) + +(defun nosetests-module (&optional debug) + "run nosetests (via eggs/bin/test) on current buffer" + (interactive) + (run-nose buffer-file-name nil debug)) + +(defun nosetests-pdb-module () + (interactive) + (nosetests-module t)) + +(defun nosetests-suite (&optional debug) + "run nosetests (via eggs/bin/test) on current suite buffer" + (interactive) + (run-nose buffer-file-name t debug)) + +(defun nosetests-pdb-suite () + (interactive) + (nosetests-suite t)) + +(defun nosetests-one (&optional debug) + "run nosetests (via eggs/bin/test) on testable thing + at point in current buffer" + (interactive) + (run-nose (format "%s:%s" buffer-file-name (nose-py-testable)) nil debug)) + +(defun nosetests-pdb-one () + (interactive) + (nosetests-one t)) + +(defun nose-py-testable () + (let* ((inner-obj (inner-testable)) + (outer (outer-testable)) + ;; elisp can't return multiple values + (outer-def (car outer)) + (outer-obj (cdr outer))) + (cond ((equal outer-def "def") outer-obj) + ((equal inner-obj outer-obj) outer-obj) + (t (format "%s.%s" outer-obj inner-obj))))) + +(defun inner-testable () + (save-excursion + (re-search-backward + "^ \\{0,4\\}\\(class\\|def\\)[ \t]+\\([a-zA-Z0-9_]+\\)" nil t) + (buffer-substring-no-properties (match-beginning 2) (match-end 2)))) + +(defun outer-testable () + (save-excursion + (re-search-backward + "^\\(class\\|def\\)[ \t]+\\([a-zA-Z0-9_]+\\)" nil t) + (let ((result + (buffer-substring-no-properties (match-beginning 2) (match-end 2)))) + + (cons + (buffer-substring-no-properties (match-beginning 1) (match-end 1)) + result)))) + +(defun nose-find-project-root (&optional dirname) + (let ((dn + (if dirname + dirname + (file-name-directory buffer-file-name)))) + (cond ((funcall nose-project-root-test dn) (expand-file-name dn)) + ((equal (expand-file-name dn) "/") nil) + (t (nose-find-project-root + (file-name-directory (directory-file-name dn))))))) + +(defun nose-project-root (dirname) + (reduce '(lambda (x y) (or x y)) + (mapcar (lambda (d) (member d (directory-files dirname))) + nose-project-root-files))) + +(provide 'nose) + +;;; nose.el ends here diff --git a/layers/+lang/python/local/pylookup/.gitignore b/layers/+lang/python/local/pylookup/.gitignore new file mode 100644 index 0000000..f614237 --- /dev/null +++ b/layers/+lang/python/local/pylookup/.gitignore @@ -0,0 +1,5 @@ +*~ +*.elc +/*.zip +*.db +python-*-docs-html diff --git a/layers/+lang/python/local/pylookup/README.md b/layers/+lang/python/local/pylookup/README.md new file mode 100644 index 0000000..9f90178 --- /dev/null +++ b/layers/+lang/python/local/pylookup/README.md @@ -0,0 +1,88 @@ +# Author + + Taesoo Kim (taesoo@mit.edu) + + Michael Markert (markert.michael@gmail.com) + Austin Bingham (austin.bingham@gmail.com) + Takafumi Arakaki + +# README + + Pylookup stole idea from 'http://furius.ca/haddoc', one of my favorite + emacs mode for python documentation lookup. I reimplemented python code and + elisp code not just to support new version of python 2.7 but also to extend + it for other documentation lookup interfaces with easy. Importantly, pylookup + mode is much faster and supports fancy highlighting. + + Please check, + Web : http://taesoo.org/proj/pylookup.html + Repo : https://github.com/tsgates/pylookup + +# INSTALL + +## Create database + + You can browse python documents from either online or offline. Since I prefer + offline, here is an easy step: + + make download + + It will download python document, and construct database for you. If you get in + any trouble, follow the below steps manually: + + 1. Download your own version of python document + (i.e. http://docs.python.org/archives/python-2.7.2-docs-html.zip) + 2. Unzip: 'unzip python-2.7.2-docs-html.zip' + 3. Index: './pylookup.py -u python-2.7.1-docs-html' + 4. Test : './pylookup.py -l ljust' + + (see updateing database section for more options) + +## Elisp + + Here is lisp part for emacs. + + - [PATH] parameter depends on your environment (i.e. "~/.emacs.d/pylookup") + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cl} +;; add pylookup to your loadpath, ex) ~/.emacs.d/pylookup +(setq pylookup-dir "[PATH]") +(add-to-list 'load-path pylookup-dir) + +;; load pylookup when compile time +(eval-when-compile (require 'pylookup)) + +;; set executable file and db file +(setq pylookup-program (concat pylookup-dir "/pylookup.py")) +(setq pylookup-db-file (concat pylookup-dir "/pylookup.db")) + +;; set search option if you want +;; (setq pylookup-search-options '("--insensitive" "0" "--desc" "0")) + +;; to speedup, just load it on demand +(autoload 'pylookup-lookup "pylookup" + "Lookup SEARCH-TERM in the Python HTML indexes." t) + +(autoload 'pylookup-update "pylookup" + "Run pylookup-update and create the database at `pylookup-db-file'." t) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Updating Databases + + You can easily accumulate many sources into single database. For example, you + can index python and scipy at the same time. Here are the examples: + + - Single source + ./pylookup.py -u http://docs.python.org + - Multiple sources, remote and local + ./pylookup.py -u http://docs.python.org -u ~/doc/python2.7 + - Adding local source to existing database (duplicate entries are not checked) + ./pylookup.py -a -u ~/doc/python + - Example online documents of python, scipy, numpy, and matplotlib + (you can append new indexes into the current db with '-a' option) + ./pylookup.py -u http://docs.python.org + ./pylookup.py -u http://docs.scipy.org/doc/numpy/genindex.html + ./pylookup.py -u http://docs.scipy.org/doc/scipy/reference/genindex.html + ./pylookup.py -u http://matplotlib.sourceforge.net/genindex.html + + You probably like to type './pylookup.py -h' to see more options. diff --git a/layers/+lang/python/local/pylookup/makefile b/layers/+lang/python/local/pylookup/makefile new file mode 100644 index 0000000..de7f495 --- /dev/null +++ b/layers/+lang/python/local/pylookup/makefile @@ -0,0 +1,19 @@ +VER := $(shell python --version 2>&1 | grep -o "[0-9].[0-9].[0-9]*") +MAJOR_VERSION = $(shell python --version 2>&1 | grep -o "Python [0-9]" | grep -o "[0-9]") +ZIP := python-${VER}-docs-html.zip +URL := https://docs.python.org/2/archives/${ZIP} +URL2:= https://docs.python.org/3/archives/${ZIP} + +ifneq (2,${MAJOR_VERSION}) + URL := ${URL2} +endif + +download: + @if [ ! -e ${ZIP} ] ; then \ + echo "Downloading ${URL}"; \ + wget ${URL}; \ + unzip ${ZIP}; \ + fi + ./pylookup.py -u $(ZIP:.zip=) + +.PHONY: download diff --git a/layers/+lang/python/local/pylookup/pylookup.el b/layers/+lang/python/local/pylookup/pylookup.el new file mode 100644 index 0000000..310e3dd --- /dev/null +++ b/layers/+lang/python/local/pylookup/pylookup.el @@ -0,0 +1,331 @@ +;;; pylookup.el --- Look up python documents (reference) in Emacs + +;; Copyright (C) 2010-2013 Taesoo Kim + +;; Author: Taesoo Kim +;; Maintainer: Taesoo Kim +;; Created: 19 June 2009 +;; Keywords: python,reference,document,help + +;; 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 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 this program. If not, see . + +;;; Code: + +(eval-when-compile + (require 'browse-url) + (require 'simple) + (require 'cl) + (require 'ido)) + +;;================================================================= +;; user options +;;================================================================= + +(defvar pylookup-db-file "pylookup.db" "Pylookup database file") +(defvar pylookup-program "pylookup.py" "Pylookup execution file") +(defvar pylookup-search-options nil + "Pylookup search options (see ./pylookup.py -h)") + +;;================================================================= +;; internal variables +;;================================================================= + +(defvar pylookup-html-locations '("http://docs.python.org")) +(defvar pylookup-history nil) +(defvar pylookup-cache nil) +(defvar pylookup-return-window-config nil) +(defvar pylookup-temp-buffer-name "*Pylookup Completions*") + +(defvar pylookup-mode-map + (let ((map (make-sparse-keymap))) + (define-key map [mouse-1] 'pylookup-mode-lookup-and-leave) + (define-key map [mouse-2] 'pylookup-mode-lookup) + (define-key map "\C-m" 'pylookup-mode-lookup-and-leave) + (define-key map " " 'pylookup-mode-lookup-and-leave) + (define-key map "f" 'pylookup-mode-lookup) + (define-key map "q" 'pylookup-mode-quit-window) + (define-key map "n" 'pylookup-mode-next-line) + (define-key map "j" 'pylookup-mode-next-line) + (define-key map "p" 'pylookup-move-prev-line) + (define-key map "k" 'pylookup-move-prev-line) + (define-key map "/" 'isearch-forward) + + (define-key map "v" 'scroll-down) + (define-key map "V" 'scroll-up) + (define-key map "l" 'recenter) + (define-key map "<" 'beginning-of-buffer) + (define-key map ">" 'end-of-buffer) + (define-key map "v" 'scroll-down) + + map) + "Keymap for `pylookup-mode-mode'.") + +(put 'pylookup-mode 'mode-class 'special) + +(defvar pylookup-completing-read + (if (null ido-mode) 'completing-read 'ido-completing-read) + "Ido support with convenience") + +;;================================================================= +;; pylookup mode specific interactive functions +;;================================================================= + +(defun pylookup-trim (desc n) + "Trim desc string to fit into the length, n" + + (if (> (length desc) (- n 2)) + (concat (substring desc 0 (- n 2)) "..") + desc)) + +(defun pylookup-mode () + "Major mode for output from \\[pylookup-lookup]." + (interactive) + + (kill-all-local-variables) + (use-local-map pylookup-mode-map) + (setq major-mode 'pylookup-mode) + (setq mode-name "Pylookup") + (setq buffer-read-only t) + (run-mode-hooks)) + +(defun pylookup-move-prev-line () + "Move to previous entry" + (interactive) + + (when (< 3 (line-number-at-pos)) + (call-interactively 'previous-line))) + +(defun pylookup-mode-next-line () + "Move to next entry" + (interactive) + + (when (< (line-number-at-pos) + (- (line-number-at-pos (point-max)) 1)) + (call-interactively 'next-line))) + +(defun pylookup-mode-lookup-and-leave () + "Lookup the current line in a browser and leave the completions window." + (interactive) + + (call-interactively 'pylookup-mode-lookup) + (pylookup-mode-quit-window)) + +(defun pylookup-mode-lookup () + "Lookup the current line in a browser." + (interactive) + + (let ((url (get-text-property (point) 'pylookup-target-url))) + (if url + (progn + (beginning-of-line) + (message "Browsing: \"%s\"" url) + (browse-url url)) + (error "No URL on this line")))) + +(defun pylookup-mode-quit-window () + "Leave the completions window." + (interactive) + + (set-window-configuration pylookup-return-window-config)) + +;;================================================================= +;; execute pylookup +;;================================================================= + +(defun pylookup-exec-get-cache () + "Run a pylookup process and get a list of cache (db key)" + + (split-string + (with-output-to-string + (call-process pylookup-program nil standard-output nil + "-d" (expand-file-name pylookup-db-file) + "-c")))) + +(defun pylookup-exec-lookup (search-term) + "Runs a pylookup process and returns a list of (term, url) pairs." + + (mapcar + (lambda (x) (split-string x ";")) + (split-string + (with-output-to-string + (apply 'call-process pylookup-program nil standard-output nil + "-d" (expand-file-name pylookup-db-file) + "-l" search-term + "-f" "Emacs" + pylookup-search-options)) + "\n" t))) + +;;================================================================= +;; interactive user interfaces +;;================================================================= + +;;;###autoload +(defun pylookup-lookup (search-term) + "Lookup SEARCH-TERM in the Python HTML indexes." + (interactive + (list + (let ((initial (thing-at-point 'word))) + (funcall pylookup-completing-read + "Search: " + (if pylookup-cache + pylookup-cache + (setq pylookup-cache (pylookup-exec-get-cache))) + nil nil initial 'pylookup-history)) + )) + + (let ((matches (pylookup-exec-lookup search-term))) + (cond + + ;; 0. No results. + ((eq matches nil) + (message "No matches for \"%s\"." search-term)) + + ;; 1. A single result. + ((= (length matches) 1) + ;; Point the browser at the unique result and get rid of the buffer + (let ((data (car matches))) + (message "Browsing: \"%s\"" (car data)) + (browse-url (cadr data)))) + + ;; N. Multiple results. + (t + ;; Decorate the temporary buffer lines with appropriate properties for + ;; selection. + (let* ((cur-window-conf (current-window-configuration)) + (tmpbuf (get-buffer-create pylookup-temp-buffer-name)) + (index 0)) + + (display-buffer tmpbuf) + (pop-to-buffer tmpbuf) + + (setq buffer-read-only nil) + (erase-buffer) + + ;; Insert the text in the buffer + (insert (format "Python index matches for %s:\n\n" search-term)) + (dolist (x matches) + ;; split like + ;; waitpid() (in module os) [lib] + ;; --------- -------------- ----- + ;; => + ;; waitpid (in module os) [lib] + ;; api module type + + (let* ((tokens (split-string (car x))) + (api (car tokens)) + (iter (cdr tokens)) + (type (car (last tokens))) + (module "")) + + (while (not (or (equal iter nil) + (string= (car iter) type))) + (setq module (concat module " " (car iter))) + (setq iter (cdr iter))) + + (incf index) + (insert (format " %03d) %-25s %-30s %10s" + index + (pylookup-trim api 25) + (pylookup-trim module 30) + (pylookup-trim type 10)))) + + (put-text-property + (line-beginning-position) (line-end-position) + 'pylookup-target-url (cadr x)) + (insert "\n")) + + ;; goto first entry + (goto-line 3) + + ;; turn mode on + (pylookup-mode) + + ;; highlighting + (font-lock-add-keywords nil `((,(format "\\(%s\\|%s\\|%s\\)" + search-term + (upcase search-term) + (upcase-initials search-term)) + 1 + font-lock-keyword-face prepend))) + + (font-lock-add-keywords nil '(("\\<\\(lib\\)" + 1 + font-lock-constant-face prepend))) + + (font-lock-add-keywords nil '(("\\<\\(in module.*)\\)" + 1 + font-lock-doc-face prepend))) + + ;; store window configuration + (set (make-local-variable 'pylookup-return-window-config) cur-window-conf) + + ;; make fit to screen + (shrink-window-if-larger-than-buffer (get-buffer-window tmpbuf))))))) + +;;;###autoload +(defun pylookup-set-search-option (option-string) + "Set search option interactively" + (interactive + (list (read-string "Search option: " + (mapconcat 'identity pylookup-search-options " ")))) + (setq pylookup-search-options (split-string option-string " "))) + +;;;###autoload +(defun pylookup-update (src &optional append) + "Run pylookup-update and create the database at `pylookup-db-file'." + (interactive + (list (funcall pylookup-completing-read + "Python Html Documentation source: " + pylookup-html-locations))) + + ;; pylookup.py -d /home/myuser/.pylookup/pylookup.db -l + (message (with-output-to-string + (call-process pylookup-program nil standard-output nil + "-u" src + "-d" (expand-file-name pylookup-db-file) + (if append + "-a" + ""))))) + +;;;###autoload +(defun pylookup-update-all () + "Run pylookup-update for all sources and create the database at `pylookup-db-file'." + (interactive) + ;; truncate db file + (with-temp-buffer (write-file pylookup-db-file)) + (mapc (lambda (s) (pylookup-update s t)) pylookup-html-locations)) + +;;;###autoload +(defun pylookup-lookup-at-point () + "Query the for string with help of word read at point and call `pylookup-lookup'" + (interactive) + (let* ((default-word (thing-at-point 'word)) + (default-prompt (concat "Lookup Word " + (if default-word + (concat "(" default-word ")") nil) + ": ")) + (pylookup-query + (funcall #'(lambda (str) + "Remove Whitespace from beginning and end of a string." + (replace-regexp-in-string "^[ \n\t]*\\(.*?\\)[ \n\t]*$" + "\\1" + str)) + (read-string default-prompt nil nil default-word)))) + (if (= (length pylookup-query) 0) nil + (pylookup-lookup pylookup-query)))) + +(provide 'pylookup) +;;; pylookup.el ends here diff --git a/layers/+lang/python/local/pylookup/pylookup.py b/layers/+lang/python/local/pylookup/pylookup.py new file mode 100755 index 0000000..9675a97 --- /dev/null +++ b/layers/+lang/python/local/pylookup/pylookup.py @@ -0,0 +1,329 @@ +#!/usr/bin/env python + +""" +Pylookup is to lookup entries from python documentation, especially within +emacs. Pylookup adopts most of ideas from haddoc, lovely toolkit by Martin +Blais. + +(usage) + ./pylookup.py -l ljust + ./pylookup.py -u http://docs.python.org + +""" + +from __future__ import with_statement + +import os +import sys +import re +try: + import cPickle as pickle +except: + import pickle +import formatter + +from os.path import join, dirname, exists, abspath, expanduser +from contextlib import closing + +if sys.version_info[0] == 3: + import html.parser as htmllib + import urllib.parse as urlparse + import urllib.request as urllib +else: + import htmllib, urllib, urlparse + +VERBOSE = False +FORMATS = { + "Emacs" : "{entry}\t({desc})\t[{book}];{url}", + "Terminal" : "{entry}\t({desc})\t[{book}]\n{url}" + } + +def build_book(s, num): + """ + Build book identifier from `s`, with `num` links. + """ + for matcher, replacement in (("library", "lib"), + ("c-api", "api"), + ("reference", "ref"), + ("", "etc")): + if matcher in s: + return replacement if num == 1 else "%s/%d" % (replacement, num) + +def trim(s): + """ + Add any globle filtering rules here + """ + s = s.replace( "Python Enhancement Proposals!", "") + s = s.replace( "PEP ", "PEP-") + return s + +class Element(object): + def __init__(self, entry, desc, book, url): + self.book = book + self.url = url + self.desc = desc + self.entry = entry + + def __format__(self, format_spec): + return format_spec.format(entry=self.entry, desc=self.desc, + book=self.book, url=self.url) + + def match_insensitive(self, key): + """ + Match key case insensitive against entry and desc. + + `key` : Lowercase string. + """ + return key in self.entry.lower() or key in self.desc.lower() + + def match_sensitive(self, key): + """ + Match key case sensitive against entry and desc. + + `key` : Lowercase string. + """ + return key in self.entry or key in self.desc + + def match_in_entry_insensitive(self, key): + """ + Match key case insensitive against entry. + + `key` : Lowercase string. + """ + return key in self.entry.lower() + + def match_in_entry_sensitive(self, key): + """ + Match key case sensitive against entry. + + `key` : Lowercase string. + """ + return key in self.entry + + +def get_matcher(insensitive=True, desc=True): + """ + Get `Element.match_*` function. + + >>> get_matcher(0, 0) + + >>> get_matcher(1, 0) + + >>> get_matcher(0, 1) + + >>> get_matcher(1, 1) + + + """ + _sensitive = "_insensitive" if insensitive else "_sensitive" + _in_entry = "" if desc else "_in_entry" + return getattr(Element, "match{0}{1}".format(_in_entry, _sensitive)) + + +class IndexProcessor( htmllib.HTMLParser ): + """ + Extract the index links from a Python HTML documentation index. + """ + + def __init__( self, writer, dirn): + htmllib.HTMLParser.__init__( self, formatter.NullFormatter() ) + + self.writer = writer + self.dirn = dirn + self.entry = "" + self.desc = "" + self.list_entry = False + self.do_entry = False + self.one_entry = False + self.num_of_a = 0 + self.desc_cnt = 0 + + def start_dd( self, att ): + self.list_entry = True + + def end_dd( self ): + self.list_entry = False + + def start_dt( self, att ): + self.one_entry = True + self.num_of_a = 0 + + def end_dt( self ): + self.do_entry = False + + def start_a( self, att ): + if self.one_entry: + self.url = join( self.dirn, dict( att )[ 'href' ] ) + self.save_bgn() + + def end_a( self ): + global VERBOSE + if self.one_entry: + if self.num_of_a == 0 : + self.desc = self.save_end() + + if VERBOSE: + self.desc_cnt += 1 + if self.desc_cnt % 100 == 0: + sys.stdout.write("%04d %s\r" \ + % (self.desc_cnt, self.desc.ljust(80))) + + # extract fist element + # ex) __and__() (in module operator) + if not self.list_entry : + self.entry = re.sub( "\([^)]+\)", "", self.desc ) + + # clean up PEP + self.entry = trim(self.entry) + + match = re.search( "\([^)]+\)", self.desc ) + if match : + self.desc = match.group(0) + + self.desc = trim(re.sub( "[()]", "", self.desc )) + + self.num_of_a += 1 + book = build_book(self.url, self.num_of_a) + e = Element(self.entry, self.desc, book, self.url) + + self.writer(e) + +def update(db, urls, append=False): + """Update database with entries from urls. + + `db` : filename to database + `urls` : list of URL + `append` : append to db + """ + mode = "ab" if append else "wb" + with open(db, mode) as f: + writer = lambda e: pickle.dump(e, f) + for url in urls: + # detech 'file' or 'url' schemes + parsed = urlparse.urlparse(url) + if not parsed.scheme or parsed.scheme == "file": + dst = abspath(expanduser(parsed.path)) + if not os.path.exists(dst): + print("Error: %s doesn't exist" % dst) + exit(1) + url = "file://%s" % dst + else: + url = parsed.geturl() + + potential_urls = [] + if url.endswith('.html'): + potential_urls.append(url) + else: + # guess index URLs + # for stdlib, this is genindex-all.html + # for django, numpy, etc. it's genindex.html + url = url.rstrip("/") + potential_urls.append(url + "/genindex-all.html") + potential_urls.append(url + "/genindex.html") + + success = False + for index_url in potential_urls: + try: + print("Wait for a few seconds...") + print("Fetching index from '%s'" % index_url) + + index = urllib.urlopen(index_url).read() + if not issubclass(type(index), str): + index = index.decode() + + parser = IndexProcessor(writer, dirname(index_url)) + with closing(parser): + parser.feed(index) + + # success, we don't need to try other potential urls + print("Loaded index from '%s'" % index_url) + success = True + break + except IOError: + print("Error: fetching file from '%s'" % index_url) + + if not success: + print("Failed to load index for input '%s'" % url) + + +def lookup(db, key, format_spec, out=sys.stdout, insensitive=True, desc=True): + """Lookup key from database and print to out. + + `db` : filename to database + `key` : key to lookup + `out` : file-like to write to + `insensitive` : lookup key case insensitive + """ + matcher = get_matcher(insensitive, desc) + if insensitive: + key = key.lower() + with open(db, "rb") as f: + try: + while True: + e = pickle.load(f) + if matcher(e, key): + out.write('%s\n' % format(e, format_spec)) + except EOFError: + pass + +def cache(db, out=sys.stdout): + """Print unique entries from db to out. + + `db` : filename to database + `out` : file-like to write to + """ + with open(db, "rb") as f: + keys = set() + try: + while True: + e = pickle.load(f) + k = e.entry + k = re.sub( "\([^)]*\)", "", k ) + k = re.sub( "\[[^]]*\]", "", k ) + keys.add(k) + except EOFError: + pass + for k in keys: + out.write('%s\n' % k) + +if __name__ == "__main__": + import optparse + parser = optparse.OptionParser( __doc__.strip() ) + parser.add_option( "-d", "--db", + help="database name", + dest="db", default="pylookup.db" ) + parser.add_option( "-l", "--lookup", + help="keyword to search", + dest="key" ) + parser.add_option( "-u", "--update", + help="update url or path", + action="append", type="str", dest="url" ) + parser.add_option( "-c", "--cache" , + help="extract keywords, internally used", + action="store_true", default=False, dest="cache") + parser.add_option( "-a", "--append", + help="append to the db from multiple sources", + action="store_true", default=False, dest="append") + parser.add_option( "-f", "--format", + help="type of output formatting, valid: Emacs, Terminal", + choices=["Emacs", "Terminal"], + default="Terminal", dest="format") + parser.add_option( "-i", "--insensitive", default=1, choices=['0', '1'], + help="SEARCH OPTION: insensitive search " + "(valid: 0, 1; default: %default)") + parser.add_option( "-s", "--desc", default=1, choices=['0', '1'], + help="SEARCH OPTION: include description field " + "(valid: 0, 1; default: %default)") + parser.add_option("-v", "--verbose", + help="verbose", action="store_true", + dest="verbose", default=False) + ( opts, args ) = parser.parse_args() + + VERBOSE = opts.verbose + if opts.url: + update(opts.db, opts.url, opts.append) + if opts.cache: + cache(opts.db) + if opts.key: + lookup(opts.db, opts.key, FORMATS[opts.format], + insensitive=int(opts.insensitive), desc=int(opts.desc)) diff --git a/layers/+lang/python/packages.el b/layers/+lang/python/packages.el new file mode 100644 index 0000000..f134cb0 --- /dev/null +++ b/layers/+lang/python/packages.el @@ -0,0 +1,448 @@ +;;; packages.el --- Python Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq python-packages + '( + anaconda-mode + company + (company-anaconda :toggle (configuration-layer/package-usedp 'company)) + cython-mode + eldoc + evil-matchit + flycheck + ggtags + helm-cscope + helm-gtags + (helm-pydoc :toggle (configuration-layer/package-usedp 'helm)) + hy-mode + live-py-mode + (nose :location local) + org + pip-requirements + py-isort + pyenv-mode + (pylookup :location local) + pytest + (python :location built-in) + pyvenv + semantic + smartparens + stickyfunc-enhance + xcscope + yapfify + )) + +(defun python/init-anaconda-mode () + (use-package anaconda-mode + :defer t + :init + (progn + (setq anaconda-mode-installation-directory + (concat spacemacs-cache-directory "anaconda-mode")) + (add-hook 'python-mode-hook 'anaconda-mode) + (add-to-list 'spacemacs-jump-handlers-python-mode + '(anaconda-mode-find-definitions :async t))) + :config + (progn + (spacemacs/set-leader-keys-for-major-mode 'python-mode + "hh" 'anaconda-mode-show-doc + "ga" 'anaconda-mode-find-assignments + "gb" 'anaconda-mode-go-back + "gu" 'anaconda-mode-find-references) + (evilified-state-evilify anaconda-mode-view-mode anaconda-mode-view-mode-map + (kbd "q") 'quit-window) + (spacemacs|hide-lighter anaconda-mode) + + (defadvice anaconda-mode-goto (before python/anaconda-mode-goto activate) + (evil--jumps-push))))) + +(defun python/post-init-company () + (spacemacs|add-company-hook python-mode) + (spacemacs|add-company-hook inferior-python-mode) + (push '(company-files company-capf) company-backends-inferior-python-mode) + (add-hook 'inferior-python-mode-hook (lambda () + (setq-local company-minimum-prefix-length 0) + (setq-local company-idle-delay 0.5)))) + +(defun python/init-company-anaconda () + (use-package company-anaconda + :defer t + :init + (push 'company-anaconda company-backends-python-mode))) + +(defun python/init-cython-mode () + (use-package cython-mode + :defer t + :init + (progn + (spacemacs/set-leader-keys-for-major-mode 'cython-mode + "hh" 'anaconda-mode-view-doc + "gu" 'anaconda-mode-usages)))) + +(defun python/post-init-eldoc () + (defun spacemacs//init-eldoc-python-mode () + (eldoc-mode) + (when (configuration-layer/package-usedp 'anaconda-mode) + (anaconda-eldoc-mode))) + (add-hook 'python-mode-hook 'spacemacs//init-eldoc-python-mode)) + +(defun python/post-init-evil-matchit () + (add-hook `python-mode-hook `turn-on-evil-matchit-mode)) + +(defun python/post-init-flycheck () + (spacemacs/add-flycheck-hook 'python-mode)) + +(defun python/pre-init-helm-cscope () + (spacemacs|use-package-add-hook xcscope + :post-init + (spacemacs/setup-helm-cscope 'python-mode))) + +(defun python/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'python-mode)) + +(defun python/post-init-ggtags () + (add-hook 'python-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun python/init-helm-pydoc () + (use-package helm-pydoc + :defer t + :init + (spacemacs/set-leader-keys-for-major-mode 'python-mode "hd" 'helm-pydoc))) + +(defun python/init-hy-mode () + (use-package hy-mode + :defer t + :init + (progn + (let ((hy-path (executable-find "hy"))) + (when hy-path + (setq hy-mode-inferior-lisp-command (concat hy-path " --spy")) + (spacemacs/set-leader-keys-for-major-mode 'hy-mode + "si" 'inferior-lisp + "sb" 'lisp-load-file + "sB" 'switch-to-lisp + "se" 'lisp-eval-last-sexp + "sf" 'lisp-eval-defun + "sF" 'lisp-eval-defun-and-go + "sr" 'lisp-eval-region + "sR" 'lisp-eval-region-and-go)))))) + +(defun python/init-live-py-mode () + (use-package live-py-mode + :defer t + :commands live-py-mode + :init + (spacemacs/set-leader-keys-for-major-mode 'python-mode + "l" 'live-py-mode))) + +(defun python/init-nose () + (use-package nose + :if (or (eq 'nose python-test-runner) + (if (listp python-test-runner) (member 'nose python-test-runner))) + :commands (nosetests-one + nosetests-pdb-one + nosetests-all + nosetests-pdb-all + nosetests-module + nosetests-pdb-module + nosetests-suite + nosetests-pdb-suite) + :init + (progn + (spacemacs//bind-python-testing-keys) + (spacemacs/set-leader-keys-for-major-mode 'python-mode + "tS" 'nosetests-pdb-suite + "ts" 'nosetests-suite)) + :config + (progn + (add-to-list 'nose-project-root-files "setup.cfg") + (setq nose-use-verbose nil)))) + +(defun python/pre-init-org () + (spacemacs|use-package-add-hook org + :post-config (add-to-list 'org-babel-load-languages '(python . t)))) + +(defun python/init-pip-requirements () + (use-package pip-requirements + :defer t + :init + (progn + ;; company support + (push 'company-capf company-backends-pip-requirements-mode) + (spacemacs|add-company-hook pip-requirements-mode)))) + +(defun python/init-py-isort () + (use-package py-isort + :defer t + :init + (progn + (add-hook 'before-save-hook 'spacemacs//python-sort-imports) + (spacemacs/set-leader-keys-for-major-mode 'python-mode + "rI" 'py-isort-buffer)))) + +(defun python/init-pyenv-mode () + (use-package pyenv-mode + :if (executable-find "pyenv") + :commands (pyenv-mode-versions) + :init + (progn + (pcase python-auto-set-local-pyenv-version + (`on-visit + (spacemacs/add-to-hooks 'spacemacs//pyenv-mode-set-local-version + '(python-mode-hook + hy-mode-hook))) + (`on-project-switch + (add-hook 'projectile-after-switch-project-hook + 'spacemacs//pyenv-mode-set-local-version))) + ;; setup shell correctly on environment switch + (dolist (func '(pyenv-mode-set pyenv-mode-unset)) + (advice-add func :after 'spacemacs/python-setup-shell)) + (spacemacs/set-leader-keys-for-major-mode 'python-mode + "vu" 'pyenv-mode-unset + "vs" 'pyenv-mode-set)))) + +(defun python/init-pyvenv () + (use-package pyvenv + :defer t + :init + (progn + (dolist (mode '(python-mode hy-mode)) + (spacemacs/set-leader-keys-for-major-mode mode + "Va" 'pyvenv-activate + "Vd" 'pyvenv-deactivate + "Vw" 'pyvenv-workon)) + ;; setup shell correctly on environment switch + (dolist (func '(pyvenv-activate pyvenv-deactivate pyvenv-workon)) + (advice-add func :after 'spacemacs/python-setup-shell))))) + +(defun python/init-pylookup () + (use-package pylookup + :commands (pylookup-lookup pylookup-update pylookup-update-all) + :init + (progn + (evilified-state-evilify pylookup-mode pylookup-mode-map) + (spacemacs/set-leader-keys-for-major-mode 'python-mode + "hH" 'pylookup-lookup)) + :config + (progn + (let ((dir (configuration-layer/get-layer-local-dir 'python))) + (setq pylookup-dir (concat dir "pylookup/") + pylookup-program (concat pylookup-dir "pylookup.py") + pylookup-db-file (concat pylookup-dir "pylookup.db"))) + (setq pylookup-completing-read 'completing-read)))) + +(defun python/init-pytest () + (use-package pytest + :if (or (eq 'pytest python-test-runner) + (if (listp python-test-runner) (member 'pytest python-test-runner))) + :defer t + :commands (pytest-one + pytest-pdb-one + pytest-all + pytest-pdb-all + pytest-module + pytest-pdb-module) + :init (spacemacs//bind-python-testing-keys) + :config (add-to-list 'pytest-project-root-files "setup.cfg"))) + +(defun python/init-python () + (use-package python + :defer t + :init + (progn + (spacemacs/register-repl 'python 'python-start-or-switch-repl "python") + + (defun python-default () + (setq mode-name "Python" + tab-width python-tab-width + fill-column python-fill-column) + (when (version< emacs-version "24.5") + ;; auto-indent on colon doesn't work well with if statement + ;; should be fixed in 24.5 and above + (setq electric-indent-chars (delq ?: electric-indent-chars))) + (setq-local comment-inline-offset 2) + (spacemacs/python-annotate-pdb) + ;; make C-j work the same way as RET + (local-set-key (kbd "C-j") 'newline-and-indent)) + + + (defun inferior-python-setup-hook () + (setq indent-tabs-mode t)) + + (add-hook 'inferior-python-mode-hook #'inferior-python-setup-hook) + (add-hook 'python-mode-hook #'python-default) + ;; call `spacemacs/python-setup-shell' once, don't put it in a hook (see issue #5988) + (spacemacs/python-setup-shell)) + :config + (progn + ;; add support for `ahs-range-beginning-of-defun' for python-mode + (with-eval-after-load 'auto-highlight-symbol + (add-to-list 'ahs-plugin-bod-modes 'python-mode)) + + (defun python-shell-send-buffer-switch () + "Send buffer content to shell and switch to it in insert mode." + (interactive) + (python-shell-send-buffer) + (python-shell-switch-to-shell) + (evil-insert-state)) + + (defun python-shell-send-defun-switch () + "Send function content to shell and switch to it in insert mode." + (interactive) + (python-shell-send-defun nil) + (python-shell-switch-to-shell) + (evil-insert-state)) + + (defun python-shell-send-region-switch (start end) + "Send region content to shell and switch to it in insert mode." + (interactive "r") + (python-shell-send-region start end) + (python-shell-switch-to-shell) + (evil-insert-state)) + + (defun python-start-or-switch-repl () + "Start and/or switch to the REPL." + (interactive) + (let ((shell-process + (or (python-shell-get-process) + ;; `run-python' has different return values and different + ;; errors in different emacs versions. In 24.4, it throws an + ;; error when the process didn't start, but in 25.1 it + ;; doesn't throw an error, so we demote errors here and + ;; check the process later + (with-demoted-errors "Error: %S" + ;; in Emacs 24.5 and 24.4, `run-python' doesn't return the + ;; shell process + (call-interactively #'run-python) + (python-shell-get-process))))) + (unless shell-process + (error "Failed to start python shell properly")) + (pop-to-buffer (process-buffer shell-process)) + (evil-insert-state))) + + (defun spacemacs/python-execute-file (arg) + "Execute a python script in a shell." + (interactive "P") + ;; set compile command to buffer-file-name + ;; universal argument put compile buffer in comint mode + (let ((universal-argument t) + (compile-command (format "python %s" (file-name-nondirectory + buffer-file-name)))) + (if arg + (call-interactively 'compile) + (compile compile-command t) + (with-current-buffer (get-buffer "*compilation*") + (inferior-python-mode))))) + + (defun spacemacs/python-execute-file-focus (arg) + "Execute a python script in a shell and switch to the shell buffer in +`insert state'." + (interactive "P") + (spacemacs/python-execute-file arg) + (switch-to-buffer-other-window "*compilation*") + (end-of-buffer) + (evil-insert-state)) + + ;; fix for issue #2569 (https://github.com/syl20bnr/spacemacs/issues/2569) + (when (version< emacs-version "25") + (advice-add 'wisent-python-default-setup :after + #'spacemacs//python-imenu-create-index-use-semantic-maybe)) + + (spacemacs/declare-prefix-for-mode 'python-mode "mc" "execute") + (spacemacs/declare-prefix-for-mode 'python-mode "md" "debug") + (spacemacs/declare-prefix-for-mode 'python-mode "mh" "help") + (spacemacs/declare-prefix-for-mode 'python-mode "mg" "goto") + (spacemacs/declare-prefix-for-mode 'python-mode "ms" "send to REPL") + (spacemacs/declare-prefix-for-mode 'python-mode "mr" "refactor") + (spacemacs/declare-prefix-for-mode 'python-mode "mv" "pyenv") + (spacemacs/declare-prefix-for-mode 'python-mode "mV" "pyvenv") + (spacemacs/set-leader-keys-for-major-mode 'python-mode + "'" 'python-start-or-switch-repl + "cc" 'spacemacs/python-execute-file + "cC" 'spacemacs/python-execute-file-focus + "db" 'spacemacs/python-toggle-breakpoint + "ri" 'spacemacs/python-remove-unused-imports + "sB" 'python-shell-send-buffer-switch + "sb" 'python-shell-send-buffer + "sF" 'python-shell-send-defun-switch + "sf" 'python-shell-send-defun + "si" 'python-start-or-switch-repl + "sR" 'python-shell-send-region-switch + "sr" 'python-shell-send-region) + + ;; Emacs users won't need these key bindings + ;; TODO: make these key bindings dynamic given the current style + ;; Doing it only at init time won't update it if the user switches style + ;; Also find a way to generalize these bindings. + (when (eq dotspacemacs-editing-style 'vim) + ;; the default in Emacs is M-n + (define-key inferior-python-mode-map (kbd "C-j") 'comint-next-input) + ;; the default in Emacs is M-p and this key binding overrides + ;; default C-k which prevents Emacs users to kill line + (define-key inferior-python-mode-map (kbd "C-k") 'comint-previous-input) + ;; the default in Emacs is M-r; C-r to search backward old output + ;; and should not be changed + (define-key inferior-python-mode-map + (kbd "C-r") 'comint-history-isearch-backward) + ;; this key binding is for recentering buffer in Emacs + ;; it would be troublesome if Emacs user + ;; Vim users can use this key since they have other key + (define-key inferior-python-mode-map + (kbd "C-l") 'spacemacs/comint-clear-buffer)) + + ;; add this optional key binding for Emacs user, since it is unbound + (define-key inferior-python-mode-map + (kbd "C-c M-l") 'spacemacs/comint-clear-buffer)))) + +(defun python/post-init-semantic () + (when (configuration-layer/package-usedp 'anaconda-mode) + (add-hook 'python-mode-hook + 'spacemacs//disable-semantic-idle-summary-mode t)) + (spacemacs/add-to-hook 'python-mode-hook + '(semantic-mode + spacemacs//python-imenu-create-index-use-semantic-maybe)) + (defadvice semantic-python-get-system-include-path + (around semantic-python-skip-error-advice activate) + "Don't cause error when Semantic cannot retrieve include +paths for Python then prevent the buffer to be switched. This +issue might be fixed in Emacs 25. Until then, we need it here to +fix this issue." + (condition-case-unless-debug nil + ad-do-it + (error nil)))) + +(defun python/post-init-smartparens () + (spacemacs/add-to-hooks 'smartparens-mode '(inferior-python-mode-hook + hy-mode-hook)) + (defadvice python-indent-dedent-line-backspace + (around python/sp-backward-delete-char activate) + (let ((pythonp (or (not smartparens-strict-mode) + (char-equal (char-before) ?\s)))) + (if pythonp + ad-do-it + (call-interactively 'sp-backward-delete-char))))) + +(defun python/post-init-stickyfunc-enhance () + (add-hook 'python-mode-hook 'spacemacs/lazy-load-stickyfunc-enhance)) + +(defun python/pre-init-xcscope () + (spacemacs|use-package-add-hook xcscope + :post-init + (spacemacs/set-leader-keys-for-major-mode 'python-mode + "gi" 'cscope/run-pycscope))) + +(defun python/init-yapfify () + (use-package yapfify + :defer t + :init (spacemacs/set-leader-keys-for-major-mode 'python-mode + "=" 'yapfify-buffer) + :config (when python-enable-yapf-format-on-save + (add-hook 'python-mode-hook 'yapf-mode)))) diff --git a/layers/+lang/racket/README.org b/layers/+lang/racket/README.org new file mode 100644 index 0000000..f2772db --- /dev/null +++ b/layers/+lang/racket/README.org @@ -0,0 +1,74 @@ +#+TITLE: Racket layer + +[[file:img/racket.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key Bindings]] + - [[#navigation][Navigation]] + - [[#documentation][Documentation]] + - [[#tests][Tests]] + - [[#repl][REPL]] + - [[#other-key-bindings][Other key bindings]] + +* Description + +Adds support for the [[http://racket-lang.org/][Racket]] programming language. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =racket= to the existing =dotspacemacs-configuration-layers= list in this +file. You will also need DrRacket installed. Alternatively, one can use the +"Minimal Racket" installation, and then run the following command. + +#+BEGIN_SRC Bash +raco pkg install drracket +#+END_SRC + +* Key Bindings + +** Navigation + +| Key Binding | Description | +|-------------+-------------------------------------| +| ~SPC m g `~ | Return to previous location | +| ~SPC m g g~ | Go to definition of symbol at point | +| ~SPC m g m~ | Go to module at point | +| ~SPC m g r~ | Open require path | + +** Documentation + +| Key Binding | Description | +|-------------+---------------------------------------------------------------| +| ~SPC m h d~ | Describes the function at point in a =Racket Describe= buffer | +| ~SPC m h h~ | View documentation of the identifier or string at point. | + +** Tests + +| Key Binding | Description | +|-------------+-----------------------------------| +| ~SPC m t b~ | Run tests of buffer | +| ~SPC m t B~ | Run tests of buffer with coverage | + +** REPL + +| Key Binding | Description | +|-------------+-----------------------------------------------------------------| +| ~SPC m s b~ | Send buffer to REPL | +| ~SPC m s B~ | Send buffer to REPL and switch to REPL buffer in =insert state= | +| ~SPC m s e~ | Send last sexp to REPL | +| ~SPC m s E~ | Send last sexp to REPL and switch to REPL in =insert state= | +| ~SPC m s f~ | Send function at point to REPL | +| ~SPC m s F~ | Send function at point and switch to REPL in =insert state= | +| ~SPC m s i~ | Start a REPL or switch to REPL buffer | +| ~SPC m s r~ | Send region to REPL | +| ~SPC m s R~ | Send region to REPL and switch to REPL in =insert state= | +| ~SPC m s s~ | Show and switch to REPL buffer | + +** Other key bindings + +| Key Binding | Description | +|-------------+---------------------------------------------------------------------------------| +| ~SPC m i l~ | Insert lambda character | +| ~H-r~ | Run current file and open REPL (=H= is hyper, *may* be bound to command on OSX) | diff --git a/layers/+lang/racket/config.el b/layers/+lang/racket/config.el new file mode 100644 index 0000000..3b3b7b4 --- /dev/null +++ b/layers/+lang/racket/config.el @@ -0,0 +1,14 @@ +;;; config.el --- Racket Layer Configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; variables + +(spacemacs|define-jump-handlers racket-mode racket-visit-definition) diff --git a/layers/+lang/racket/img/racket.png b/layers/+lang/racket/img/racket.png new file mode 100644 index 0000000..2ddee2d Binary files /dev/null and b/layers/+lang/racket/img/racket.png differ diff --git a/layers/+lang/racket/packages.el b/layers/+lang/racket/packages.el new file mode 100644 index 0000000..e071da2 --- /dev/null +++ b/layers/+lang/racket/packages.el @@ -0,0 +1,119 @@ +(setq racket-packages + '( + company + company-quickhelp + ggtags + helm-gtags + racket-mode + )) + +(defun racket/post-init-company () + ;; this is the only thing to do to enable company in racket-mode + ;; because racket-mode handle everything for us when company + ;; is loaded. + (add-hook 'racket-mode-hook 'company-mode)) + +(defun racket/post-init-company-quickhelp () + ;; Bug exists in Racket company backend that opens docs in new window when + ;; company-quickhelp calls it. Note hook is appendended for proper ordering. + (add-hook 'company-mode-hook + '(lambda () + (when (and (equal major-mode 'racket-mode) + (bound-and-true-p company-quickhelp-mode)) + (company-quickhelp-mode -1))) t)) + +(defun racket/post-init-ggtags () + (add-hook 'racket-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun racket/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'racket-mode)) + +(defun racket/init-racket-mode () + (use-package racket-mode + :defer t + :init + (progn + (spacemacs/register-repl 'racket-mode 'racket-repl "racket")) + :config + (progn + ;; smartparens configuration + (with-eval-after-load 'smartparens + (add-to-list 'sp--lisp-modes 'racket-mode) + (when (fboundp 'sp-local-pair) + (sp-local-pair 'racket-mode "'" nil :actions nil) + (sp-local-pair 'racket-mode "`" nil :actions nil))) + + (defun spacemacs/racket-test-with-coverage () + "Call `racket-test' with universal argument." + (interactive) + (racket-test t)) + + (defun spacemacs/racket-run-and-switch-to-repl () + "Call `racket-run-and-switch-to-repl' and enable +`insert state'." + (interactive) + (racket-run-and-switch-to-repl) + (evil-insert-state)) + + (defun spacemacs/racket-send-last-sexp-focus () + "Call `racket-send-last-sexp' and switch to REPL buffer in +`insert state'." + (interactive) + (racket-send-last-sexp) + (racket-repl) + (evil-insert-state)) + + (defun spacemacs/racket-send-definition-focus () + "Call `racket-send-definition' and switch to REPL buffer in +`insert state'." + (interactive) + (racket-send-definition) + (racket-repl) + (evil-insert-state)) + + (defun spacemacs/racket-send-region-focus (start end) + "Call `racket-send-region' and switch to REPL buffer in +`insert state'." + (interactive "r") + (racket-send-region start end) + (racket-repl) + (evil-insert-state)) + + (dolist (prefix '(("mg" . "navigation") + ("mh" . "doc") + ("mi" . "insert") + ("ms" . "repl") + ("mt" . "tests"))) + (spacemacs/declare-prefix-for-mode 'racket-mode (car prefix) (cdr prefix))) + + (spacemacs/set-leader-keys-for-major-mode 'racket-mode + ;; navigation + "g`" 'racket-unvisit + "gm" 'racket-visit-module + "gr" 'racket-open-require-path + ;; doc + "hd" 'racket-describe + "hh" 'racket-doc + ;; insert + "il" 'racket-insert-lambda + ;; REPL + "'" 'racket-repl + "sb" 'racket-run + "sB" 'spacemacs/racket-run-and-switch-to-repl + "se" 'racket-send-last-sexp + "sE" 'spacemacs/racket-send-last-sexp-focus + "sf" 'racket-send-definition + "sF" 'spacemacs/racket-send-definition-focus + "si" 'racket-repl + "sr" 'racket-send-region + "sR" 'spacemacs/racket-send-region-focus + "ss" 'racket-repl + ;; Tests + "tb" 'racket-test + "tB" 'spacemacs/racket-test-with-coverage) + (define-key racket-mode-map (kbd "H-r") 'racket-run) + ;; remove racket auto-insert of closing delimiter + ;; see https://github.com/greghendershott/racket-mode/issues/140 + (define-key racket-mode-map ")" 'self-insert-command) + (define-key racket-mode-map "]" 'self-insert-command) + (define-key racket-mode-map "}" 'self-insert-command)))) diff --git a/layers/+lang/ruby/README.org b/layers/+lang/ruby/README.org new file mode 100644 index 0000000..d1a3b39 --- /dev/null +++ b/layers/+lang/ruby/README.org @@ -0,0 +1,186 @@ +#+TITLE: Ruby layer + +[[file:img/ruby.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#prerequisites][Prerequisites]] + - [[#ruby-version-management][Ruby version management]] + - [[#test-runner][Test runner]] + - [[#key-bindings][Key bindings]] + - [[#ruby-enh-ruby-mode-robe-inf-ruby-ruby-tools][Ruby (enh-ruby-mode, robe, inf-ruby, ruby-tools)]] + - [[#bundler][Bundler]] + - [[#rubocop][RuboCop]] + - [[#tests][Tests]] + - [[#rspec-mode][RSpec-mode]] + - [[#ruby-test-mode][Ruby-test-mode]] + - [[#minitest-mode][minitest-mode]] + - [[#rake][Rake]] + +* Description +This layer provides support for the Ruby language with the following features: +- version manager (rbenv, rvm or chruby) +- integration with bundler +- test runner (ruby-test and rspec) +- rake runner +- linter (rubocop) +- interactive REPL and code navigation (robe) + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =ruby= to the existing =dotspacemacs-configuration-layers= list in this +file. + +This layer supports two different Ruby modes: Emacs' built-in Ruby Mode and +[[https://github.com/zenspider/enhanced-ruby-mode][enh-ruby-mode]]. By default the built-in Ruby mode is enabled. To switch to the +=enh-ruby-mode= set =ruby-enable-enh-ruby-mode= to t: + +#+BEGIN_SRC emacs-lisp + (defun dotspacemacs-configuration-layers () + '((ruby :variables ruby-enable-enh-ruby-mode t))) +#+END_SRC + +** Prerequisites +Some of the advanced features supported by this layer depend on external gems +that need to be installed in the context of your project (see below for guidance +based on your version manager): + +- =pry= and =pry-doc= are required for *jump to definition* and *code documentation* (=robe-mode=) +- =ruby_parser= is required for *goto-step_definition* in =feature-mode= +- =rubocop= is required for rubocop integration + +You can install the gems in the context of your current project by +adding them to the =Gemfile=, e.g.: + +#+BEGIN_SRC ruby + gem 'pry' +#+END_SRC + +or on the command line (please refer to your ruby version manager +specific documentation for details and caveats): + +#+BEGIN_SRC sh + gem install pry +#+END_SRC + +** Ruby version management +This layer supports [[https://rvm.io/][RVM]], [[https://github.com/sstephenson/rbenv][Rbenv]], and [[https://github.com/postmodern/chruby][Chruby]]. You can choose the default version +manager by setting the variable =ruby-version-manager= in your dotfile, for +example: + +#+BEGIN_SRC emacs-lisp + (defun dotspacemacs-configuration-layers () + '((ruby :variables ruby-version-manager 'rvm))) +#+END_SRC + +When a version manager is enabled it will use the currently activated ruby +except if a =.ruby-version= file exists in which case the ruby version of +this file is used. +=rvm= will also try to look for a =.rvmrc= and =gemfile=, the priority order is +=.rvmrc= then =.ruby-version= then =gemfile=. + +Note: Only one version manager at a time can be enabled. + +** Test runner +This layer supports =RSpec=, =ruby-test= and =minitest= test runners +(frameworks). By default =ruby-test= is used, to change to another frameworks +set the layer variable =ruby-test-runner=. + +Example to set the test runner to =RSpec=: + +#+BEGIN_SRC emacs-lisp + (defun dotspacemacs-configuration-layers () + '((ruby :variables ruby-test-runner 'rspec))) +#+END_SRC + +=Tip:= You can enable different test runners for different projects by using +directory local variables. + +* Key bindings +** Ruby (enh-ruby-mode, robe, inf-ruby, ruby-tools) + +| Key binding | Description | +|-------------+------------------------------------------------------| +| ~SPC m '​~ | toggle quotes of current string (only built-in mode) | +| ~SPC m {~ | toggle style of current block (only built-in mode) | +| ~SPC m g g~ | go to definition (robe-jump) | +| ~SPC m h d~ | go to Documentation | +| ~SPC m s f~ | send function definition | +| ~SPC m s F~ | send function definition and switch to REPL | +| ~SPC m s i~ | start REPL | +| ~SPC m s r~ | send region | +| ~SPC m s R~ | send region and switch to REPL | +| ~SPC m s s~ | switch to REPL | +| ~SPC m x '​~ | Change symbol or " string to ' | +| ~SPC m x "​~ | Change symbol or ' string to " | +| ~SPC m x :~ | Change string to symbol | +| ~%~ | [[https://github.com/redguardtoo/evil-matchit][evil-matchit]] jumps between blocks | + +** Bundler + +| Key binding | Description | +|-------------+--------------------| +| ~SPC b c~ | run bundle check | +| ~SPC b i~ | run bundle install | +| ~SPC b s~ | run bundle console | +| ~SPC b u~ | run bundle update | +| ~SPC b x~ | run bundle exec | +| ~SPC b o~ | run bundle open | + +** RuboCop + +| Key binding | Description | +|---------------+------------------------------------------------------| +| ~SPC m r r f~ | Runs RuboCop on the currently visited file | +| ~SPC m r r F~ | Runs auto-correct on the currently visited file | +| ~SPC m r r d~ | Prompts from a directory on which to run RuboCop | +| ~SPC m r r D~ | Prompts for a directory on which to run auto-correct | +| ~SPC m r r p~ | Runs RuboCop on the entire project | +| ~SPC m r r P~ | Runs auto-correct on the project | + +** Tests +*** RSpec-mode +When =ruby-test-runner= equals =rspec=. + +| Key binding | Description | +|---------------+--------------------------------------------------------| +| ~SPC m t a~ | run all specs | +| ~SPC m t b~ | run current spec file | +| ~SPC m t c~ | run the current spec file and subsequent ones | +| ~SPC m t d~ | run tests in a directory | +| ~SPC m t e~ | mark example as pending | +| ~SPC m t f~ | run method | +| ~SPC m t l~ | run last failed spec | +| ~SPC m t m~ | run specs related to the current buffer | +| ~SPC m t r~ | re-run last spec | +| ~SPC m t t~ | run spec at pointer | +| ~SPC m t TAB~ | toggle between spec's and target's buffer | +| ~SPC m t ~~ | toggle between spec's and target's buffer find example | + +*** Ruby-test-mode +When =ruby-test-runner= equals =ruby-test=. + +| Key binding | Description | +|-------------+---------------------| +| ~SPC m t b~ | run test file | +| ~SPC m t t~ | run test at pointer | + +*** minitest-mode +When =ruby-test-runner= equals =minitest=. + +| Key binding | Description | +|-------------+---------------------------| +| ~SPC m t a~ | run all tests | +| ~SPC m t b~ | run current file | +| ~SPC m t r~ | repeat last test command | +| ~SPC m t s~ | run test for current file | + +** Rake + +| Key binding | Description | +|-------------+---------------------------------| +| ~SPC m k k~ | Runs rake | +| ~SPC m k r~ | Re-runs the last rake task | +| ~SPC m k R~ | Regenerates the rake cache | +| ~SPC m k f~ | Finds definition of a rake task | diff --git a/layers/+lang/ruby/config.el b/layers/+lang/ruby/config.el new file mode 100644 index 0000000..617d97b --- /dev/null +++ b/layers/+lang/ruby/config.el @@ -0,0 +1,28 @@ +;;; config.el --- Ruby Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(spacemacs|defvar-company-backends enh-ruby-mode) +(spacemacs|defvar-company-backends ruby-mode) + +(spacemacs|define-jump-handlers enh-ruby-mode) +(spacemacs|define-jump-handlers ruby-mode) + +(defvar ruby-enable-enh-ruby-mode nil + "If non-nil, use `enh-ruby-mode' package instead of the built-in Ruby Mode.") + +(defvar ruby-version-manager nil + "If non nil, defines the Ruby version manager. +Possible values are `rbenv', `rvm' or `chruby'.)") + +(defvar ruby-test-runner 'ruby-test + "Test runner to use. Possible values are `ruby-test', `minitest' or `rspec'.") diff --git a/layers/+lang/ruby/funcs.el b/layers/+lang/ruby/funcs.el new file mode 100644 index 0000000..6a67eec --- /dev/null +++ b/layers/+lang/ruby/funcs.el @@ -0,0 +1,61 @@ +;;; funcs.el --- Ruby Layer functions File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + +;; rbenv + +(defun spacemacs//enable-rbenv () + "Enable rbenv, use .ruby-version if exists." + (require 'rbenv) + (let ((version-file-path (rbenv--locate-file ".ruby-version"))) + (global-rbenv-mode) + ;; try to use the ruby defined in .ruby-version + (if version-file-path + (progn + (rbenv-use (rbenv--read-version-from-file + version-file-path)) + (message (concat "[rbenv] Using ruby version " + "from .ruby-version file."))) + (message "[rbenv] Using the currently activated ruby.")))) + + +;; rspec + +(defun spacemacs//ruby-enable-rspec-mode () + "Conditionally enable `rspec-mode'" + (when (eq 'rspec ruby-test-runner) + (rspec-enable-appropriate-mode))) + +(defun ruby/rspec-verify-directory (dir) + "Launch tests in DIR directory. +Called interactively it prompts for a directory." + (interactive "Drspec directory: ") + (rspec-run-single-file dir (rspec-core-options))) + +(defun spacemacs//inf-ruby-auto-enter () + "Automatically enters inf-ruby-mode in ruby modes' debugger breakpoints." + (add-hook 'compilation-filter-hook 'inf-ruby-auto-enter nil t)) + + +;; ruby-test + +(defun spacemacs//ruby-enable-ruby-test-mode () + "Conditionally enable `ruby-test-mode'" + (when (eq 'ruby-test ruby-test-runner) + (ruby-test-mode))) + + +;; minitest + +(defun spacemacs//ruby-enable-minitest-mode () + "Conditionally enable `minitest-mode'" + (when (eq 'minitest ruby-test-runner) + (minitest-enable-appropriate-mode))) diff --git a/layers/+lang/ruby/img/ruby.png b/layers/+lang/ruby/img/ruby.png new file mode 100644 index 0000000..892360c Binary files /dev/null and b/layers/+lang/ruby/img/ruby.png differ diff --git a/layers/+lang/ruby/packages.el b/layers/+lang/ruby/packages.el new file mode 100644 index 0000000..aa681be --- /dev/null +++ b/layers/+lang/ruby/packages.el @@ -0,0 +1,280 @@ +;;; packages.el --- Ruby Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq ruby-packages + '( + bundler + chruby + company + (enh-ruby-mode :toggle ruby-enable-enh-ruby-mode) + evil-matchit + flycheck + ggtags + helm-gtags + minitest + popwin + rbenv + robe + rspec-mode + rubocop + (ruby-mode :location built-in :toggle (not ruby-enable-enh-ruby-mode)) + ruby-test-mode + ruby-tools + rvm + smartparens + rake + )) + +(defun ruby/init-bundler () + (use-package bundler + :defer t + :init (dolist (mode '(ruby-mode enh-ruby-mode)) + (spacemacs/declare-prefix-for-mode mode "mb" "ruby/bundle") + (spacemacs/set-leader-keys-for-major-mode mode + "bc" 'bundle-check + "bi" 'bundle-install + "bs" 'bundle-console + "bu" 'bundle-update + "bx" 'bundle-exec + "bo" 'bundle-open)))) + +(defun ruby/post-init-company () + (spacemacs|add-company-hook ruby-mode) + (spacemacs|add-company-hook enh-ruby-mode) + (with-eval-after-load 'company-dabbrev-code + (dolist (mode '(ruby-mode enh-ruby-mode)) + (push mode company-dabbrev-code-modes)))) + +(defun ruby/init-chruby () + (use-package chruby + :if (equal ruby-version-manager 'chruby) + :commands chruby-use-corresponding + :defer t + :init (spacemacs/add-to-hooks 'chruby-use-corresponding + '(ruby-mode-hook enh-ruby-mode-hook)))) + +(defun ruby/init-enh-ruby-mode () + (use-package enh-ruby-mode + :mode (("Appraisals\\'" . enh-ruby-mode) + ("\\(Rake\\|Thor\\|Guard\\|Gem\\|Cap\\|Vagrant\\|Berks\\|Pod\\|Puppet\\)file\\'" . enh-ruby-mode) + ("\\.\\(rb\\|rabl\\|ru\\|builder\\|rake\\|thor\\|gemspec\\|jbuilder\\)\\'" . enh-ruby-mode)) + :interpreter "ruby" + :init + (progn + (setq enh-ruby-deep-indent-paren nil + enh-ruby-hanging-paren-deep-indent-level 2)))) + +(defun ruby/post-init-evil-matchit () + (dolist (hook '(ruby-mode-hook enh-ruby-mode-hook)) + (add-hook hook `turn-on-evil-matchit-mode))) + +(defun ruby/post-init-flycheck () + (spacemacs/add-flycheck-hook 'ruby-mode) + (spacemacs/add-flycheck-hook 'enh-ruby-mode)) + +(defun ruby/post-init-ggtags () + (add-hook 'ruby-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun ruby/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'ruby-mode)) + +(defun ruby/init-minitest () + (use-package minitest + :defer t + :init + (progn + (spacemacs/add-to-hooks 'spacemacs//ruby-enable-minitest-mode + '(ruby-mode-local-vars-hook + enh-ruby-mode-local-vars-hook)) + ;; remove hooks added by minitest mode + (dolist (hook '(ruby-mode-hook enh-ruby-mode-hook)) + (remove-hook hook 'minitest-enable-appropriate-mode))) + :config + (progn + (spacemacs|hide-lighter minitest-mode) + (dolist (mode '(ruby-mode enh-ruby-mode)) + (spacemacs/set-leader-keys-for-major-mode mode + "ta" 'minitest-verify-all + "tb" 'minitest-verify + "tr" 'minitest-rerun + "ts" 'minitest-verify-single))))) + +(defun ruby/post-init-popwin () + (push '("*rspec-compilation*" :dedicated t :position bottom :stick t :noselect t :height 0.4) + popwin:special-display-config) + (push '("*rake-compilation*" :dedicated t :position bottom :stick t :noselect t :height 0.4) + popwin:special-display-config)) + +(defun ruby/init-rbenv () + (use-package rbenv + :if (equal ruby-version-manager 'rbenv) + :defer t + :init (spacemacs/add-to-hooks 'spacemacs//enable-rbenv + '(ruby-mode-hook enh-ruby-mode-hook)))) + +(defun ruby/init-robe () + (use-package robe + :defer t + :init + (progn + (spacemacs/register-repl 'robe 'robe-start "robe") + (dolist (hook '(ruby-mode-hook enh-ruby-mode-hook)) + (add-hook hook 'robe-mode)) + (when (configuration-layer/package-usedp 'company) + (push 'company-robe company-backends-enh-ruby-mode) + (push 'company-robe company-backends-ruby-mode)) + (spacemacs/add-to-hooks 'robe-jump + '(spacemacs-jump-handlers-ruby-mode + spacemacs-jump-handlers-enh-ruby-mode))) + :config + (progn + (spacemacs|hide-lighter robe-mode) + (dolist (mode '(ruby-mode enh-ruby-mode)) + (spacemacs/declare-prefix-for-mode mode "mg" "ruby/goto") + (spacemacs/declare-prefix-for-mode mode "mh" "ruby/docs") + (spacemacs/declare-prefix-for-mode mode "ms" "ruby/repl") + (spacemacs/set-leader-keys-for-major-mode mode + "'" 'robe-start + ;; robe mode specific + "hd" 'robe-doc + "rsr" 'robe-rails-refresh + ;; inf-enh-ruby-mode + "sf" 'ruby-send-definition + "sF" 'ruby-send-definition-and-go + "si" 'robe-start + "sr" 'ruby-send-region + "sR" 'ruby-send-region-and-go + "ss" 'ruby-switch-to-inf))))) + +(defun ruby/init-rspec-mode () + (use-package rspec-mode + :defer t + :init + (progn + (spacemacs/add-to-hooks 'spacemacs//ruby-enable-rspec-mode + '(ruby-mode-local-vars-hook + enh-ruby-mode-local-vars-hook)) + ;; remove hooks automatically added by rspec via autoload + ;; because we want to be able to control when rspec-mode is + ;; loaded based on the layer variable `ruby-test-runner' + (dolist (hook '(ruby-mode-hook enh-ruby-mode-hook)) + (remove-hook hook 'rspec-enable-appropriate-mode))) + :config + (progn + (add-hook 'rspec-compilation-mode-hook 'spacemacs//inf-ruby-auto-enter) + (spacemacs|hide-lighter rspec-mode) + (dolist (mode '(ruby-mode enh-ruby-mode)) + (spacemacs/set-leader-keys-for-major-mode mode + "ta" 'rspec-verify-all + "tb" 'rspec-verify + "tc" 'rspec-verify-continue + "td" 'ruby/rspec-verify-directory + "te" 'rspec-toggle-example-pendingness + "tf" 'rspec-verify-method + "tl" 'rspec-run-last-failed + "tm" 'rspec-verify-matching + "tr" 'rspec-rerun + "tt" 'rspec-verify-single + "t~" 'rspec-toggle-spec-and-target-find-example + "t TAB" 'rspec-toggle-spec-and-target))))) + +(defun ruby/init-rubocop () + (use-package rubocop + :defer t + :init (spacemacs/add-to-hooks 'rubocop-mode '(ruby-mode-hook + enh-ruby-mode-hook)) + :config (dolist (mode '(ruby-mode enh-ruby-mode)) + (spacemacs/declare-prefix-for-mode mode "mrr" "ruby/RuboCop") + (spacemacs/set-leader-keys-for-major-mode mode + "rrd" 'rubocop-check-directory + "rrD" 'rubocop-autocorrect-directory + "rrf" 'rubocop-check-current-file + "rrF" 'rubocop-autocorrect-current-file + "rrp" 'rubocop-check-project + "rrP" 'rubocop-autocorrect-project)))) + +(defun ruby/init-ruby-mode () + (use-package ruby-mode + :defer t + :mode (("Appraisals\\'" . ruby-mode) + ("Puppetfile" . ruby-mode)) + :init + (progn + (spacemacs/declare-prefix-for-mode 'ruby-mode "mt" "ruby/test")) + :config (spacemacs/set-leader-keys-for-major-mode 'ruby-mode + "'" 'ruby-toggle-string-quotes + "{" 'ruby-toggle-block))) + +(defun ruby/init-ruby-tools () + (use-package ruby-tools + :defer t + :init (dolist (hook '(ruby-mode-hook enh-ruby-mode-hook)) + (add-hook hook 'ruby-tools-mode)) + :config + (progn + (spacemacs|hide-lighter ruby-tools-mode) + (dolist (mode '(ruby-mode enh-ruby-mode)) + (spacemacs/declare-prefix-for-mode mode "mx" "ruby/text") + (spacemacs/set-leader-keys-for-major-mode mode + "x\'" 'ruby-tools-to-single-quote-string + "x\"" 'ruby-tools-to-double-quote-string + "x:" 'ruby-tools-to-symbol))))) + +(defun ruby/init-ruby-test-mode () + "Define keybindings for ruby test mode" + (use-package ruby-test-mode) + :defer t + :init (spacemacs/add-to-hooks 'spacemacs//ruby-enable-ruby-test-mode + '(ruby-mode-local-vars-hook + enh-ruby-mode-local-vars-hook)) + :config + (progn + ;; `ruby-test-mode' adds a hook to enable itself, this hack + ;; removes it to be sure that we control the loading of the + ;; mode + (remove-hook 'ruby-mode-hook 'ruby-test-enable) + (spacemacs|hide-lighter ruby-test-mode) + (dolist (mode '(ruby-mode enh-ruby-mode)) + (spacemacs/set-leader-keys-for-major-mode mode + "tb" 'ruby-test-run + "tt" 'ruby-test-run-at-point)))) + +(defun ruby/init-rvm () + (use-package rvm + :if (equal ruby-version-manager 'rvm) + :defer t + :init + (progn + (setq rspec-use-rvm t) + (spacemacs/add-to-hooks 'rvm-activate-corresponding-ruby + '(ruby-mode-hook enh-ruby-mode-hook))))) + +(defun ruby/post-init-smartparens () + (spacemacs|use-package-add-hook smartparens + :post-config + (sp-with-modes (if ruby-enable-enh-ruby-mode 'enh-ruby-mode 'ruby-mode) + (sp-local-pair + "{" "}" + :pre-handlers '(sp-ruby-pre-handler) + :post-handlers '(sp-ruby-post-handler + (spacemacs/smartparens-pair-newline-and-indent "RET")) + :suffix "")))) + +(defun ruby/init-rake () + (use-package rake + :defer t + :init (setq rake-cache-file (concat spacemacs-cache-directory "rake.cache")) + :config (dolist (mode '(ruby-mode enh-ruby-mode)) + (spacemacs/set-leader-keys-for-major-mode mode + "kk" 'rake + "kr" 'rake-rerun + "kR" 'rake-regenerate-cache + "kf" 'rake-find-task)))) diff --git a/layers/+lang/rust/README.org b/layers/+lang/rust/README.org new file mode 100644 index 0000000..9ef12bc --- /dev/null +++ b/layers/+lang/rust/README.org @@ -0,0 +1,64 @@ +#+TITLE: Rust contribution layer for Spacemacs + +[[file:img/rust.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#racer][Racer]] + - [[#cargo][Cargo]] + - [[#rustfmt][Rustfmt]] + - [[#key-bindings][Key bindings]] + +* Description +This layer supports [[http://www.rust-lang.org/][Rust]] development in Spacemacs. + +It has auto-completion and navigation support through [[https://github.com/phildawes/racer][Racer]] and supports [[http://doc.crates.io/index.html][Cargo]]. + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =rust= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Racer +You must install [[https://github.com/phildawes/racer][Racer]] to use this. Make sure the =racer= binary is available in +your =PATH= and to set the environment variable =RUST_SRC_PATH=, as described in +the [[https://github.com/phildawes/racer#installation][installation instructions]]. + +To enable auto-completion, ensure that the =auto-completion= layer is enabled. + +** Cargo +[[http://doc.crates.io/index.html][Cargo]] is a project management command line tool for Rust. Installation +instructions can be found on the main page of [[http://doc.crates.io/index.html][Cargo]]. + +** Rustfmt +Format Rust code according to style guidelines using [[https://github.com/rust-lang-nursery/rustfmt][rustfmt]]. + +#+BEGIN_SRC sh +cargo install rustfmt +#+END_SRC + +To enable automatic buffer formatting on save, set the variable =rust-format-on-save= to =t=. + +* Key bindings + +| Key Binding | Description | +|-------------+---------------------------------------------| +| ~SPC m =~ | reformat the buffer | +| ~SPC m c .~ | repeat the last Cargo command | +| ~SPC m c C~ | remove build artifacts with Cargo | +| ~SPC m c X~ | execute a project example with Cargo | +| ~SPC m c c~ | compile project with Cargo | +| ~SPC m c d~ | generate documentation with Cargo | +| ~SPC m c e~ | run benchmarks with Cargo | +| ~SPC m c f~ | run the current test with Cargo | +| ~SPC m c i~ | create a new project with Cargo (init) | +| ~SPC m c n~ | create a new project with Cargo (new) | +| ~SPC m c o~ | run all tests in current file with Cargo | +| ~SPC m c s~ | search for packages on crates.io with Cargo | +| ~SPC m c u~ | update dependencies with Cargo | +| ~SPC m c x~ | execute a project with Cargo | +| ~SPC m g g~ | jump to definition | +| ~SPC m t~ | run tests with Cargo | diff --git a/layers/+lang/rust/config.el b/layers/+lang/rust/config.el new file mode 100644 index 0000000..d81f7e3 --- /dev/null +++ b/layers/+lang/rust/config.el @@ -0,0 +1,16 @@ +;;; config.el --- Rust Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Chris Hoeppner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(spacemacs|defvar-company-backends rust-mode) + +(spacemacs|define-jump-handlers rust-mode) diff --git a/layers/+lang/rust/img/rust.png b/layers/+lang/rust/img/rust.png new file mode 100644 index 0000000..e1968f7 Binary files /dev/null and b/layers/+lang/rust/img/rust.png differ diff --git a/layers/+lang/rust/packages.el b/layers/+lang/rust/packages.el new file mode 100644 index 0000000..4bb4682 --- /dev/null +++ b/layers/+lang/rust/packages.el @@ -0,0 +1,97 @@ +;;; packages.el --- Rust Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Chris Hoeppner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq rust-packages + '( + cargo + company + racer + flycheck + (flycheck-rust :toggle (configuration-layer/package-usedp 'flycheck)) + ggtags + helm-gtags + rust-mode + toml-mode + )) + +(defun rust/init-cargo () + (use-package cargo + :defer t + :init + (progn + (spacemacs/declare-prefix-for-mode 'rust-mode "mc" "cargo") + (spacemacs/set-leader-keys-for-major-mode 'rust-mode + "c." 'cargo-process-repeat + "cC" 'cargo-process-clean + "cX" 'cargo-process-run-example + "cc" 'cargo-process-build + "cd" 'cargo-process-doc + "ce" 'cargo-process-bench + "cf" 'cargo-process-current-test + "cf" 'cargo-process-fmt + "ci" 'cargo-process-init + "cn" 'cargo-process-new + "co" 'cargo-process-current-file-tests + "cs" 'cargo-process-search + "cu" 'cargo-process-update + "cx" 'cargo-process-run + "t" 'cargo-process-test)))) + +(defun rust/post-init-flycheck () + (spacemacs/add-flycheck-hook 'rust-mode)) + +(defun rust/init-flycheck-rust () + (use-package flycheck-rust + :defer t + :init (add-hook 'flycheck-mode-hook #'flycheck-rust-setup))) + +(defun rust/post-init-ggtags () + (add-hook 'rust-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun rust/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'rust-mode)) + +(defun rust/init-rust-mode () + (use-package rust-mode + :defer t + :init + (progn + (spacemacs/set-leader-keys-for-major-mode 'rust-mode + "=" 'rust-format-buffer)))) + +(defun rust/init-toml-mode () + (use-package toml-mode + :mode "/\\(Cargo.lock\\|\\.cargo/config\\)\\'")) + +(defun rust/post-init-company () + (push 'company-capf company-backends-rust-mode) + (spacemacs|add-company-hook rust-mode) + (add-hook 'rust-mode-hook + (lambda () + (setq-local company-tooltip-align-annotations t)))) + +(defun rust/post-init-smartparens () + (with-eval-after-load 'smartparens + ;; Don't pair lifetime specifiers + (sp-local-pair 'rust-mode "'" nil :actions nil))) + +(defun rust/init-racer () + (when (memq window-system '(mac ns x)) + (exec-path-from-shell-copy-env "RUST_SRC_PATH")) + + (use-package racer + :diminish racer-mode + :defer t + :init + (progn + (spacemacs/add-to-hook 'rust-mode-hook '(racer-mode eldoc-mode)) + (spacemacs/declare-prefix-for-mode 'rust-mode "mg" "goto") + (add-to-list 'spacemacs-jump-handlers-rust-mode 'racer-find-definition)))) diff --git a/layers/+lang/scala/README.org b/layers/+lang/scala/README.org new file mode 100644 index 0000000..6bf9464 --- /dev/null +++ b/layers/+lang/scala/README.org @@ -0,0 +1,266 @@ +#+TITLE: Scala layer + +[[file:img/scala.png]] with [[file:img/ensime.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#layer-installation][Layer Installation]] + - [[#ensime][Ensime]] + - [[#installation][Installation]] + - [[#usage][Usage]] + - [[#scalastyle][Scalastyle]] + - [[#use-java-doc-style][Use Java doc-style]] + - [[#automatically-show-the-type-of-the-symbol-under-the-cursor][Automatically show the type of the symbol under the cursor]] + - [[#automatically-insert-asterisk-in-multiline-comments][Automatically insert asterisk in multiline comments]] + - [[#automatically-replace-arrows-with-unicode-ones][Automatically replace arrows with unicode ones]] + - [[#auto-start][Auto-start]] + - [[#key-bindings][Key bindings]] + - [[#ensime-key-bindings][Ensime key bindings]] + - [[#search][Search]] + - [[#sbt][sbt]] + - [[#typecheck][Typecheck]] + - [[#debug][Debug]] + - [[#errors][Errors]] + - [[#goto][Goto]] + - [[#print-and-yank-types][Print and yank types]] + - [[#documentation-inspect][Documentation, Inspect]] + - [[#server][Server]] + - [[#refactoring][Refactoring]] + - [[#tests][Tests]] + - [[#repl][REPL]] + +* Description +This layer adds support for the Scala language using the excellent [[http://ensime.github.io/][ENSIME]] +client/server. + +* Layer Installation +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =scala= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Ensime +[[http://ensime.github.io/][ENSIME]] provides IDE-like features, such as refactoring, incremental compilation +and project-wide type-checking. + +ENSIME requires a configuration file at the root of each Scala project. It +provides an SBT plugin to generate these files. + +** Installation +Refer to the [[https://ensime.github.io/build_tools/sbt/][Ensime installation instructions]] to install the =sbt-ensime= +plugin. + +Please note you have to use a version newer than =0.13.5= of =sbt= in your +project's =project/build.properties=. For example, + +#+BEGIN_SRC scala + sbt.version=0.13.11 +#+END_SRC + +** Usage +1. Create a =.ensime= file at the root of your Scala project using =sbt + ensimeConfig= and =sbt ensimeConfigProject= at the shell. +2. Run =M-x ensime= within Emacs to start an ENSIME session. + +Each Scala project uses a dedicated ENSIME session, so you only need to run =M-x +ensime= once per project. Any Scala files you create or visit within the project +will automatically use ENSIME for the remainder of your editing session. + +* Scalastyle +[[http://www.scalastyle.org/][Scalastyle]] provides style-checking and linting. The Emacs functionality is +provided by Flycheck. + +To use scalastyle, it must be present as an executable in your =PATH=. + +- OSX users: =brew install scalastyle= +- Linux, please see http://www.scalastyle.org/command-line.html + +To test if =scalastyle= executable is in your path, run =scalastyle= in a new +terminal, it should output something like: +#+BEGIN_SRC bash +$ scalastyle +scalastyle 0.8.0 +Usage: scalastyle [options] +... +#+END_SRC + +Finally, enable the =syntax-checking= layer and set the =flycheck-scalastylerc= +variable to a valid location. +#+BEGIN_SRC emacs-lisp + (setq-default flycheck-scalastylerc "/usr/local/etc/scalastyle_config.xml") +#+END_SRC + +See the [[http://www.flycheck.org/en/latest/languages.html?highlight=scala#syntax-checker-scala-scalastyle][flycheck documentation]] and [[http://www.scalastyle.org/configuration.html][scalastyle configuration]] for up-to-date +configuration instructions. + +** Use Java doc-style +To enable =java-doc-style=, set the variable =scala-indent:use-javadoc-style= to +=t= + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '( + (scala :variables scala-indent:use-javadoc-style t))) +#+END_SRC + +* Automatically show the type of the symbol under the cursor +To enable the feature =ensime-print-type-at-point= when cursor moves, set the +variable =scala-enable-eldoc= to =t=. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '( + (scala :variables scala-use-java-doc-style t))) +#+END_SRC + +Enabling this option can cause slow editor performance. + +* Automatically insert asterisk in multiline comments +To insert a leading asterisk in multiline comments automatically, set the +variable =scala-auto-insert-asterisk-in-comments= to =t=. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '( + (scala :variables scala-auto-insert-asterisk-in-comments t))) +#+END_SRC + +* Automatically replace arrows with unicode ones +To replace ~=>~, =->= and =<-= with unicode arrows =⇒=, =→= and =←=, set the +variable =scala-use-unicode-arrows= to =t=. + +If in some occasions you don't want the arrows replaced (for example when +defining compound operators like ~=>>~), you can always undo the change and get +the ascii arrows back. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '( + (scala :variables scala-use-unicode-arrows t))) +#+END_SRC + +* Auto-start +If you prefer to have Ensime start when you load a scala file, you can enable it +with + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers '( + (scala :variables scala-auto-start-ensime t))) +#+END_SRC + +* Key bindings +** Ensime key bindings +*** Search + +| Key Binding | Description | +|-------------+-----------------------------------------------------| +| ~SPC m /~ | incremental search using =ensime-scalex= major mode | +| ~SPC m ?~ | incremental search in all live buffers | + +*** sbt + +| Key Binding | Description | +|-------------+---------------------| +| ~SPC m b .~ | sbt transient state | +| ~SPC m b b~ | sbt command | +| ~SPC m b c~ | compile | +| ~SPC m b C~ | clean command | +| ~SPC m b i~ | switch to sbt shell | +| ~SPC m b p~ | package command | +| ~SPC m b r~ | run command | + +*** Typecheck + +| Key Binding | Description | +|-------------+---------------------------------| +| ~SPC m c t~ | type check the current file | +| ~SPC m c T~ | type check all the open buffers | + +*** Debug + +| Key Binding | Description | +|-------------+-----------------------------| +| ~SPC m d A~ | Attach to a remote debugger | +| ~SPC m d b~ | set breakpoint | +| ~SPC m d B~ | clear breakpoint | +| ~SPC m d C~ | clear all breakpoints | +| ~SPC m d c~ | continue | +| ~SPC m d i~ | inspect value at point | +| ~SPC m d n~ | next | +| ~SPC m d o~ | step out | +| ~SPC m d q~ | quit | +| ~SPC m d r~ | run | +| ~SPC m d s~ | step | +| ~SPC m d t~ | backtrace | + +*Note:* These key bindings need a transient-state, PR welcome :-) + +*** Errors + +| Key Binding | Description | +|-------------+----------------------------------------------------| +| ~SPC m e e~ | print error at point | +| ~SPC m e l~ | show all errors and warnings | +| ~SPC m e s~ | switch to buffer containing the stack trace parser | + +*** Goto + +| Key Binding | Description | +|-------------+----------------------| +| ~SPC m g g~ | go to definition | +| ~SPC m g i~ | go to implementation | +| ~SPC m g t~ | go to test | + +*** Print and yank types +|-------------+--------------------------------| +| ~SPC m h T~ | print full type name at point | +| ~SPC m h t~ | print short type name at point | +| ~SPC m y T~ | yank full type name at point | +| ~SPC m y t~ | yank short type name at point | + +*** Documentation, Inspect + +| Key Binding | Description | +|-------------+----------------------------------------| +| ~SPC m h h~ | show documentation for symbol at point | +| ~SPC m h u~ | show uses for symbol at point | +| ~SPC m i i~ | inspect type at point | +| ~SPC m i I~ | inspect type in other frame | +| ~SPC m i p~ | inspect project package | + +*** Server + +| Key Binding | Description | +|-------------+--------------------------------------------------------| +| ~SPC m n F~ | reload open files | +| ~SPC m n s~ | start ensime server | +| ~SPC m n S~ | regenerate the =.ensime= and restart the ensime server | + +*** Refactoring + +| Key Binding | Description | +|-------------+----------------------------------------------------------------------| +| ~SPC m r a~ | add type annotation | +| ~SPC m r f~ | format source | +| ~SPC m r d~ | get rid of an intermediate variable (=ensime-refactor-inline-local=) | +| ~SPC m r D~ | get rid of an intermediate variable (=ensime-undo-peek=) | +| ~SPC m r i~ | organize imports | +| ~SPC m r m~ | extract a range of code into a method | +| ~SPC m r r~ | rename a symbol project wide | +| ~SPC m r t~ | import type at point | +| ~SPC m r v~ | extract a range of code into a variable | +| ~SPC m z~ | expand/contract region | + +*** Tests + +| Key Binding | Description | +|-------------+--------------------------| +| ~SPC m t a~ | test command (sbt) | +| ~SPC m t r~ | test quick command (sbt) | +| ~SPC m t t~ | test only (sbt) | + +*** REPL + +| Key Binding | Description | +|-------------+---------------------------------------------------------------------| +| ~SPC m s a~ | ask for a file to be loaded in the REPL | +| ~SPC m s b~ | send buffer to the REPL | +| ~SPC m s B~ | send buffer to the REPL and focus the REPL buffer in =insert state= | +| ~SPC m s i~ | start or switch to the REPL inferior process | +| ~SPC m s r~ | send region to the REPL | +| ~SPC m s R~ | send region to the REPL and focus the REPL buffer in =insert state= | diff --git a/layers/+lang/scala/config.el b/layers/+lang/scala/config.el new file mode 100644 index 0000000..ad98b83 --- /dev/null +++ b/layers/+lang/scala/config.el @@ -0,0 +1,26 @@ +;;; config.el --- Scala Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(spacemacs|define-jump-handlers scala-mode) + +(spacemacs|define-jump-handlers scala-mode) + +(defvar scala-enable-eldoc nil + "If non nil then eldoc-mode is enabled in the scala layer.") + +(defvar scala-auto-insert-asterisk-in-comments nil + "If non-nil automatically insert leading asterisk in multi-line comments.") + +(defvar scala-use-unicode-arrows nil + "If non-nil then `->`, `=>` and `<-` are replaced with unicode arrows.") + +(defvar scala-auto-start-ensime nil + "If non nil then ensime will be started when a scala file is opened.") diff --git a/layers/+lang/scala/funcs.el b/layers/+lang/scala/funcs.el new file mode 100644 index 0000000..e9870cf --- /dev/null +++ b/layers/+lang/scala/funcs.el @@ -0,0 +1,119 @@ +;;; funcs.el --- Scala Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;;; Ensime + +(autoload 'ensime-config-find-file "ensime-config") +(autoload 'ensime-config-find "ensime-config") +(autoload 'projectile-project-p "projectile") + +(defun scala/configure-ensime () + "Ensure the file exists before starting `ensime-mode'." + (cond + ((and (buffer-file-name) (file-exists-p (buffer-file-name))) + (ensime-mode +1)) + ((buffer-file-name) + (add-hook 'after-save-hook (lambda () (ensime-mode +1)) nil t)))) + +(defun scala/maybe-start-ensime () + (when (buffer-file-name) + (let ((ensime-buffer (scala/ensime-buffer-for-file (buffer-file-name))) + (file (ensime-config-find-file (buffer-file-name))) + (is-source-file (s-matches? (rx (or "/src/" "/test/")) (buffer-file-name)))) + + (when (and is-source-file (null ensime-buffer)) + (noflet ((ensime-config-find (&rest _) file)) + (save-window-excursion + (ensime))))))) + +(defun scala/ensime-buffer-for-file (file) + "Find the Ensime server buffer corresponding to FILE." + (let ((default-directory (file-name-directory file))) + (-when-let (project-name (projectile-project-p)) + (--first (-when-let (bufname (buffer-name it)) + (and (s-contains? "inferior-ensime-server" bufname) + (s-contains? (file-name-nondirectory project-name) bufname))) + (buffer-list))))) + +(defun scala/enable-eldoc () + (setq-local eldoc-documentation-function + (lambda () + (when (ensime-connected-p) + (ensime-print-type-at-point)))) + (eldoc-mode +1)) + +(defun spacemacs/ensime-refactor-accept () + (interactive) + (funcall continue-refactor) + (ensime-popup-buffer-quit-function)) + +(defun spacemacs/ensime-refactor-cancel () + (interactive) + (funcall cancel-refactor) + (ensime-popup-buffer-quit-function)) + +;;; Interactive commands + +(defun spacemacs/scala-join-line () + "Adapt `scala-indent:join-line' to behave more like evil's line join. + +`scala-indent:join-line' acts like the vanilla `join-line', +joining the current line with the previous one. The vimmy way is +to join the current line with the next. + +Try to move to the subsequent line and then join. Then manually move +point to the position of the join." + (interactive) + (let (join-pos) + (save-excursion + (goto-char (line-end-position)) + (unless (eobp) + (forward-line) + (call-interactively 'scala-indent:join-line) + (setq join-pos (point)))) + + (when join-pos + (goto-char join-pos)))) + +(defun scala/completing-dot () + "Insert a period and show company completions." + (interactive "*") + (when (s-matches? (rx (+ (not space))) + (buffer-substring (line-beginning-position) (point))) + (delete-horizontal-space t)) + (company-abort) + (insert ".") + (company-complete)) + +;;; Flyspell + +(defun scala/flyspell-verify () + "Prevent common flyspell false positives in scala-mode." + (and (flyspell-generic-progmode-verify) + (not (s-matches? (rx bol (* space) "package") (current-line))))) + +(defun scala/configure-flyspell () + (setq-local flyspell-generic-check-word-predicate 'scala/flyspell-verify)) + +(defun scala/yank-type-at-point () + "Yank to kill ring and print short type name at point to the minibuffer." + (interactive) + (ensime-type-at-point t nil)) + +(defun scala/yank-type-at-point-full-name () + "Yank to kill ring and print full type name at point to the minibuffer." + (interactive) + (ensime-type-at-point t t)) + +(defun sbt-hydra () + "Wrapper to rename sbt-hydra:hydra to sbt-hydra" + (interactive) + (sbt-hydra:hydra)) diff --git a/layers/+lang/scala/img/ensime.png b/layers/+lang/scala/img/ensime.png new file mode 100644 index 0000000..44be74a Binary files /dev/null and b/layers/+lang/scala/img/ensime.png differ diff --git a/layers/+lang/scala/img/scala.png b/layers/+lang/scala/img/scala.png new file mode 100644 index 0000000..4059be3 Binary files /dev/null and b/layers/+lang/scala/img/scala.png differ diff --git a/layers/+lang/scala/packages.el b/layers/+lang/scala/packages.el new file mode 100644 index 0000000..31112f4 --- /dev/null +++ b/layers/+lang/scala/packages.el @@ -0,0 +1,281 @@ +;;; packages.el --- Scala Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq scala-packages + '( + ensime + flycheck + ggtags + helm-gtags + noflet + org + scala-mode + sbt-mode + )) + +(defun scala/init-ensime () + (use-package ensime + :defer t + :init + ;; note ensime-mode is hooked to scala-mode-hook automatically by + ;; ensime-mode via an autoload + (progn + (spacemacs/register-repl 'ensime 'ensime-inf-switch "ensime") + (when scala-enable-eldoc + (add-hook 'ensime-mode-hook 'scala/enable-eldoc)) + (add-hook 'scala-mode-hook 'scala/configure-flyspell) + (add-hook 'scala-mode-hook 'scala/configure-ensime) + (when scala-auto-start-ensime + (add-hook 'scala-mode-hook 'scala/maybe-start-ensime)) + (add-to-list 'spacemacs-jump-handlers-scala-mode 'ensime-edit-definition)) + :config + (progn + (setq user-emacs-ensime-directory ".cache/ensime") + + (evil-define-key 'insert ensime-mode-map + (kbd ".") 'scala/completing-dot + (kbd "M-.") 'ensime-edit-definition + (kbd "M-,") 'ensime-pop-find-definition-stack) + + (evil-define-key 'normal ensime-mode-map + (kbd "M-.") 'ensime-edit-definition + (kbd "M-,") 'ensime-pop-find-definition-stack) + + (evil-define-key 'normal ensime-popup-buffer-map + (kbd "q") 'ensime-popup-buffer-quit-function) + + (evil-define-key 'normal ensime-inspector-mode-map + (kbd "q") 'ensime-popup-buffer-quit-function) + + (evil-define-key 'normal ensime-refactor-info-map + (kbd "q") 'spacemacs/ensime-refactor-cancel + (kbd "c") 'spacemacs/ensime-refactor-accept + (kbd "RET") 'spacemacs/ensime-refactor-accept) + + (evil-define-key 'normal ensime-compile-result-map + (kbd "g") 'ensime-show-all-errors-and-warnings + (kbd "TAB") 'forward-button + (kbd "") 'backward-button + (kbd "M-n") 'forward-button + (kbd "M-p") 'backward-button + (kbd "n") 'forward-button + (kbd "N") 'backward-button) + + (defun ensime-gen-and-restart() + "Regenerate `.ensime' file and restart the ensime server." + (interactive) + (progn + (sbt-command ";ensimeConfig;ensimeConfigProject") + (ensime-shutdown) + (ensime))) + + (defun ensime-inf-eval-buffer-switch () + "Send buffer content to shell and switch to it in insert mode." + (interactive) + (ensime-inf-eval-buffer) + (ensime-inf-switch) + (evil-insert-state)) + + (defun ensime-inf-eval-region-switch (start end) + "Send region content to shell and switch to it in insert mode." + (interactive "r") + (ensime-inf-switch) + (ensime-inf-eval-region start end) + (evil-insert-state)) + + (dolist (prefix '(("mb" . "scala/build") + ("mc" . "scala/check") + ("md" . "scala/debug") + ("me" . "scala/errors") + ("mg" . "scala/goto") + ("mh" . "scala/docs") + ("mi" . "scala/inspect") + ("mn" . "scala/ensime") + ("mr" . "scala/refactor") + ("mt" . "scala/test") + ("ms" . "scala/repl") + ("my" . "scala/yank"))) + (spacemacs/declare-prefix-for-mode 'scala-mode (car prefix) (cdr prefix))) + + (spacemacs/set-leader-keys-for-major-mode 'scala-mode + "/" 'ensime-search + "'" 'ensime-inf-switch + + "bc" 'ensime-sbt-do-compile + "bC" 'ensime-sbt-do-clean + "bi" 'ensime-sbt-switch + "bp" 'ensime-sbt-do-package + "br" 'ensime-sbt-do-run + + "ct" 'ensime-typecheck-current-buffer + "cT" 'ensime-typecheck-all + + "dA" 'ensime-db-attach + "db" 'ensime-db-set-break + "dB" 'ensime-db-clear-break + "dC" 'ensime-db-clear-all-breaks + "dc" 'ensime-db-continue + "di" 'ensime-db-inspect-value-at-point + "dn" 'ensime-db-next + "do" 'ensime-db-step-out + "dq" 'ensime-db-quit + "dr" 'ensime-db-run + "ds" 'ensime-db-step + "dt" 'ensime-db-backtrace + + "ee" 'ensime-print-errors-at-point + "el" 'ensime-show-all-errors-and-warnings + "es" 'ensime-stacktrace-switch + + "gp" 'ensime-pop-find-definition-stack + "gi" 'ensime-goto-impl + "gt" 'ensime-goto-test + + "hh" 'ensime-show-doc-for-symbol-at-point + "hT" 'ensime-type-at-point-full-name + "ht" 'ensime-type-at-point + "hu" 'ensime-show-uses-of-symbol-at-point + + "ii" 'ensime-inspect-type-at-point + "iI" 'ensime-inspect-type-at-point-other-frame + "ip" 'ensime-inspect-project-package + + "nF" 'ensime-reload-open-files + "ns" 'ensime + "nS" 'ensime-gen-and-restart + + "ra" 'ensime-refactor-add-type-annotation + "rd" 'ensime-refactor-diff-inline-local + "rD" 'ensime-undo-peek + "rf" 'ensime-format-source + "ri" 'ensime-refactor-diff-organize-imports + "rm" 'ensime-refactor-diff-extract-method + "rr" 'ensime-refactor-diff-rename + "rt" 'ensime-import-type-at-point + "rv" 'ensime-refactor-diff-extract-local + + "ta" 'ensime-sbt-do-test-dwim + "tr" 'ensime-sbt-do-test-quick-dwim + "tt" 'ensime-sbt-do-test-only-dwim + + "sa" 'ensime-inf-load-file + "sb" 'ensime-inf-eval-buffer + "sB" 'ensime-inf-eval-buffer-switch + "si" 'ensime-inf-switch + "sr" 'ensime-inf-eval-region + "sR" 'ensime-inf-eval-region-switch + + "yT" 'scala/yank-type-at-point-full-name + "yt" 'scala/yank-type-at-point + + "z" 'ensime-expand-selection-command + ) + + ;; Don't use scala checker if ensime mode is active, since it provides + ;; better error checking. + (with-eval-after-load 'flycheck + (defun scala/disable-flycheck-scala () + (push 'scala flycheck-disabled-checkers)) + + (add-hook 'ensime-mode-hook 'scala/disable-flycheck-scala)) + + ;; Enable Expand Region integration from Ensime. Ignore load errors to + ;; handle older Ensime versions gracefully. + (when (configuration-layer/package-usedp 'expand-region) + (require 'ensime-expand-region nil 'noerror))))) + +(defun scala/post-init-flycheck () + (spacemacs/add-flycheck-hook 'scala-mode)) + +(defun scala/init-noflet () + (use-package noflet)) + +(defun scala/pre-init-org () + (spacemacs|use-package-add-hook org + :post-config (add-to-list 'org-babel-load-languages '(scala . t)))) + +(defun scala/init-sbt-mode () + (use-package sbt-mode + :defer t + :init (spacemacs/set-leader-keys-for-major-mode 'scala-mode + "b." 'sbt-hydra + "bb" 'sbt-command))) + +(defun scala/init-scala-mode () + (use-package scala-mode + :defer t + :init + (progn + (dolist (ext '(".cfe" ".cfs" ".si" ".gen" ".lock")) + (add-to-list 'completion-ignored-extensions ext))) + :config + (progn + ;; Automatically insert asterisk in a comment when enabled + (defun scala/newline-and-indent-with-asterisk () + (interactive) + (newline-and-indent) + (when scala-auto-insert-asterisk-in-comments + (scala-indent:insert-asterisk-on-multiline-comment))) + + (evil-define-key 'insert scala-mode-map + (kbd "RET") 'scala/newline-and-indent-with-asterisk) + + ;; Automatically replace arrows with unicode ones when enabled + (defconst scala-unicode-arrows-alist + '(("=>" . "⇒") + ("->" . "→") + ("<-" . "←"))) + + (defun scala/replace-arrow-at-point () + "Replace the arrow before the point (if any) with unicode ones. +An undo boundary is inserted before doing the replacement so that +it can be undone." + (let* ((end (point)) + (start (max (- end 2) (point-min))) + (x (buffer-substring start end)) + (arrow (assoc x scala-unicode-arrows-alist))) + (when arrow + (undo-boundary) + (backward-delete-char 2) + (insert (cdr arrow))))) + + (defun scala/gt () + "Insert a `>' to the buffer. If it's part of a right arrow (`->' or `=>'), +replace it with the corresponding unicode arrow." + (interactive) + (insert ">") + (scala/replace-arrow-at-point)) + + (defun scala/hyphen () + "Insert a `-' to the buffer. If it's part of a left arrow (`<-'), +replace it with the unicode arrow." + (interactive) + (insert "-") + (scala/replace-arrow-at-point)) + + (when scala-use-unicode-arrows + (define-key scala-mode-map + (kbd ">") 'scala/gt) + (define-key scala-mode-map + (kbd "-") 'scala/hyphen)) + + (evil-define-key 'normal scala-mode-map "J" 'spacemacs/scala-join-line) + + ;; Compatibility with `aggressive-indent' + (setq scala-indent:align-forms t + scala-indent:align-parameters t + scala-indent:default-run-on-strategy scala-indent:operator-strategy)))) + +(defun scala/post-init-ggtags () + (add-hook 'scala-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun scala/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'scala-mode)) diff --git a/layers/+lang/scheme/README.org b/layers/+lang/scheme/README.org new file mode 100644 index 0000000..4c14250 --- /dev/null +++ b/layers/+lang/scheme/README.org @@ -0,0 +1,100 @@ +#+TITLE: Scheme layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key Bindings]] + - [[#compiling][Compiling]] + - [[#navigation][Navigation]] + - [[#documentation][Documentation]] + - [[#insertion][Insertion]] + - [[#macroexpansion][Macroexpansion]] + - [[#repl][REPL]] + - [[#evaluation][Evaluation]] + +* Description + +A spacemacs contribution layer providing Scheme support via [[http://www.nongnu.org/geiser/][Geiser]]. + +* Install +The scheme layer currently supports: Chicken and Guile. Combined usage of racket-mode +and geiser has not been tested. + +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =scheme= to the existing =dotspacemacs-configuration-layers= list in this +file. + +For full Chicken support, the following commands should be run: + +#+BEGIN_SRC shell + $ chicken-install -s apropos chicken-doc + $ cd `csi -p '(chicken-home)'` + $ curl https://3e8.org/pub/chicken-doc/chicken-doc-repo.tgz | sudo tar zx +#+END_SRC + +* Key Bindings + +** Compiling + +| Key Binding | Description | +|-------------+----------------------------| +| ~SPC m c c~ | Compile current buffer | +| ~SPC m c p~ | Add directory to load path | + +** Navigation + +| Key Binding | Description | +|-------------+---------------------| +| ~SPC m g g~ | Goto Definition | +| ~SPC m g b~ | Go Back | +| ~SPC m g m~ | Goto Module | +| ~SPC m g n~ | Goto next error | +| ~SPC m g N~ | Goto previous error | + +** Documentation + +| Key Binding | Description | +|-------------+------------------------------------------| +| ~SPC m h h~ | Docs for symbol at point | +| ~SPC m h d~ | Look up manual entry for symbol at point | +| ~SPC m h m~ | Display exports for module | +| ~SPC m h <~ | Display callers | +| ~SPC m h >~ | Display callees | + +** Insertion + +| Key Binding | Description | +|-------------+---------------| +| ~SPC m i l~ | Insert Lambda | + +** Macroexpansion + +| Key Binding | Description | +|-------------+------------------------------| +| ~SPC m m e~ | Macroexpand last sexp | +| ~SPC m m f~ | Macroexpand surrounding sexp | +| ~SPC m m r~ | Macroexpand region | + +** REPL + +| Key Binding | Description | +|-------------+------------------------------------------| +| ~SPC m s i~ | Start or switch to the REPL | +| ~SPC m s s~ | Select Scheme implementation | +| ~SPC m s b~ | Send buffer to the REPL | +| ~SPC m s B~ | Send buffer to the REPL and focus it | +| ~SPC m s f~ | Send definition to the REPL | +| ~SPC m s F~ | Send definition to the REPL and focus it | +| ~SPC m s e~ | Send last sexp to the REPL | +| ~SPC m s r~ | Send region to the REPL | +| ~SPC m s R~ | Send region to the REPL and focus it | + +** Evaluation + +| Key Binding | Description | +|-------------+---------------------------| +| ~SPC m e b~ | Evaluate the whole buffer | +| ~SPC m e e~ | Evaluate last sexp | +| ~SPC m e f~ | Evaluate current function | +| ~SPC m e l~ | Evaluate line | +| ~SPC m e r~ | Evaluate region | diff --git a/layers/+lang/scheme/config.el b/layers/+lang/scheme/config.el new file mode 100644 index 0000000..5e51dee --- /dev/null +++ b/layers/+lang/scheme/config.el @@ -0,0 +1,12 @@ +;;; config.el --- scheme Layer Configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(spacemacs|define-jump-handlers scheme-mode geiser-edit-symbol-at-point) diff --git a/layers/+lang/scheme/packages.el b/layers/+lang/scheme/packages.el new file mode 100644 index 0000000..23b62c7 --- /dev/null +++ b/layers/+lang/scheme/packages.el @@ -0,0 +1,83 @@ +;;; packages.el --- Scheme Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq scheme-packages + '( + company + geiser + ggtags + helm-gtags + )) + +(defun scheme/post-init-company () + ;; Geiser provides completion as long as company mode is loaded. + (spacemacs|add-company-hook scheme-mode)) + +(defun scheme/init-geiser () + (use-package geiser + :commands run-geiser + :init + (progn + (spacemacs/register-repl 'geiser 'geiser-mode-switch-to-repl "geiser")) + :config + (progn + (spacemacs/declare-prefix-for-mode 'scheme-mode "mc" "compiling") + (spacemacs/declare-prefix-for-mode 'scheme-mode "mg" "navigation") + (spacemacs/declare-prefix-for-mode 'scheme-mode "mh" "documentation") + (spacemacs/declare-prefix-for-mode 'scheme-mode "mi" "insertion") + (spacemacs/declare-prefix-for-mode 'scheme-mode "mm" "macroexpansion") + (spacemacs/declare-prefix-for-mode 'scheme-mode "ms" "repl") + + (spacemacs/set-leader-keys-for-major-mode 'scheme-mode + "'" 'geiser-mode-switch-to-repl + "," 'lisp-state-toggle-lisp-state + + "cc" 'geiser-compile-current-buffer + "cp" 'geiser-add-to-load-path + + "eb" 'geiser-eval-buffer + "ee" 'geiser-eval-last-sexp + "ef" 'geiser-eval-definition + "el" 'lisp-state-eval-sexp-end-of-line + "er" 'geiser-eval-region + + "gb" 'geiser-pop-symbol-stack + "gm" 'geiser-edit-module + "gn" 'next-error + "gN" 'previous-error + + "hh" 'geiser-doc-symbol-at-point + "hd" 'geiser-doc-look-up-manual + "hm" 'geiser-doc-module + "h<" 'geiser-xref-callers + "h>" 'geiser-xref-callees + + "il" 'geiser-insert-lambda + + "me" 'geiser-expand-last-sexp + "mf" 'geiser-expand-definition + "mx" 'geiser-expand-region + + "si" 'geiser-mode-switch-to-repl + "sb" 'geiser-eval-buffer + "sB" 'geiser-eval-buffer-and-go + "sf" 'geiser-eval-definition + "sF" 'geiser-eval-definition-and-go + "se" 'geiser-eval-last-sexp + "sr" 'geiser-eval-region + "sR" 'geiser-eval-region-and-go + "ss" 'geiser-set-scheme)))) + +(defun scheme/post-init-ggtags () + (add-hook 'scheme-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun scheme/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'scheme-mode)) diff --git a/layers/+lang/shaders/README.org b/layers/+lang/shaders/README.org new file mode 100644 index 0000000..dd64475 --- /dev/null +++ b/layers/+lang/shaders/README.org @@ -0,0 +1,22 @@ +#+TITLE: Shaders layer + +[[file:img/shaders.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + +* Description +This layer provides syntax highlighting for shader files. By default it will +provide highlighting for files ending in: +- =.fsh= +- =.vsh= +- =.glsl= +- =.vert= +- =.frag= +- =.geom= + +* Install +To use this configuration layer, add it to your =~.spacemacs=. You will need to +add =shaders= to the existing =dotspacemacs-configuration-layers= list in this +file. diff --git a/layers/+lang/shaders/img/shaders.png b/layers/+lang/shaders/img/shaders.png new file mode 100644 index 0000000..8efcb1a Binary files /dev/null and b/layers/+lang/shaders/img/shaders.png differ diff --git a/layers/+lang/shaders/packages.el b/layers/+lang/shaders/packages.el new file mode 100644 index 0000000..afdd475 --- /dev/null +++ b/layers/+lang/shaders/packages.el @@ -0,0 +1,17 @@ +;;; packages.el --- shaders layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Alan Love +;; URL: https://github.com/ell +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GLPv3 +(setq shaders-packages '(glsl-mode)) + +(defun shaders/init-glsl-mode () + "Initialize GLSL mode" + (use-package glsl-mode + :mode (("\\.fsh\\'" . glsl-mode) + ("\\.vsh\\'" . glsl-mode)))) diff --git a/layers/+lang/shell-scripts/README.org b/layers/+lang/shell-scripts/README.org new file mode 100644 index 0000000..c2bca5e --- /dev/null +++ b/layers/+lang/shell-scripts/README.org @@ -0,0 +1,41 @@ +#+TITLE: Shell Scripts layer + +[[file:img/fish.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#install][Install]] + - [[#linting][Linting]] + - [[#key-bindings][Key Bindings]] + +* Description + +This simple layer adds support for shell scripting. + +Supported scripting files: +- =.sh= +- =.fish=: [[https://github.com/fish-shell/fish-shell][fish shell]] + +*Note:* For Windows scripting see the layer =windows-scripts= + +** Features +- Auto-completion using [[https://github.com/Alexander-Miller/company-shell][company-shell]] +- =Sh= scripts linting using [[https://www.shellcheck.net/][shellcheck]] + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =shell-scripts= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Linting +In order to enable =sh= scripts linting, install [[https://www.shellcheck.net/][shellcheck]]. + +* Key Bindings + +| Key Binding | Description | +|-------------+-----------------------------------------------------------| +| ~SPC i !~ | insert shebang in a script file | +| ~SPC m \~ | insert end-of-line backslashes to the lines in the region | + + diff --git a/layers/+lang/shell-scripts/config.el b/layers/+lang/shell-scripts/config.el new file mode 100644 index 0000000..e27a985 --- /dev/null +++ b/layers/+lang/shell-scripts/config.el @@ -0,0 +1,16 @@ +;;; config.el --- Shell Scripts Layer Configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; variables +(spacemacs|defvar-company-backends sh-mode) +(spacemacs|defvar-company-backends fish-mode) + +(spacemacs|define-jump-handlers sh-mode) diff --git a/layers/+lang/shell-scripts/funcs.el b/layers/+lang/shell-scripts/funcs.el new file mode 100644 index 0000000..3ee1f44 --- /dev/null +++ b/layers/+lang/shell-scripts/funcs.el @@ -0,0 +1,20 @@ +;;; funcs.el --- Shell Scripts Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + +;; shebang + +(defun spacemacs/insert-shebang () + "Insert shebang line at the top of the file." + (interactive) + (require 'insert-shebang) + (insert-shebang-get-extension-and-insert + (file-name-nondirectory (buffer-file-name)))) diff --git a/layers/+lang/shell-scripts/img/fish.png b/layers/+lang/shell-scripts/img/fish.png new file mode 100644 index 0000000..deed738 Binary files /dev/null and b/layers/+lang/shell-scripts/img/fish.png differ diff --git a/layers/+lang/shell-scripts/packages.el b/layers/+lang/shell-scripts/packages.el new file mode 100644 index 0000000..04c189b --- /dev/null +++ b/layers/+lang/shell-scripts/packages.el @@ -0,0 +1,81 @@ +;;; packages.el --- Shell Scripts Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq shell-scripts-packages + '( + company + (company-shell :toggle (configuration-layer/package-usedp 'company)) + fish-mode + flycheck + ggtags + helm-gtags + insert-shebang + (sh-script :location built-in) + )) + +(defun shell-scripts/post-init-company () + (spacemacs|add-company-hook sh-mode) + (spacemacs|add-company-hook fish-mode)) + +(defun shell-scripts/init-company-shell () + (use-package company-shell + :defer t + :init + (progn + (push 'company-shell company-backends-sh-mode) + (push '(company-shell company-fish-shell) company-backends-fish-mode)))) + +(defun shell-scripts/post-init-flycheck () + (spacemacs/add-flycheck-hook 'sh-mode)) + +(defun shell-scripts/init-fish-mode () + (use-package fish-mode + :defer t)) + +(defun shell-scripts/init-sh-script () + (use-package sh-script + :defer t + :init + (progn + (spacemacs/set-leader-keys-for-major-mode 'sh-mode + "\\" 'sh-backslash-region) + + ;; Use sh-mode when opening `.zsh' files, and when opening Prezto runcoms. + (dolist (pattern '("\\.zsh\\'" + "zlogin\\'" + "zlogout\\'" + "zpreztorc\\'" + "zprofile\\'" + "zshenv\\'" + "zshrc\\'")) + (add-to-list 'auto-mode-alist (cons pattern 'sh-mode))) + + (defun spacemacs//setup-shell () + (when (and buffer-file-name + (string-match-p "\\.zsh\\'" buffer-file-name)) + (sh-set-shell "zsh"))) + (add-hook 'sh-mode-hook 'spacemacs//setup-shell)))) + +(defun shell-scripts/post-init-ggtags () + (add-hook 'sh-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun shell-scripts/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'sh-mode)) + +(defun shell-scripts/init-insert-shebang () + (use-package insert-shebang + :defer t + :init + (progn + (spacemacs/set-leader-keys "i!" 'spacemacs/insert-shebang) + ;; we don't want to insert shebang lines automatically + (remove-hook 'find-file-hook 'insert-shebang)))) + diff --git a/layers/+lang/sml/README.org b/layers/+lang/sml/README.org new file mode 100644 index 0000000..4a5cee4 --- /dev/null +++ b/layers/+lang/sml/README.org @@ -0,0 +1,41 @@ +#+TITLE: SML layer + +[[file:img/sml.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key Bindings]] + - [[#form-completion][Form Completion]] + - [[#repl][REPL]] + +* Description + +Adds support for the [[http://www.smlnj.org][SML]] programming language. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =sml= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key Bindings + +** Form Completion + +| Key Binding | Description | +|-------------+-------------------------------------------------------------------------------------------| +| ~M-SPC~ | Inserts a space and completes the form before the cursor. | +| ~\vert~ | Inserts a pipe and adds a double arrow or copies the function name. Generally just works. | + +** REPL + +| Key Binding | Description | +|-------------+-------------------------------------------------------------------| +| ~SPC m s b~ | Send buffer to REPL | +| ~SPC m s B~ | Send buffer to REPL and switch to REPL buffer in =insert state= | +| ~SPC m s f~ | Send function to REPL | +| ~SPC m s F~ | Send function to REPL and switch to REPL buffer in =insert state= | +| ~SPC m s i~ | Run the sml REPL or switch to it if the REPL is already running | +| ~SPC m s r~ | Send region to REPL | +| ~SPC m s R~ | Send region to REPL and switch to REPL buffer in =insert state= | +| ~SPC m s s~ | Run the sml REPL or switch to it if the REPL is already running | diff --git a/layers/+lang/sml/img/sml.png b/layers/+lang/sml/img/sml.png new file mode 100644 index 0000000..79d48c2 Binary files /dev/null and b/layers/+lang/sml/img/sml.png differ diff --git a/layers/+lang/sml/packages.el b/layers/+lang/sml/packages.el new file mode 100644 index 0000000..92785cd --- /dev/null +++ b/layers/+lang/sml/packages.el @@ -0,0 +1,70 @@ +;;; packages.el --- sml Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Keith Simmons +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq sml-packages + '( + sml-mode + ob-sml + smartparens + )) + +(defun sml/init-sml-mode () + (use-package sml-mode + :mode ("\\.\\(sml\\|sig\\)\\'" . sml-mode) + :defer t + :commands run-sml + :init (spacemacs/register-repl 'sml-mode 'run-sml "sml") + :config + (progn + (defun spacemacs/sml-prog-proc-send-buffer-and-focus () + "Send buffer to REPL and switch to it in `insert state'." + (interactive) + (sml-prog-proc-send-buffer t) + (evil-insert-state)) + + (defun spacemacs/sml-prog-proc-send-region-and-focus (start end) + "Send region to REPL and switch to it in `insert state'." + (interactive "r") + (sml-prog-proc-send-region start end t) + (evil-insert-state)) + + (defun spacemacs/sml-send-function-and-focus () + "Send function at point to REPL and switch to it in `insert state'." + (interactive) + (sml-send-function t) + (evil-insert-state)) + + (spacemacs/set-leader-keys-for-major-mode 'sml-mode + ;; REPL + "'" 'run-sml + "sb" 'sml-prog-proc-send-buffer + "sB" 'spacemacs/sml-prog-proc-send-buffer-and-focus + "sf" 'sml-send-function + "sF" 'spacemacs/sml-send-function-and-focus + "si" 'run-sml + "sr" 'sml-prog-proc-send-region + "sR" 'spacemacs/sml-prog-proc-send-region-and-focus + "ss" 'run-sml) + (define-key sml-mode-map (kbd "RET") 'reindent-then-newline-and-indent) + (define-key sml-mode-map (kbd "M-SPC") 'sml-electric-space) + (define-key sml-mode-map (kbd "|") 'sml-electric-pipe)))) + +(defun sml/post-init-smartparens () + (with-eval-after-load 'smartparens + ;; don't auto-close apostrophes (type 'a = foo) and backticks (`Foo) + (sp-local-pair 'sml-mode "'" nil :actions nil) + (sp-local-pair 'sml-mode "`" nil :actions nil))) + +(defun sml/init-ob-sml () + (use-package ob-sml + :defer t + :init + (org-babel-do-load-languages 'org-babel-do-load-languages '(sml . t)))) diff --git a/layers/+lang/sql/README.org b/layers/+lang/sql/README.org new file mode 100644 index 0000000..fba6062 --- /dev/null +++ b/layers/+lang/sql/README.org @@ -0,0 +1,60 @@ +#+TITLE: SQL layer + +[[file:img/sql.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + - [[#highlighting][Highlighting]] + - [[#inferior-process-interactions-sqli][Inferior Process Interactions (SQLi)]] + - [[#send-sql-queries-to-sqli][Send SQL queries to SQLi:]] + - [[#sqli-buffer][SQLi buffer]] + +* Description + +This layer adds key bindings and configuration for =sql-mode=, which manages +interactive SQL buffers and highlights a wide range of SQL dialects. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =sql= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key bindings + +** Highlighting + +| Key Binding | Description | +|-------------+-----------------------------------| +| ~SPC m h k~ | select a SQL dialect to highlight | + +** Inferior Process Interactions (SQLi) + +| Key Binding | Description | +|-------------+-----------------------------| +| ~SPC m b b~ | show the SQLi buffer name | +| ~SPC m b s~ | set the SQLi buffer | +| ~SPC m l a~ | List all objects | +| ~SPC m l t~ | list all objects in a table | + +*** Send SQL queries to SQLi: + +| Key Binding | Description | +|-------------+---------------------------------------------------------------------------------------| +| ~SPC m s b~ | Send the whole buffer to the SQLi buffer | +| ~SPC m s B~ | Send the whole buffer to the SQLi buffer and switch to it in =insert state= | +| ~SPC m s i~ | Start the SQLi process | +| ~SPC m s f~ | Send the paragraph around point to the SQLi buffer | +| ~SPC m s F~ | Send the paragraph around point to the SQLi buffer and switch to it in =insert state= | +| ~SPC m s q~ | Prompt for a string to send to the SQLi buffer | +| ~SPC m s Q~ | Prompt for a string to send to the SQLi buffer and switch to it in =insert state= | +| ~SPC m s r~ | Send the selected region to the SQLi buffer | +| ~SPC m s R~ | Send the selected region to the SQLi buffer and switch to it in =insert state= | + +** SQLi buffer + +| Key Binding | Description | +|-------------+--------------------------------------------------------------| +| ~SPC m b r~ | rename buffer (follow up in the SQL buffer with ~SPC m b s~) | +| ~SPC m b S~ | save the current connection | diff --git a/layers/+lang/sql/img/sql.png b/layers/+lang/sql/img/sql.png new file mode 100644 index 0000000..f5db89e Binary files /dev/null and b/layers/+lang/sql/img/sql.png differ diff --git a/layers/+lang/sql/packages.el b/layers/+lang/sql/packages.el new file mode 100644 index 0000000..45c4e8f --- /dev/null +++ b/layers/+lang/sql/packages.el @@ -0,0 +1,119 @@ +;;; packages.el --- sql Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Brian Hicks +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq sql-packages '(sql sql-indent)) + +(defun sql/init-sql () + (use-package sql + :defer t + :init (spacemacs/register-repl 'sql 'spacemacs/sql-start "sql") + :config + (progn + (setq spacemacs-sql-highlightable sql-product-alist + spacemacs-sql-startable (remove-if-not + (lambda (product) (sql-get-product-feature (car product) :sqli-program)) + sql-product-alist) + + ;; should not set this to anything else than nil + ;; the focus of SQLi is handled by spacemacs conventions + sql-pop-to-buffer-after-send-region nil) + + (defun spacemacs//sql-source (products) + "return a source for helm selection" + `((name . "SQL Products") + (candidates . ,(mapcar (lambda (product) + (cons (sql-get-product-feature (car product) :name) + (car product))) + products)) + (action . (lambda (candidate) (helm-marked-candidates))))) + + (defun spacemacs/sql-highlight () + "set SQL dialect-specific highlighting" + (interactive) + (let ((product (car (helm + :sources (list (spacemacs//sql-source spacemacs-sql-highlightable)))))) + (sql-set-product product))) + + (defun spacemacs/sql-start () + "set SQL dialect-specific highlighting and start inferior SQLi process" + (interactive) + (let ((product (car (helm + :sources (list (spacemacs//sql-source spacemacs-sql-startable)))))) + (sql-set-product product) + (sql-product-interactive product))) + + (defun spacemacs/sql-send-string-and-focus () + "Send a string to SQLi and switch to SQLi in `insert state'." + (interactive) + (let ((sql-pop-to-buffer-after-send-region t)) + (call-interactively 'sql-send-string) + (evil-insert-state))) + + (defun spacemacs/sql-send-buffer-and-focus () + "Send the buffer to SQLi and switch to SQLi in `insert state'." + (interactive) + (let ((sql-pop-to-buffer-after-send-region t)) + (sql-send-buffer) + (evil-insert-state))) + + (defun spacemacs/sql-send-paragraph-and-focus () + "Send the paragraph to SQLi and switch to SQLi in `insert state'." + (interactive) + (let ((sql-pop-to-buffer-after-send-region t)) + (sql-send-paragraph) + (evil-insert-state))) + + (defun spacemacs/sql-send-region-and-focus (start end) + "Send region to SQLi and switch to SQLi in `insert state'." + (interactive "r") + (let ((sql-pop-to-buffer-after-send-region t)) + (sql-send-region start end) + (evil-insert-state))) + + (spacemacs/set-leader-keys-for-major-mode 'sql-mode + "'" 'spacemacs/sql-start + + ;; sqli buffer + "bb" 'sql-show-sqli-buffer + "bs" 'sql-set-sqli-buffer + + ;; dialects + "hk" 'spacemacs/sql-highlight + + ;; interactivity + "sb" 'sql-send-buffer + "sB" 'spacemacs/sql-send-buffer-and-focus + "si" 'spacemacs/sql-start + ;; paragraph gets "f" here because they can be assimilated to functions. + ;; If you separate your commands in a SQL file, this key will send the + ;; command around point, which is what you probably want. + "sf" 'sql-send-paragraph + "sF" 'spacemacs/sql-send-paragraph-and-focus + "sq" 'sql-send-string + "sQ" 'spacemacs/sql-send-string-and-focus + "sr" 'sql-send-region + "sR" 'spacemacs/sql-send-region-and-focus + + ;; listing + "la" 'sql-list-all + "lt" 'sql-list-table) + + (spacemacs/set-leader-keys-for-major-mode 'sql-interactive-mode + ;; sqli buffer + "br" 'sql-rename-buffer + "bS" 'sql-save-connection) + + (add-hook 'sql-interactive-mode-hook + (lambda () (toggle-truncate-lines t)))))) + +(defun sql/init-sql-indent () + (use-package sql-indent + :defer t)) diff --git a/layers/+lang/swift/README.org b/layers/+lang/swift/README.org new file mode 100644 index 0000000..13e189e --- /dev/null +++ b/layers/+lang/swift/README.org @@ -0,0 +1,62 @@ +#+TITLE: Swift layer + +[[file:img/swift.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#usage-information][Usage information]] + - [[#key-bindings][Key bindings]] + - [[#swift-mode][swift-mode]] + - [[#swift-repl-mode][swift-repl-mode]] + +* Description +This layer adds support for Apple's Swift programming language, used as a +general purpose scripting language. + +It relies on the [[https://github.com/chrisbarrett/swift-mode][swift-mode]] major-mode* for Emacs 24.4 or later, to provide the +following features: + +- Syntax highlighting +- Indentation +- Code navigation using ~imenu~ (built-in) +- Automatic syntax checking with ~flycheck~ (available with the + ~syntax-checking~ layer) + +* Install +First check that you are able to run this from the command line: + +On OS X: +#+BEGIN_SRC sh + xcrun swift +#+END_SRC + +Then to use this configuration layer, add it to your =~/.spacemacs=. You will +need to add =swift= to the existing =dotspacemacs-configuration-layers= list in +this file. + +* Usage information +Unless configured by the user, the REPL will be invoked using the command ~xcrun +swift~. +You can launch the REPL using the keybinding ~SPC m s s~ (or ~C-c C-z~). +The universal prefix ~SPC u~ (~C-u~) may be used to modify command invocation. + +* Key bindings +** swift-mode + +| Key bindings | Description | +|--------------+------------------------| +| ~SPC m s s~ | swift-mode-run-repl | +| ~SPC m s b~ | swift-mode-send-buffer | +| ~SPC m s r~ | swift-mode-send-region | + +Notes: +1. ~swift-mode-run-repl~ will run or switch to an existing REPL. +2. To edit the command invocation, prefix with ~SPC u~ (or ~C-u~). +3. Emacs key bindings in use are the those set by the package. + +** swift-repl-mode + +| Key bindings | Description | +|--------------+-----------------------------| +| ~SPC m s s~ | swift-repl-mode-switch-back | diff --git a/layers/+lang/swift/img/swift.png b/layers/+lang/swift/img/swift.png new file mode 100644 index 0000000..cd9e5f9 Binary files /dev/null and b/layers/+lang/swift/img/swift.png differ diff --git a/layers/+lang/swift/packages.el b/layers/+lang/swift/packages.el new file mode 100644 index 0000000..4d5ecdf --- /dev/null +++ b/layers/+lang/swift/packages.el @@ -0,0 +1,61 @@ +;;; packages.el --- swift Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Uri Sharf +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq swift-packages + '( + flycheck + swift-mode + )) + +(defun swift/post-init-flycheck () + (spacemacs|use-package-add-hook flycheck + :post-config (add-to-list 'flycheck-checkers 'swift))) + +(defun swift/init-swift-mode () + (use-package swift-mode + :mode ("\\.swift\\'" . swift-mode) + :defer t + :init + (progn + (spacemacs|advise-commands "store-initial-buffer-name" + (swift-mode-run-repl) around + "Store current buffer bane in bufffer local variable, +before activiting or switching to REPL." + (let ((initial-buffer (current-buffer))) + ad-do-it + (with-current-buffer swift-repl-buffer + (setq swift-repl-mode-previous-buffer initial-buffer)))) + + (defun spacemacs/swift-repl-mode-hook () + "Hook to run when starting an interactive swift mode repl" + (make-variable-buffer-local 'swift-repl-mode-previous-buffer)) + (add-hook 'swift-repl-mode-hook 'spacemacs/swift-repl-mode-hook) + + (defun spacemacs/swift-repl-mode-switch-back () + "Switch back to from REPL to editor." + (interactive) + (if swift-repl-mode-previous-buffer + (switch-to-buffer-other-window swift-repl-mode-previous-buffer) + (message "No previous buffer")))) + :config + (progn + (spacemacs/set-leader-keys-for-major-mode 'swift-mode + "sS" 'swift-mode-run-repl ; run or switch to an existing swift repl + "ss" 'swift-mode-run-repl + "sb" 'swift-mode-send-buffer + "sr" 'swift-mode-send-region) + + (with-eval-after-load 'swift-repl-mode-map + ;; Switch back to editor from REPL + (spacemacs/set-leader-keys-for-major-mode 'swift-repl-mode + "ss" 'spacemacs/swift-repl-mode-switch-back) + (define-key swift-repl-mode-map + (kbd "C-c C-z") 'spacemacs/swift-repl-mode-switch-back))))) diff --git a/layers/+lang/typescript/README.org b/layers/+lang/typescript/README.org new file mode 100644 index 0000000..be12e75 --- /dev/null +++ b/layers/+lang/typescript/README.org @@ -0,0 +1,107 @@ +#+TITLE: TypeScript layer + +[[file:img/TypeScript.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#pre-requisites][Pre-requisites]] + - [[#layer][Layer]] + - [[#notes][Notes]] + - [[#key-bindings][Key bindings]] + - [[#typescript-major-mode][Typescript Major Mode]] + - [[#reference-major-mode][Reference Major Mode]] + +* Description + +This layer adds support for TypeScript and TSX editing. + +This layer provides: +- Eldoc-mode +- Documentation at point +- Auto complete +- Flycheck with linter +- Jump to definition, Jump to type definition +- Find occurrences (Imenu-mode) +- Rename symbol +- tsx mode +- formatting +- TypeScript playground integration + +* Install +** Pre-requisites +You will need =node.js v0.12.0= or greater + +If you want linting run: =npm install -g typescript= =npm install -g tslint= + +If you want to use typescript-formatter for formatting run: =npm install -g typescript-formatter= + +For best results, make sure that the =auto-completion= (company) and =html= layers are enabled. + +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =typescript= to the existing =dotspacemacs-configuration-layers= list in this +file. + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers '(typescript)) +#+END_SRC + +If you need formatting on save: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers '( + (typescript :variables + typescript-fmt-on-save t))) +#+END_SRC + +You can choose formatting tool: + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers '( + (typescript :variables + typescript-fmt-tool 'typescript-formatter))) +#+END_SRC + +Default is 'tide . + +** Notes + +This layer uses: +- [[https://github.com/ananthakumaran/tide][tide]] +- [[https://github.com/Simplify/flycheck-typescript-tslint][flycheck-typescript-tslint]] +- [[https://github.com/vvakame/typescript-formatter][typescript-formatter]] - optional. + +*The tools use configuration files. You can learn more in their documentation.* + +Make sure to add [[https://github.com/Microsoft/TypeScript/wiki/tsconfig.json][tsconfig.json]] in the project root folder. + +tsserver mangles output sometimes [[https://github.com/Microsoft/TypeScript/issues/2758][issue - #2758]], which will result in json parse error. Try node version 0.12.x if you get this error. + +Send to playground requires browser. + +Currently tsserver doesn't pickup tsconfig.json file changes. You might need to restart server after editing it. + +* Key bindings + +** Typescript Major Mode + +| Key Binding | Description | +|-------------+--------------------------------------------------------------| +| ~SPC m =~ | reformat the buffer | +| ~SPC m g b~ | jump back | +| ~SPC m g g~ | jump to entity's definition | +| ~SPC m g t~ | jump to entity's type definition | +| ~SPC m g u~ | references | +| ~SPC m h h~ | documentation at point | +| ~SPC m r r~ | rename symbol | +| ~SPC m s p~ | send selected region or current buffer to the web playground | +| ~SPC m S r~ | restart server | + +** Reference Major Mode + +| Key Binding | Description | +|-------------+-------------------------| +| ~C-j~ | find previous reference | +| ~C-k~ | find next reference | +| ~C-l~ | goto reference | diff --git a/layers/+lang/typescript/config.el b/layers/+lang/typescript/config.el new file mode 100644 index 0000000..06af5b7 --- /dev/null +++ b/layers/+lang/typescript/config.el @@ -0,0 +1,23 @@ +;;; config.el --- Typescript Layer Configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(spacemacs|defvar-company-backends typescript-mode) + +(defvar typescript-fmt-on-save nil + "Run formatter on buffer save.") + +(defvar typescript-fmt-tool 'tide + "The name of the tool to be used +for TypeScript source code formatting. +Currently avaliable 'tide (default) +and 'typescript-formatter .") + +(spacemacs|define-jump-handlers typescript-mode) diff --git a/layers/+lang/typescript/funcs.el b/layers/+lang/typescript/funcs.el new file mode 100644 index 0000000..0348884 --- /dev/null +++ b/layers/+lang/typescript/funcs.el @@ -0,0 +1,66 @@ +;;; funcs.el --- TypeScript Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun typescript/tsfmt-format-buffer () + "Format buffer with tsfmt." + (interactive) + (if (executable-find "tsfmt") + (let* ((tmpfile (make-temp-file "~fmt-tmp" nil ".ts")) + (coding-system-for-read 'utf-8) + (coding-system-for-write 'utf-8) + (outputbuf (get-buffer-create "*~fmt-tmp.ts*"))) + (unwind-protect + (progn + (with-current-buffer outputbuf (erase-buffer)) + (write-region nil nil tmpfile) + (if (zerop (apply 'call-process "tsfmt" nil outputbuf nil + (list (format + "--baseDir='%s' --" + default-directory) + tmpfile))) + (let ((p (point))) + (save-excursion + (with-current-buffer (current-buffer) + (erase-buffer) + (insert-buffer-substring outputbuf))) + (goto-char p) + (message "formatted.") + (kill-buffer outputbuf)) + (progn + (message "Formatting failed!") + (display-buffer outputbuf))) + (progn + (delete-file tmpfile))))) + (error "tsfmt not found. Run \"npm install -g typescript-formatter\""))) + +(defun typescript/format () + "Call formatting tool specified in `typescript-fmt-tool'." + (interactive) + (cond + ((eq typescript-fmt-tool 'typescript-formatter) + (call-interactively 'typescript/tsfmt-format-buffer)) + ((eq typescript-fmt-tool 'tide) + (call-interactively 'tide-format)) + (t (error (concat "%s isn't valid typescript-fmt-tool value." + " It should be 'tide or 'typescript-formatter." + (symbol-name typescript-fmt-tool)))))) + +(defun typescript/fmt-before-save-hook () + (add-hook 'before-save-hook 'typescript/format t t)) + +(defun typescript/open-region-in-playground (start end) + "Open selected region in http://www.typescriptlang.org/Playground + If nothing is selected - open the whole current buffer." + (interactive (if (use-region-p) + (list (region-beginning) (region-end)) + (list (point-min) (point-max)))) + (browse-url (concat "http://www.typescriptlang.org/Playground#src=" + (url-hexify-string (buffer-substring-no-properties start end))))) diff --git a/layers/+lang/typescript/img/TypeScript.png b/layers/+lang/typescript/img/TypeScript.png new file mode 100644 index 0000000..6b8bdb5 Binary files /dev/null and b/layers/+lang/typescript/img/TypeScript.png differ diff --git a/layers/+lang/typescript/packages.el b/layers/+lang/typescript/packages.el new file mode 100644 index 0000000..313cb36 --- /dev/null +++ b/layers/+lang/typescript/packages.el @@ -0,0 +1,87 @@ +;;; packages.el --- typescript Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Chris Bowdon +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq typescript-packages + '( + company + flycheck + tide + typescript-mode + web-mode + )) + +(defun typescript/post-init-company () + (spacemacs|add-company-hook typescript-mode)) + +(defun typescript/post-init-flycheck () + (spacemacs/add-flycheck-hook 'typescript-mode)) + +(defun typescript/init-tide () + (use-package tide + :defer t + :commands (typescript/jump-to-type-def) + :init + (progn + (evilified-state-evilify tide-references-mode tide-references-mode-map + (kbd "C-k") 'tide-find-previous-reference + (kbd "C-j") 'tide-find-next-reference + (kbd "C-l") 'tide-goto-reference) + + (add-hook 'typescript-mode-hook 'tide-setup) + (add-hook 'typescript-mode-hook 'eldoc-mode) + + (add-to-list 'spacemacs-jump-handlers-typescript-mode 'tide-jump-to-definition) + + (push 'company-tide company-backends-typescript-mode)) + :config + (progn + (spacemacs/declare-prefix-for-mode 'typescript-mode "mg" "goto") + (spacemacs/declare-prefix-for-mode 'typescript-mode "mh" "help") + (spacemacs/declare-prefix-for-mode 'typescript-mode "mn" "name") + (spacemacs/declare-prefix-for-mode 'typescript-mode "mr" "rename") + (spacemacs/declare-prefix-for-mode 'typescript-mode "mS" "server") + (spacemacs/declare-prefix-for-mode 'typescript-mode "ms" "send") + + (defun typescript/jump-to-type-def() + (interactive) + (tide-jump-to-definition t)) + + (spacemacs/set-leader-keys-for-major-mode 'typescript-mode + "gb" 'tide-jump-back + "gt" 'typescript/jump-to-type-def + "gu" 'tide-references + "hh" 'tide-documentation-at-point + "rr" 'tide-rename-symbol + "Sr" 'tide-restart-server)))) + +(defun typescript/post-init-web-mode () + (add-to-list 'auto-mode-alist '("\\.tsx\\'" . web-mode)) + ;; FIXME -- this is not good! + (add-hook 'web-mode-hook + (lambda () + (when (and (buffer-file-name) + (string-equal "tsx" (file-name-extension (buffer-file-name)))) + (tide-setup) + (flycheck-mode +1) + (eldoc-mode +1) + (when (configuration-layer/package-usedp 'company) + (company-mode-on)))))) + +(defun typescript/init-typescript-mode () + (use-package typescript-mode + :defer t + :config + (progn + (when typescript-fmt-on-save + (add-hook 'typescript-mode-hook 'typescript/fmt-before-save-hook)) + (spacemacs/set-leader-keys-for-major-mode 'typescript-mode + "=" 'typescript/format + "sp" 'typescript/open-region-in-playground)))) diff --git a/layers/+lang/vimscript/README.org b/layers/+lang/vimscript/README.org new file mode 100644 index 0000000..4fb4019 --- /dev/null +++ b/layers/+lang/vimscript/README.org @@ -0,0 +1,15 @@ +#+TITLE: Vimscript language layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + +* Description + +This layer adds syntax highlighting support for vim filetypes, in addition to +the pentadactyl firefox extension. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =vimscript= to the existing =dotspacemacs-configuration-layers= list in this +file. diff --git a/layers/+lang/vimscript/config.el b/layers/+lang/vimscript/config.el new file mode 100644 index 0000000..08a0956 --- /dev/null +++ b/layers/+lang/vimscript/config.el @@ -0,0 +1,14 @@ +;;; packages.el --- Vimscript Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; variables + +(spacemacs|define-jump-handlers vimrc-mode) diff --git a/layers/+lang/vimscript/packages.el b/layers/+lang/vimscript/packages.el new file mode 100644 index 0000000..2a344bb --- /dev/null +++ b/layers/+lang/vimscript/packages.el @@ -0,0 +1,48 @@ +;;; packages.el --- vimscript Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq vimscript-packages + '( + vimrc-mode + ggtags + helm-gtags + dactyl-mode + )) + +(defun vimscript/init-vimrc-mode () + "Initialize vimrc package" + (use-package vimrc-mode + :mode "\\.vim[rc]?\\'" + :mode "_vimrc\\'" + :defer t + :init + (progn + (defun spacemacs//vimrc-mode-hook () + "Hooked function for `vimrc-mode-hook'." + (highlight-numbers-mode -1) + (rainbow-delimiters-mode-disable)) + (add-hook 'vimrc-mode-hook 'spacemacs//vimrc-mode-hook)))) + +(defun vimscript/init-dactyl-mode () + (use-package dactyl-mode + :mode "pentadactylrc\\'" + :mode "vimperatorrc\\'" + :mode "_pentadactylrc\\'" + :mode "_vimperatorrc\\'" + :mode "\\.penta\\'" + :mode "\\.vimp\\'" + :defer t)) + +(defun vimscript/post-init-ggtags () + (add-hook 'vimrc-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun vimscript/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'vimrc-mode)) diff --git a/layers/+lang/windows-scripts/README.org b/layers/+lang/windows-scripts/README.org new file mode 100644 index 0000000..67f9e2c --- /dev/null +++ b/layers/+lang/windows-scripts/README.org @@ -0,0 +1,39 @@ +#+TITLE: Windows Scripting layer + +[[file:img/ps.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key Bindings]] + - [[#powershell][Powershell]] + - [[#batch-dosel][Batch (dos.el)]] + +* Description +This simple layer adds support for the Powershell scripting language as well +as support for batch files. + +Supported windows scription extensions: +- =.ps1=: [[https://github.com/jschaf/powershell.el][powershell]] +- =.bat=: [[http://www.emacswiki.org/emacs/dos.el][dos.el]] + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =windows-scripts= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key Bindings +** Powershell +No useful bindings. + +** Batch (dos.el) + +| Key Binding | Description | +|-------------+--------------------------------------| +| ~SPC m D~ | ask for a command and display help | +| ~SPC m e b~ | evaluate buffer | +| ~SPC m e B~ | evaluate buffer with args | +| ~SPC m s~ | insert separator =&= | +| ~SPC m t~ | mini snippet to start a batch script | +| ~SPC m T~ | big snippet to start a batch script | +| ~SPC m z~ | toggle outline | diff --git a/layers/+lang/windows-scripts/config.el b/layers/+lang/windows-scripts/config.el new file mode 100644 index 0000000..c73132f --- /dev/null +++ b/layers/+lang/windows-scripts/config.el @@ -0,0 +1,14 @@ +;;; packages.el --- Windows Scripts Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; variables + +(spacemacs|define-jump-handlers dos-mode) diff --git a/layers/+lang/windows-scripts/img/ps.png b/layers/+lang/windows-scripts/img/ps.png new file mode 100644 index 0000000..7fcf3db Binary files /dev/null and b/layers/+lang/windows-scripts/img/ps.png differ diff --git a/layers/+lang/windows-scripts/local/dos/dos.el b/layers/+lang/windows-scripts/local/dos/dos.el new file mode 100644 index 0000000..a81a71e --- /dev/null +++ b/layers/+lang/windows-scripts/local/dos/dos.el @@ -0,0 +1,255 @@ +;;; dos.el --- major mode for editing Dos scripts (batch files) + +;; Copyright (C) 2003, 2008, 2009, 2010, 2011, 2012, 2013 Arni Magnusson + +;; Author: Arni Magnusson +;; Version: 2.18 +;; Keywords: languages +;; URL: http://emacswiki.org/emacs/dos.el + +(defconst dos-mode-version "2.18" "Dos Mode version number.") + +;;; Commentary: +;; +;; Major mode for editing Dos scripts. Provides syntax highlighting, templates, and smaller tools. The syntax groups for +;; highlighting are: +;; +;; Face Example +;; dos-label-face :LABEL +;; font-lock-comment-face rem +;; font-lock-builtin-face copy +;; font-lock-keyword-face goto +;; font-lock-warning-face cp +;; font-lock-constant-face [call] prog +;; font-lock-variable-name-face %var% +;; font-lock-type-face -option +;; +;; Installation: +;; +;; 1. Copy this file (dos.el) to a directory in `load-path', or edit .emacs to add the directory to `load-path': +;; (add-to-list 'load-path "mypath/dos") +;; 2. Byte-compile this file to dos.elc for faster startup: +;; M-x byte-compile-file +;; 3. Edit .emacs so that `dos-mode' is autoloaded and assigned to *.bat files: +;; (autoload 'dos-mode "dos" "Edit Dos scripts." t) +;; (add-to-list 'auto-mode-alist '("\\.bat$" . dos-mode)) +;; +;; Customization: +;; +;; See documentation of variable `dos-mode-hook' and function `dos-outline' for ideas. +;; +;; Usage: +;; +;; See documentation of function `dos-mode'. +;; +;; Acknowledgements: +;; +;; Inspired by `batch-mode' (Agnar Renolen) and `cmd-mode' (Tadamegu Furukawa). + +;;; History: +;; +;; 22 Jan 2013 2.18 Moved keywords "mkdir" and "rmdir" from `font-lock-warning-face' to `font-lock-builtin-face'. +;; 30 Mar 2012 2.17 Improved documentation. +;; 14 Feb 2011 2.16 Improved highlighting of variable names. +;; 20 Sep 2010 2.15 Changed :LABEL highlighting to new `dos-label-face'. Improved highlighting of variable names. +;; 8 Jul 2010 2.14 Added user function `dos-mode-version'. +;; 29 Jun 2010 2.13 Added keyword "erase". +;; 16 Apr 2010 2.12 Added ;;;###autoload cookie. +;; 29 Sep 2009 2.11 Improved highlighting of strings. +;; 18 Sep 2009 2.10 Improved highlighting of comments. +;; 27 May 2009 2.9 Improved documentation. +;; 26 May 2009 2.8 Added user function `dos-help-mode'. Renamed user function `dos-help' to `dos-help-cmd'. Added +;; internal variable `dos-menu', providing GUI menu. +;; 18 May 2009 2.7 Improved highlighting of scripts following call and goto. +;; 23 Apr 2009 2.6 Improved highlighting of --options. +;; 21 Apr 2009 2.5 Improved highlighting of variable names. +;; 24 Mar 2009 2.4 Improved highlighting of scripts/labels following call and goto. +;; 18 Mar 2009 2.3 Added support for @rem highlighting. Improved highlighting of -options and scripts/labels following +;; call and goto. +;; 11 Mar 2009 2.2 Added user functions `dos-help', `dos-run', and `dos-run-args'. Improved highlighting of scripts +;; and labels following call and goto. +;; 10 Mar 2009 2.1 Added keywords "at", "attrib", "cd", "cmd", "color", "doskey", "path", "popd", "prompt", "pushd", +;; "sort", and "start". Added support for highlighting /options. +;; 9 Mar 2009 2.0 Complete rewrite. Added user functions `dos-outline' and `dos-sep'. Added internal variables +;; `dos-font-lock-keywords', `dos-mode-abbrev-table', `dos-mode-map', and `dos-mode-syntax-table'. +;; Added local variables `comment-start', `imenu-generic-expression', and `outline-regexp'. Added +;; keyword "copy". Added support for ::comment highlighting. Added commentary on installation, +;; customization, and usage. +;; 18 Feb 2009 1.1 Changed face names, added keyword "cls", and removed `dos-template' line containing "[-help]". +;; 5 Dec 2008 1.0 Added support for underscored_variable highlighting. +;; 22 Aug 2003 0.9 Created main function `dos-mode', user variable `dos-mode-hook', user functions `dos-template' and +;; `dos-template-mini', and local variable `font-lock-defaults'. + +;;; Code: + +;; 1 Preamble + +(require 'outline) +(defgroup dos nil "Major mode for editing Dos scripts." :tag "Dos" :group 'languages) + +;; 2 User variables + +(defcustom dos-mode-hook nil + "Hook for `dos-mode'.\n +If you want to set syntax colors or keybindings, here is an example that does +that:\n +\(defun my-dos-hook () + (set-face-attribute 'font-lock-doc-face nil + :foreground \"black\" :weight 'bold) + (local-set-key [down-mouse-3] 'imenu)) +\(add-hook 'dos-mode-hook 'my-dos-hook)" + :tag "Hook" + :type 'hook + :group 'dos) +(defface dos-label-face '((t :weight bold)) "Font Lock mode face used to highlight Dos labels." :group 'dos) + +;; 3 Internal variables + +(defvar dos-font-lock-keywords + (eval-when-compile + (let ((COMMANDS + '("at" "attrib" "cd" "cls" "color" "copy" "date" "defined" "del" "dir" + "doskey" "echo" "endlocal" "erase" "exist" "fc" "find" "md" "mkdir" "more" + "move" "path" "pause" "popd" "prompt" "pushd" "ren" "rd" "rmdir" "set" + "setlocal" "shift" "sort" "time" "title" "type" "xcopy")) + (CONTROLFLOW + '("call" "cmd" "do" "else" "equ" "exit" "for" "geq" "goto" "gtr" + "if" "in" "leq" "lss" "neq" "not" "start")) + (LINUX + '("cat" "cp" "ls" "mv" "rm"))) + (list + '("\\<\\(call\\|goto\\)\\>[ \t]+%?\\([A-Za-z0-9-_\\:.]+\\)%?" (2 font-lock-constant-face t)) + '("^[ \t]*\\(@?rem\\>\\|::\\).*" (0 font-lock-comment-face t)) + '("^:[^:].*" . 'dos-label-face) + '("\\<\\(defined\\|set\\)\\>[ \t]*\\(\\w+\\)" (2 font-lock-variable-name-face)) + '("%\\(\\w+\\)%?" (1 font-lock-variable-name-face)) + '("!\\(\\w+\\)!?" (1 font-lock-variable-name-face)) ; delayed-expansion !variable! + '("[ =][-/]+\\(\\w+\\)" (1 font-lock-type-face append)) + (cons (regexp-opt COMMANDS 'words) font-lock-builtin-face) + (cons (regexp-opt CONTROLFLOW 'words) font-lock-keyword-face) + (cons (regexp-opt LINUX 'words) font-lock-warning-face))))) +(defvar dos-menu + '("Dos" + ["Run" dos-run ] ; :help "Run script" + ["Run with Args" dos-run-args ] ; :help "Run script with args" + "--" + ["Imenu" imenu ] ; :help "Navigate with imenu" + "--" + ["Template" dos-template ] ; :help "Insert template" + ["Mini Template" dos-template-mini] ; :help "Insert minimal template" + "--" + ["Help (cmd)" dos-help-cmd ] ; :help "Show help page for Dos command" + ["Help (mode)" dos-help-mode ] ; :help "Show help page for Emacs dos-mode" + ["Version" dos-mode-version ])) ; :help "Show Dos Mode version" +(defvar dos-mode-abbrev-table nil)(define-abbrev-table 'dos-mode-abbrev-table ()) +(defvar dos-mode-map + (let ((map (make-sparse-keymap))) + (easy-menu-define nil map nil dos-menu) + (define-key map [f11] 'dos-outline ) + (define-key map [S-f12] 'dos-template-mini) + (define-key map [f12] 'dos-template ) + (define-key map [?\C-c ?\C-.] 'dos-mode-version ) + (define-key map [?\C-c ?\C-/] 'dos-help-cmd ) + (define-key map [?\C-c ?\C- ] 'dos-sep ) + (define-key map [?\C-c ?\C-a] 'dos-run-args ) + (define-key map [?\C-c ?\C-c] 'dos-run ) + (define-key map [?\C-c ?\C-m] 'dos-help-mode ) + (define-key map [?\C-c ?\C-v] 'dos-run ) + map)) +(defvar dos-mode-syntax-table + (let ((table (make-syntax-table))) + (modify-syntax-entry ?~ "w" table) + (modify-syntax-entry ?% "." table) + (modify-syntax-entry ?- "w" table) + (modify-syntax-entry ?_ "w" table) + (modify-syntax-entry ?{ "w" table) + (modify-syntax-entry ?} "w" table) + (modify-syntax-entry ?\\ "." table) + table)) + +;; 4 User functions + +(defun dos-help-cmd (cmd) "Show help for Dos command." (interactive "sHelp: ")(shell-command (concat "help " cmd))) +(defun dos-help-mode () "Show help page for `dos-mode'." (interactive) + (describe-function 'dos-mode)(switch-to-buffer "*Help*")(delete-other-windows)(message nil)) +(defun dos-mode-version () "Show Dos Mode version number." (interactive) + (message (concat "Dos Mode version " dos-mode-version))) +(defun dos-outline () "Navigate within Dos script using outline-mode. + +If you haven't already configured an `outline-mode-hook', here is an example +that makes it easy to return to `dos-mode': + +\(defun my-outline-hook () + (local-set-key [mouse-1] 'outline-mouse-select) + (local-set-key [return] 'dos-mode ) + (defun outline-mouse-select () \"Select position and return to `dos-mode'.\" + (interactive)(dos-mode)(beginning-of-line))) +\(add-hook 'outline-mode-hook 'my-outline-hook) +" + (interactive)(let ((outreg outline-regexp))(outline-mode)(setq outline-regexp "^:[^:]"))(outline-mode)(hide-body)) +(defun dos-run () "Run Dos script." (interactive)(save-buffer)(shell-command buffer-file-name)) +(defun dos-run-args (args) "Run Dos script with ARGS." (interactive "sArgs: ") + (shell-command (concat buffer-file-name " " args))) +(defun dos-sep () "Insert & separator." (interactive)(insert " & ")) +(defun dos-template () "Insert Dos template." (interactive) + (goto-char (point-min))(insert " +@echo off +setlocal +if [%1]==[] goto HELP +if [%1]==[--help] goto HELP +REM #################################################################################################################### +REM # +REM Script: # +REM # +REM Purpose: # +REM # +REM Args: # +REM # +REM Notes: # +REM # +REM Warning: # +REM # +REM Requires: # +REM # +REM Returns: # +REM # +REM #################################################################################################################### +\nrem Pop args until file=%1 +set par=default +:STARTLOOP +if [%2]==[] goto ENDLOOP +if %1==-flag set par=%2 & shift & shift +goto STARTLOOP +:ENDLOOP\n\n\n +:HELP +echo Usage: +echo.\n +:EOF +")(goto-char (point-min))(delete-char 1)(search-forward ": ")(overwrite-mode t)) +(defun dos-template-mini () "Insert minimal Dos template." (interactive) + (goto-char (point-min))(insert "@echo off\nsetlocal\n\n")) + +;; 5 Main function + +;;;###autoload +(defun dos-mode () "Major mode for editing Dos scripts.\n +The `dos-help-mode' command shows this page.\n +Start a new script from `dos-template' or `dos-template-mini'. Navigate between +sections using `dos-outline', `imenu', or `outline-minor-mode'. Use `dos-sep' to +save keystrokes. Read help for Dos command with `dos-help-cmd'. Run script using +`dos-run' and `dos-run-args'. + +\\{dos-mode-map}" + (interactive)(kill-all-local-variables)(setq major-mode 'dos-mode)(setq mode-name "Dos") + (set (make-local-variable 'comment-start) "rem") + (set (make-local-variable 'imenu-generic-expression) '((nil "^:[^:].*" 0))) + (set (make-local-variable 'font-lock-defaults) '(dos-font-lock-keywords nil t)) ; case-insensitive keywords + (set (make-local-variable 'outline-regexp) ":[^:]") + (set-syntax-table dos-mode-syntax-table) + (setq local-abbrev-table dos-mode-abbrev-table) + (use-local-map dos-mode-map) + (run-mode-hooks 'dos-mode-hook)) + +(provide 'dos) + +;;; dos.el ends here diff --git a/layers/+lang/windows-scripts/packages.el b/layers/+lang/windows-scripts/packages.el new file mode 100644 index 0000000..61060cb --- /dev/null +++ b/layers/+lang/windows-scripts/packages.el @@ -0,0 +1,75 @@ +;;; packages.el --- Windows Scripts Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq windows-scripts-packages + '( + (dos :location local) + ggtags + helm-gtags + powershell + )) + +(defun windows-scripts/init-dos () + (use-package dos + :commands dos-mode + :mode (("\\.bat\\'" . dos-mode) + ("\\.cmd\\'" . dos-mode)) + :init + (progn + (defun windows-scripts/dos-outline-hook () + (defun outline-mouse-select () + "Select position and return to `dos-mode'." + (interactive) + (dos-mode) + (beginning-of-line))) + (defun windows-scripts/dos-outline () + "Set a local binding to be able to return easily in dos-mode." + (interactive) + (dos-outline) + (define-key evil-normal-state-local-map (kbd "SPC m z") 'dos-mode)) + (add-hook 'outline-mode-hook 'windows-scripts/dos-outline-hook)) + :config + (spacemacs/set-leader-keys-for-major-mode 'dos-mode + "hD" 'dos-help-cmd + "eb" 'dos-run + "eB" 'dos-run-args + "s" 'dos-sep + "t" 'dos-template-mini + "T" 'dos-template + "z" 'windows-scripts/dos-outline))) + +(defun windows-scripts/post-init-ggtags () + (add-hook 'dos-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + +(defun windows-scripts/post-init-helm-gtags () + (spacemacs/helm-gtags-define-keys-for-mode 'dos-mode)) + +(defun windows-scripts/init-powershell () + (use-package powershell + :mode (("\\.ps1\\'" . powershell-mode) + ("\\.psm1\\'" . powershell-mode)) + :defer t + :init + (progn + (defun powershell/define-text-objects () + (spacemacs|define-text-object "$" "dollarparen" "$(" ")") + ) + (add-hook 'powershell-mode-hook 'powershell/define-text-objects) + (spacemacs/set-leader-keys + "asp" 'powershell) + (spacemacs/set-leader-keys-for-major-mode 'powershell-mode + "rr" 'powershell-regexp-to-regex) + + ;; TODO + ;; - split out powershell + ;; - get help output with mgg (Get-Help) or Get-Help -online + ;; - + ))) diff --git a/layers/+lang/yaml/README.org b/layers/+lang/yaml/README.org new file mode 100644 index 0000000..418e740 --- /dev/null +++ b/layers/+lang/yaml/README.org @@ -0,0 +1,18 @@ +#+TITLE: YAML layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#syntax-checking-with-flycheck][Syntax checking with flycheck]] + +* Description +This layer provides syntax highlighting and syntax checking via [[http://www.flycheck.org/en/latest/languages.html#yaml][flycheck]] for YAML files. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =yaml= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Syntax checking with flycheck +Flycheck checks YAML with yaml-jsyaml or yaml-ruby. The flycheck YAML +documentation can be found at the [[http://www.flycheck.org/en/latest/languages.html#yaml][flycheck website]]. diff --git a/layers/+lang/yaml/config.el b/layers/+lang/yaml/config.el new file mode 100644 index 0000000..fa10b6d --- /dev/null +++ b/layers/+lang/yaml/config.el @@ -0,0 +1,14 @@ +;;; config.el --- YAML Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; variables + +(spacemacs|defvar-company-backends yaml-mode) diff --git a/layers/+lang/yaml/packages.el b/layers/+lang/yaml/packages.el new file mode 100644 index 0000000..de5fe74 --- /dev/null +++ b/layers/+lang/yaml/packages.el @@ -0,0 +1,28 @@ +;;; packages.el --- YAML Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(setq yaml-packages '(company + flycheck + yaml-mode)) + +(defun yaml/post-init-company () + (spacemacs|add-company-hook yaml-mode)) + +(defun yaml/post-init-flycheck () + (spacemacs/add-flycheck-hook 'yaml-mode)) + +(defun yaml/init-yaml-mode () + "Initialize YAML mode" + (use-package yaml-mode + :mode (("\\.\\(yml\\|yaml\\)\\'" . yaml-mode) + ("Procfile\\'" . yaml-mode)) + :config (add-hook 'yaml-mode-hook + '(lambda () + (define-key yaml-mode-map "\C-m" 'newline-and-indent))))) diff --git a/layers/+misc/nlinum/packages.el b/layers/+misc/nlinum/packages.el new file mode 100644 index 0000000..651e70f --- /dev/null +++ b/layers/+misc/nlinum/packages.el @@ -0,0 +1,43 @@ +;;; packages.el --- nlinum Layer packages File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defconst nlinum-packages + '( + (linum :excluded t) + (linum-relative :excluded t) + nlinum + nlinum-relative + )) + +(defun nlinum/init-nlinum () + (use-package nlinum + :init + (progn + (when dotspacemacs-line-numbers + (add-hook 'prog-mode-hook 'nlinum-mode) + (add-hook 'text-mode-hook 'nlinum-mode)) + (setq nlinum-format "%4d") + (spacemacs|add-toggle line-numbers + :mode nlinum-mode + :documentation "Show the line numbers." + :evil-leader "tn")))) + +(defun nlinum/init-nlinum-relative () + (use-package nlinum-relative + :commands (nlinum-relative-toggle nlinum-relative-on) + :init + (progn + (setq nlinum-relative-current-symbol "" + nlinum-relative-redisplay-delay 0) + (when (eq dotspacemacs-line-numbers 'relative) + (nlinum-relative-setup-evil) + (add-hook 'nlinum-mode-hook 'nlinum-relative-on)) + (spacemacs/set-leader-keys "tr" 'nlinum-relative-toggle)))) diff --git a/layers/+os/nixos/README.org b/layers/+os/nixos/README.org new file mode 100644 index 0000000..bd9fc94 --- /dev/null +++ b/layers/+os/nixos/README.org @@ -0,0 +1,34 @@ +#+TITLE: NixOS layer + +[[file:img/nixos.jpg]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features:]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#key-bindings][Key Bindings]] + - [[#nixos-options][NixOS Options]] + +* Description + +This layer adds tools for better integration of emacs in NixOS. + +** Features: +- Nix-mode using [[https://github.com/NixOS/nix/blob/master/misc/emacs/nix-mode.el][nix-mode]] +- Auto-completion of NixOS Options using [[https://github.com/travisbhartwell/nix-emacs/blob/master/company-nixos-options.el][company-nixos-options]] +- Helm Lookup for NixOS Options [[https://github.com/travisbhartwell/nix-emacs/blob/master/helm-nixos-options.el][helm-nixos-options]] + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =nixos= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key Bindings + +** NixOS Options + +| Key Binding | Description | +|-------------+-------------------------| +| ~SPC h >~ | Call helm-nixos-options | diff --git a/layers/+os/nixos/config.el b/layers/+os/nixos/config.el new file mode 100644 index 0000000..05f4701 --- /dev/null +++ b/layers/+os/nixos/config.el @@ -0,0 +1 @@ +(spacemacs|defvar-company-backends nix-mode) diff --git a/layers/+os/nixos/img/nixos.jpg b/layers/+os/nixos/img/nixos.jpg new file mode 100644 index 0000000..b3a52ad Binary files /dev/null and b/layers/+os/nixos/img/nixos.jpg differ diff --git a/layers/+os/nixos/packages.el b/layers/+os/nixos/packages.el new file mode 100644 index 0000000..91b0e9b --- /dev/null +++ b/layers/+os/nixos/packages.el @@ -0,0 +1,31 @@ +(setq nixos-packages + '( + company + (company-nixos-options :toggle (configuration-layer/package-usedp 'company)) + (helm-nixos-options :toggle (configuration-layer/package-usedp 'helm)) + nix-mode + nixos-options + )) + +(defun nixos/post-init-company () + (spacemacs|add-company-hook nix-mode) + (push 'company-capf company-backends-nix-mode)) + +(defun nixos/init-company-nixos-options () + (use-package company-nixos-options + :defer t + :init + (push 'company-nixos-options company-backends-nix-mode))) + +(defun nixos/init-helm-nixos-options () + (use-package helm-nixos-options + :config + (spacemacs/set-leader-keys + "h>" 'helm-nixos-options))) + +(defun nixos/init-nix-mode () + (use-package nix-mode) + (add-to-list 'spacemacs-indent-sensitive-modes 'nix-mode)) + +(defun nixos/init-nixos-options () + (use-package nixos-options)) diff --git a/layers/+os/osx/README.org b/layers/+os/osx/README.org new file mode 100644 index 0000000..e3ffc56 --- /dev/null +++ b/layers/+os/osx/README.org @@ -0,0 +1,102 @@ +#+TITLE: OSX layer + +[[file:img/apple.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#philosophy][Philosophy]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#use-with-non-us-keyboard-layouts][Use with non-US keyboard layouts]] + - [[#define-words-using-os-x-dictionary][Define words using OS X Dictionary]] + - [[#coreutils][Coreutils]] + - [[#key-bindings][Key Bindings]] + - [[#future-work][Future Work]] + +* Description +Spacemacs is not just emacs+vim. It can have OSX keybindings too! This layer +globally defines common OSX keybindings. ~⌘~ is set to ~super~ and ~⌥~ is set to +~meta~. Aside from that, there's nothing much, really. + +While in =dired= this layer will try to use =gls= instead of =ls=. + +* Philosophy +While this layer enables common OSX bindings, it does not implement OSX +navigation keybindings. Spacemacs is meant to be used with evil, and we +encourage you to do so :) + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =osx= to the existing =dotspacemacs-configuration-layers= list in this file. + +*** Use with non-US keyboard layouts +If you need the ~⌥~ key to type common characters such as ={[]}~= which is usual +for e.g. Finnish and Swedish keyboard layouts, you'll probably want to leave the +~⌥~ key unchanged by setting the =osx-use-option-as-meta= variable to =nil=: + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '( + (osx :variables osx-use-option-as-meta nil))) +#+END_SRC + +If you have problem entering symbols that are behind the ~⌥~ key you may want to +added this to the user-init in the .spacemacs-File. This will allow you to use +the right ~⌥~ key to write symbols. The left ~⌥~ key can be used as the Meta +key. + +#+BEGIN_SRC emacs-lisp + (setq-default mac-right-option-modifier nil) +#+END_SRC + +*** Define words using OS X Dictionary + +This layer by default enables defining words under point ~SPC x w d~ using OS X +Dictionary. In some cases you might want to manually setup dictionary to use. +For example, + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '( + (osx :variables osx-dictionary-dictionary-choice "English"))) +#+END_SRC + +To get the list of available dictionaries call =osx/list-available-dictionaries= +function. + +You can disable it by setting =osx-use-dictionary-app= variable to =nil=: + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '( + (osx :variables osx-use-dictionary-app nil))) +#+END_SRC + +** Coreutils +To get =gls= install coreutils homebrew: + +#+BEGIN_SRC sh + brew install coreutils +#+END_SRC + +* Key Bindings + +| Key Binding | Description | +|-------------+-----------------------------| +| ~⌘ =~ | Scale up text | +| ~⌘ -~ | Scale down text | +| ~⌘ q~ | Quit | +| ~⌘ v~ | Paste | +| ~⌘ c~ | Copy | +| ~⌘ x~ | Cut | +| ~⌘ a~ | Select all | +| ~⌘ w~ | Close window | +| ~⌘ W~ | Close frame | +| ~⌘ n~ | New frame | +| ~⌘ z~ | Undo | +| ~⌘ Z~ | Redo | +| ~⌃ ⌘ f~ | Toggle fullscreen | +| ~SPC x w d~ | Define word under the point | + +* Future Work +- Allow user to choose from either ~hyper~ or ~super~ as ~⌘~. This is an option + that is supported cross-platform. +- Configurable option to keep the OSX and spacemacs clipboards separate diff --git a/layers/+os/osx/config.el b/layers/+os/osx/config.el new file mode 100644 index 0000000..bcc27df --- /dev/null +++ b/layers/+os/osx/config.el @@ -0,0 +1,23 @@ +;;; config.el --- OSX Layer config File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar osx-use-option-as-meta t + "If non nil the option key is mapped to meta. Set to `nil` if you need the + option key to type common characters.") + +(defvar osx-use-dictionary-app t + "If non nil use osx dictionary app instead of wordnet") + +;; Use the OS X Emoji font for Emoticons +(when (fboundp 'set-fontset-font) + (set-fontset-font "fontset-default" + '(#x1F600 . #x1F64F) + (font-spec :name "Apple Color Emoji") nil 'prepend)) diff --git a/layers/+os/osx/funcs.el b/layers/+os/osx/funcs.el new file mode 100644 index 0000000..305e4a2 --- /dev/null +++ b/layers/+os/osx/funcs.el @@ -0,0 +1,18 @@ +;;; config.el --- OSX Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Boris Buliga +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun osx/list-available-dictionaries () + "Get list of available dictionaries. + +Useful when setting `osx-dictionary-dictionary-choice'." + (interactive) + (message (shell-command-to-string + (format "%s -l" (osx-dictionary-cli-find-or-recompile))))) diff --git a/layers/+os/osx/img/apple.png b/layers/+os/osx/img/apple.png new file mode 100644 index 0000000..4fdfe44 Binary files /dev/null and b/layers/+os/osx/img/apple.png differ diff --git a/layers/+os/osx/img/osx.png b/layers/+os/osx/img/osx.png new file mode 100644 index 0000000..4553893 Binary files /dev/null and b/layers/+os/osx/img/osx.png differ diff --git a/layers/+os/osx/keybindings.el b/layers/+os/osx/keybindings.el new file mode 100644 index 0000000..a1fe684 --- /dev/null +++ b/layers/+os/osx/keybindings.el @@ -0,0 +1,46 @@ +;;; config.el --- OSX Layer keybindings File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(when (spacemacs/system-is-mac) + (spacemacs/set-leader-keys "bf" 'reveal-in-osx-finder) + + ;; this is only applicable to GUI mode + (when (display-graphic-p) + ;; Treat command as super + (setq mac-command-key-is-meta nil) + (setq mac-command-modifier 'super) + + (when osx-use-option-as-meta + ;; Treat option as meta + (setq mac-option-key-is-meta t)) + (setq mac-option-modifier (if osx-use-option-as-meta 'meta nil)) + + ;; Keybindings + (global-set-key (kbd "s-=") 'spacemacs/scale-up-font) + (global-set-key (kbd "s--") 'spacemacs/scale-down-font) + (global-set-key (kbd "s-0") 'spacemacs/reset-font-size) + (global-set-key (kbd "s-q") 'save-buffers-kill-terminal) + (global-set-key (kbd "s-v") 'yank) + (global-set-key (kbd "s-c") 'evil-yank) + (global-set-key (kbd "s-a") 'mark-whole-buffer) + (global-set-key (kbd "s-x") 'kill-region) + (global-set-key (kbd "s-w") 'delete-window) + (global-set-key (kbd "s-W") 'delete-frame) + (global-set-key (kbd "s-n") 'make-frame) + (global-set-key (kbd "s-z") 'undo-tree-undo) + (global-set-key (kbd "s-s") + (lambda () + (interactive) + (call-interactively (key-binding "\C-x\C-s")))) + (global-set-key (kbd "s-Z") 'undo-tree-redo) + (global-set-key (kbd "C-s-f") 'spacemacs/toggle-frame-fullscreen) + ;; Emacs sometimes registers C-s-f as this weird keycode + (global-set-key (kbd "") 'spacemacs/toggle-frame-fullscreen))) diff --git a/layers/+os/osx/packages.el b/layers/+os/osx/packages.el new file mode 100644 index 0000000..318ea59 --- /dev/null +++ b/layers/+os/osx/packages.el @@ -0,0 +1,118 @@ +;;; config.el --- OSX Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq osx-packages + '( + exec-path-from-shell + helm + launchctl + (osx-dictionary :toggle osx-use-dictionary-app) + osx-trash + pbcopy + reveal-in-osx-finder + term + )) + +(when (spacemacs/system-is-mac) + ;; Enable built-in trash support via finder API if available (only on Emacs + ;; Mac Port) + (when (boundp 'mac-system-move-file-to-trash-use-finder) + (setq mac-system-move-file-to-trash-use-finder t))) + +(defun osx/post-init-exec-path-from-shell () + ;; Use GNU ls as `gls' from `coreutils' if available. Add `(setq + ;; dired-use-ls-dired nil)' to your config to suppress the Dired warning when + ;; not using GNU ls. We must look for `gls' after `exec-path-from-shell' was + ;; initialized to make sure that `gls' is in `exec-path' + (when (spacemacs/system-is-mac) + (let ((gls (executable-find "gls"))) + (when gls + (setq insert-directory-program gls + dired-listing-switches "-aBhl --group-directories-first"))))) + +(defun osx/pre-init-helm () + ;; Use `mdfind' instead of `locate'. + (when (spacemacs/system-is-mac) + (spacemacs|use-package-add-hook helm + :post-config + ;; Disable fuzzy matchting to make mdfind work with helm-locate + ;; https://github.com/emacs-helm/helm/issues/799 + (setq helm-locate-fuzzy-match nil) + (setq helm-locate-command "mdfind -name %s %s")))) + +(defun osx/init-launchctl () + (use-package launchctl + :if (spacemacs/system-is-mac) + :defer t + :init + (progn + (add-to-list 'auto-mode-alist '("\\.plist\\'" . nxml-mode)) + (spacemacs/set-leader-keys "al" 'launchctl)) + :config + (progn + (evilified-state-evilify launchctl-mode launchctl-mode-map + (kbd "q") 'quit-window + (kbd "s") 'tabulated-list-sort + (kbd "g") 'launchctl-refresh + (kbd "n") 'launchctl-new + (kbd "e") 'launchctl-edit + (kbd "v") 'launchctl-view + (kbd "l") 'launchctl-load + (kbd "u") 'launchctl-unload + (kbd "r") 'launchctl-reload + (kbd "S") 'launchctl-start + (kbd "K") 'launchctl-stop + (kbd "R") 'launchctl-restart + (kbd "D") 'launchctl-remove + (kbd "d") 'launchctl-disable + (kbd "E") 'launchctl-enable + (kbd "i") 'launchctl-info + (kbd "f") 'launchctl-filter + (kbd "=") 'launchctl-setenv + (kbd "#") 'launchctl-unsetenv + (kbd "h") 'launchctl-help)))) + +(defun osx/init-osx-dictionary () + (use-package osx-dictionary + :if osx-use-dictionary-app + :init (spacemacs/set-leader-keys "xwd" 'osx-dictionary-search-pointer) + :commands (osx-dictionary-search-pointer + osx-dictionary-search-input + osx-dictionary-cli-find-or-recompile) + :config + (progn + (evilified-state-evilify-map osx-dictionary-mode-map + :mode osx-dictionary-mode + :bindings + "q" 'osx-dictionary-quit + "r" 'osx-dictionary-read-word + "s" 'osx-dictionary-search-input + "o" 'osx-dictionary-open-dictionary.app)))) + +(defun osx/init-osx-trash () + (use-package osx-trash + :if (and (spacemacs/system-is-mac) + (not (boundp 'mac-system-move-file-to-trash-use-finder))) + :init (osx-trash-setup))) + +(defun osx/init-pbcopy () + (use-package pbcopy + :if (and (spacemacs/system-is-mac) (not (display-graphic-p))) + :init (turn-on-pbcopy))) + +(defun osx/init-reveal-in-osx-finder () + (use-package reveal-in-osx-finder + :if (spacemacs/system-is-mac) + :commands reveal-in-osx-finder)) + +(defun osx/post-init-term () + (with-eval-after-load 'term + (define-key term-raw-map (kbd "s-v") 'term-paste))) diff --git a/layers/+pair-programming/floobits/README.org b/layers/+pair-programming/floobits/README.org new file mode 100644 index 0000000..8fd4c8f --- /dev/null +++ b/layers/+pair-programming/floobits/README.org @@ -0,0 +1,32 @@ +#+TITLE: Floobits layer + +[[file:img/floobits.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#key-bindings][Key Bindings]] + +* Description +This layer adds support for peer programming tool [[https://github.com/Floobits/floobits-emacs][floobits]]. + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =floobits= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key Bindings + +| Key Binding | Description | +|-------------+------------------------------------------------------------------------------------------| +| ~SPC P c~ | Clears all mirrored highlights. | +| ~SPC P d~ | Load the .floorc.json file for floobits configuration. | +| ~SPC P f~ | Follow a users changes. This also toggles follow mode. | +| ~SPC P j~ | Join an existing floobits workspace. | +| ~SPC P l~ | Leave the current workspace. | +| ~SPC P R~ | Create a workspace and populate it with the contents of the directory, DIR (or make it). | +| ~SPC P s~ | Summon everyone in the workspace to your cursor position. | +| ~SPC P t~ | Toggle following of recent changes. | +| ~SPC P U~ | Create a workspace and populate it with the contents of the directory, DIR (or make it). | diff --git a/layers/+pair-programming/floobits/img/floobits.png b/layers/+pair-programming/floobits/img/floobits.png new file mode 100644 index 0000000..5de6673 Binary files /dev/null and b/layers/+pair-programming/floobits/img/floobits.png differ diff --git a/layers/+pair-programming/floobits/packages.el b/layers/+pair-programming/floobits/packages.el new file mode 100644 index 0000000..5a3f839 --- /dev/null +++ b/layers/+pair-programming/floobits/packages.el @@ -0,0 +1,42 @@ +;;; packages.el --- floobits Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Rodolfo Hansen +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq floobits-packages + '( + floobits + )) + +(defun floobits/init-floobits () + (use-package floobits + :defer t + :init + (progn + (spacemacs/declare-prefix "P" "PP/floobits") + + (defun spacemacs/floobits-rclocation () + "Return the absolute path to the floobits dotfile." + (concat user-home-directory ".floorc.json")) + + (defun spacemacs/floobits-load-rcfile () + "Load ~/.floobitsrc if it exists." + (let ((floobitsrc (spacemacs/floobits-rclocation))) + (if (file-exists-p floobitsrc) (load floobitsrc)))) + + (spacemacs/set-leader-keys + "Pc" 'floobits-clear-highlights + "Pd" 'spacemacs/floobits-load-rcfile + "Pf" 'floobits-follow-user + "Pj" 'floobits-join-workspace + "Pl" 'floobits-leave-workspace + "PR" 'floobits-share-dir-private + "Ps" 'floobits-summon + "Pt" 'floobits-follow-mode-toggle + "PU" 'floobits-share-dir-public)))) diff --git a/layers/+source-control/git/README.org b/layers/+source-control/git/README.org new file mode 100644 index 0000000..85a6bd4 --- /dev/null +++ b/layers/+source-control/git/README.org @@ -0,0 +1,268 @@ +#+TITLE: Git contribution layer for Spacemacs + +[[file:img/git.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features:]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#magit-status-fullscreen][Magit status fullscreen]] + - [[#magit-auto-complete][Magit auto-complete]] + - [[#magit-svn-plugin][Magit SVN plugin]] + - [[#global-git-commit-mode][Global git commit mode]] + - [[#git][Git]] + - [[#git-flow][Git-Flow]] + - [[#org-integration][Org integration]] + - [[#working-with-git][Working with Git]] + - [[#magit][Magit]] + - [[#staging-lines][Staging lines]] + - [[#commit-message-editing-buffer][Commit message editing buffer]] + - [[#interactive-rebase-buffer][Interactive rebase buffer]] + - [[#quick-guide-for-recurring-use-cases-in-magit][Quick guide for recurring use cases in Magit]] + - [[#git-flow-1][Git-Flow]] + - [[#git-time-machine][Git time machine]] + - [[#git-links-to-web-services][Git links to web services]] + +* Description +This layers adds extensive support for [[http://git-scm.com/][git]]. + +** Features: +- git repository management the indispensable [[http://magit.vc/][magit]] package +- [[https://github.com/jtatarik/magit-gitflow][git-flow]] add-on for magit. +- quick in buffer history browsing with [[https://github.com/pidu/git-timemachine][git-timemachine]]. +- quick in buffer last commit message per line with [[https://github.com/syohex/emacs-git-messenger][git-messenger]] +- colorize buffer line by age of commit with [[https://github.com/syohex/emacs-smeargle][smeargle]] +- gitignore generator with [[https://github.com/jupl/helm-gitignore][helm-gitignore]] +- org integration with magit via [[https://github.com/magit/orgit][orgit]] + +New to Magit? Checkout the [[http://magit.vc/about.html][official intro]]. + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =git= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Magit status fullscreen +To display the =magit status= buffer in fullscreen set the variable +=git-magit-status-fullscreen= to =t= in your =dotspacemacs/user-init= function. + +#+BEGIN_SRC emacs-lisp + (defun dotspacemacs/user-init () + (setq-default git-magit-status-fullscreen t)) +#+END_SRC + +** Magit auto-complete +Magit auto-complete feature is enabled. For this feature to work best you +have to setup your Git repository directory in your =dotspacemacs/user-config= +function, this is the folder where you keep all your git-controlled projects +(the path should end up with a ~/~ to respect Emacs conventions): + +#+BEGIN_SRC emacs-lisp + (setq magit-repository-directories '("~/repos/")) +#+END_SRC + +For more information, see [[http://magit.vc/manual/magit.html#Status-buffer][Magit-User-Manual#Status-buffer]] + +** Magit SVN plugin +For convenience the magit SVN plugin can be activated directly in the Git +layer by setting the variable =git-enable-magit-svn-plugin= to =t=. + +#+BEGIN_SRC emacs-lisp + (defun dotspacemacs/user-init () + (setq-default git-enable-magit-svn-plugin t)) +#+END_SRC + +** Global git commit mode +Spacemacs can be used as the =$EDITOR= (or =$GIT_EDITOR=) for editing git +commits messages. To enable this you have to add the following line to your +=dotspacemacs/user-config=: + +#+begin_src emacs-lisp +(global-git-commit-mode t) +#+end_src + +** Git +Of course if your OS does not ship with git (!) you'll have to install it +on your machine. You can download it from the [[http://git-scm.com/downloads][download page]]. + +** Git-Flow +Git-flow is a standardized branching pattern for git repositories with the aim +of making things more manageable. While there are tools to assist with making +this easier, these do nothing you couldn't do manually. + +Support requires installation of the git-flow extensions. Please reference their +[[https://github.com/petervanderdoes/gitflow/wiki][installation page]] for assistance. + +** Org integration + +See the commentary section of the package [[https://github.com/magit/orgit/blob/master/orgit.el#L28][here]]. + +* Working with Git +Git commands (start with ~g~): + +| Key Binding | Description | +|-------------+-----------------------------------------------------| +| ~SPC g >~ | show submodule prompt | +| ~SPC g b~ | open a =magit= blame | +| ~SPC g f h~ | show file commits history | +| ~SPC g H c~ | clear highlights | +| ~SPC g H h~ | highlight regions by age of commits | +| ~SPC g H t~ | highlight regions by last updated time | +| ~SPC g I~ | open =helm-gitignore= | +| ~SPC g s~ | open a =magit= status window | +| ~SPC g S~ | stage current file | +| ~SPC g m~ | magit dispatch popup | +| ~SPC g M~ | display the last commit message of the current line | +| ~SPC g t~ | launch the git time machine | +| ~SPC g U~ | unstage current file | + +- Highlight by age of commit or last update time is provided by + [[https://github.com/syohex/emacs-smeargle][smeargle]]. +- Git time machine is provided by [[https://github.com/pidu/git-timemachine][git-timemachine]]. +- Git last commit message per line is provided by [[https://github.com/syohex/emacs-git-messenger][git-messenger]]. + +** Magit +Spacemacs uses [[http://magit.vc/][magit]] to manage Git repositories. + +To open a =status buffer=, type in a buffer of a Git repository: ~SPC g s~. +The central key binding hub of Magit is available on ~SPC g m~. + +Spacemacs uses [[https://github.com/justbur/evil-magit][evil-magit]] for key bindings in magit buffers (unless your editing +style is set to emacs, in which case you get the default magit bindings), which +are the standard magit key bindings with some minimal changes to make them +comfortable for evil users. + +Here are the often used bindings inside a =status buffer=: + +| Key Binding | Description | +|-------------+---------------------------------------------------------------------| +| ~/~ | evil-search | +| ~$~ | open =command output buffer= | +| ~c c~ | open a =commit message buffer= | +| ~b b~ | checkout a branch | +| ~b c~ | create a branch | +| ~f f~ | fetch changes | +| ~F (r) u~ | pull tracked branch and rebase | +| ~gr~ | refresh | +| ~j~ | goto next magit section | +| ~C-j~ | next visual line | +| ~k~ | goto previous magit section | +| ~C-k~ | previous visual line | +| ~l l~ | open =log buffer= | +| ~n~ | next search occurrence | +| ~N~ | previous search occurrence | +| ~o~ | revert item at point | +| ~P u~ | push to tracked branch | +| ~P m~ | push to matching branch (e.g., upstream/develop to origin/develop) | +| ~q~ | quit | +| ~s~ | on a file or hunk in a diff: stage the file or hunk | +| ~x~ | discard changes | +| ~+~ | on a hunk: increase hunk size | +| ~-~ | on a hunk: decrease hunk size | +| ~S~ | stage all | +| ~TAB~ | on a file: expand/collapse diff | +| ~u~ | on a staged file: unstage | +| ~U~ | unstage all staged files | +| ~v or V~ | select multiple lines | +| ~z z~ | stash changes | + +** Staging lines +Magit allows you to stage specific lines by selecting them in a diff and hitting +=s= to stage. Due to inconsistencies between Vim and Emacs editing styles, if +you enter visual line state with =V=, you will stage one more line than +intended. To work around this, you can use =v= instead (since Magit only stages +whole lines, in any case). + +** Commit message editing buffer +In a commit message buffer press ~,c~ (if =dotspacemacs-major-mode-leader-key= is ~​,​~) +or ~C-c C-c~ to commit the changes with the entered message. Pressing ~,a~ or ~C-c C-k~ +will discard the commit message. + +| Key Binding | Description | +|-------------+-------------| +| ~h~ | go left | +| ~j~ | go down | +| ~k~ | go up | +| ~l~ | go right | + +** Interactive rebase buffer + +| Key Binding | Description | +|-------------+----------------| +| ~c~ or ~p~ | pick | +| ~e~ | edit | +| ~f~ | fixup | +| ~j~ | go down | +| ~M-j~ | move line down | +| ~k~ | go up | +| ~M-k~ | move line up | +| ~d~ or ~x~ | kill line | +| ~r~ | reword | +| ~s~ | squash | +| ~u~ | undo | +| ~y~ | insert | +| ~!~ | execute | + +** Quick guide for recurring use cases in Magit +- Amend a commit: + - ~l l~ to open =log buffer= + - ~c a~ on the commit you want to amend + - ~,c~ or ~C-c C-c~ to submit the changes +- Squash last commit: + - ~l l~ to open =log buffer= + - ~r e~ on the second to last commit, it opens the =rebase buffer= + - ~j~ to put point on last commit + - ~s~ to squash it + - ~,c~ or ~C-c C-c~ to continue to the =commit message buffer= + - ~,c~ or ~C-c C-c~ again when you have finished to edit the commit message +- Force push a squashed commit: + - in the =status buffer= you should see the new commit unpushed and the old + commit unpulled + - ~P -f P~ for force a push (*beware* usually it is not recommended to rewrite + the history of a public repository, but if you are *sure* that you are the + only one to work on a repository it is ok - i.e. in your fork). +- Add upstream remote (the parent repository you have forked): + - ~M~ to open the =remote popup= + - ~a~ to add a remote, type the name (i.e. =upstream=) and the URL +- Pull changes from upstream (the parent repository you have forked) and push: + - ~F -r C-u F~ and choose =upstream= or the name you gave to it + - ~P P~ to push the commit to =origin= + +** Git-Flow +[[https://github.com/jtatarik/magit-gitflow][magit-gitflow]] provides git-flow commands in its own magit menu. + +| Key Binding | Description | +|-------------+-------------------------| +| ~%~ | open magit-gitflow menu | + +** Git time machine +[[https://github.com/pidu/git-timemachine][git-timemachine]] allows to quickly browse the commits of the current buffer. + +| Key Binding | Description | +|-------------+----------------------------------------------------| +| ~SPC g t~ | start git timemachine and initiate transient-state | +| ~c~ | show current commit | +| ~n~ | show next commit | +| ~N~ | show previous commit | +| ~p~ | show previous commit | +| ~q~ | leave transient-state and git timemachine | +| ~Y~ | copy current commit hash | + +** Git links to web services +These key bindings allow to quickly construct URLs pointing to a given commit +or lines in a file hosted on Git web services like GitHub, GitLab, Bitbucket... + +| Key Binding | Description | +|-------------+------------------------------------------------------------------------| +| ~SPC g l c~ | on a commit hash, browse to the current file at this commit | +| ~SPC g l C~ | on a commit hash, create link to the file at this commit and copy it | +| ~SPC g l l~ | on a region, browse to file at current lines position | +| ~SPC g l L~ | on a region, create a link to the file highlighting the selected lines | + +*Notes:* +- You can use the universal argument ~SPC u~ to select a remote repository. +- When the link is opened, the URL is also copied in the kill ring, you can + override this behavior by setting the variable =git-link-open-in-browser= to + =nil=. diff --git a/layers/+source-control/git/config.el b/layers/+source-control/git/config.el new file mode 100644 index 0000000..2aafb69 --- /dev/null +++ b/layers/+source-control/git/config.el @@ -0,0 +1,18 @@ +;;; config.el --- Git Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(defvar git-enable-magit-svn-plugin nil + "If non nil `magit-svn' plugin is enabled.") + +(defvar git-magit-status-fullscreen nil + "If non nil magit-status buffer is displayed in fullscreen.") diff --git a/layers/+source-control/git/funcs.el b/layers/+source-control/git/funcs.el new file mode 100644 index 0000000..58190a7 --- /dev/null +++ b/layers/+source-control/git/funcs.el @@ -0,0 +1,72 @@ +;;; funcs.el --- Colors Layer functions File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + +;; magit + +(defun spacemacs/magit-toggle-whitespace () + "Toggle whitespace in `magit-diff-mode'." + (interactive) + (if (member "-w" (if (derived-mode-p 'magit-diff-mode) + magit-refresh-args + magit-diff-section-arguments)) + (spacemacs//magit-dont-ignore-whitespace) + (spacemacs//magit-ignore-whitespace))) + +(defun spacemacs//magit-ignore-whitespace () + "Ignore whitespace in `magit-diff-mode'" + (add-to-list (if (derived-mode-p 'magit-diff-mode) + 'magit-refresh-args 'magit-diff-section-arguments) "-w") + (magit-refresh)) + +(defun spacemacs//magit-dont-ignore-whitespace () + "Don't ignore whitespace in `magit-diff-mode'" + (setq magit-diff-options + (remove "-w" + (if (derived-mode-p 'magit-diff-mode) + magit-refresh-args + magit-diff-section-arguments))) (magit-refresh)) + +(defun spacemacs/git-link-copy-url-only () + "Only copy the generated link to the kill ring." + (interactive) + (let (git-link-open-in-browser) + (call-interactively 'spacemacs/git-link))) + +(defun spacemacs/git-link-commit-copy-url-only () + "Only copy the generated link to the kill ring." + (interactive) + (let (git-link-open-in-browser) + (call-interactively 'spacemacs/git-link-commit))) + +(defun spacemacs/git-link () + "Allow the user to run git-link in a git-timemachine buffer." + (interactive) + (require 'git-link) + (if (and (boundp 'git-timemachine-revision) + git-timemachine-revision) + (cl-letf (((symbol-function 'git-link--branch) + (lambda () + (car git-timemachine-revision)))) + (call-interactively 'git-link)) + (call-interactively 'git-link))) + +(defun spacemacs/git-link-commit () + "Allow the user to run git-link-commit in a git-timemachine buffer." + (interactive) + (require 'git-link) + (if (and (boundp 'git-timemachine-revision) + git-timemachine-revision) + (cl-letf (((symbol-function 'word-at-point) + (lambda () + (car git-timemachine-revision)))) + (call-interactively 'git-link-commit)) + (call-interactively 'git-link-commit))) diff --git a/layers/+source-control/git/img/git.png b/layers/+source-control/git/img/git.png new file mode 100644 index 0000000..7280e93 Binary files /dev/null and b/layers/+source-control/git/img/git.png differ diff --git a/layers/+source-control/git/packages.el b/layers/+source-control/git/packages.el new file mode 100644 index 0000000..3107f0b --- /dev/null +++ b/layers/+source-control/git/packages.el @@ -0,0 +1,406 @@ +;;; packages.el --- Git Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq git-packages + '( + evil-magit + fill-column-indicator + gitattributes-mode + gitconfig-mode + gitignore-mode + git-commit + git-link + git-messenger + git-timemachine + (helm-gitignore :toggle (configuration-layer/package-usedp 'helm)) + magit + magit-gitflow + ;; not compatible with magit 2.1 at the time of release + ;; magit-svn + orgit + smeargle + )) + +(defun git/init-evil-magit () + (with-eval-after-load 'magit + (require 'evil-magit) + (evil-define-key 'motion magit-mode-map + (kbd dotspacemacs-leader-key) spacemacs-default-map))) + +(defun git/post-init-fill-column-indicator () + (add-hook 'git-commit-mode-hook 'fci-mode)) + +(defun git/init-helm-gitignore () + (use-package helm-gitignore + :defer t + :init (spacemacs/set-leader-keys "gI" 'helm-gitignore))) + +(defun git/init-git-commit () + (use-package git-commit + :defer t)) + +(defun git/init-git-link () + (use-package git-link + :defer t + :init + (progn + (spacemacs/declare-prefix "gl" "links") + (spacemacs/set-leader-keys + "gll" 'spacemacs/git-link + "glL" 'spacemacs/git-link-copy-url-only + "glc" 'spacemacs/git-link-commit + "glC" 'spacemacs/git-link-commit-copy-url-only) + ;; default is to open the generated link + (setq git-link-open-in-browser t)))) + +(defun git/init-git-messenger () + (use-package git-messenger + :defer t + :init (spacemacs/set-leader-keys "gM" 'git-messenger:popup-message) + :config (define-key git-messenger-map [escape] 'git-messenger:popup-close))) + +(defun git/init-git-timemachine () + (use-package git-timemachine + :defer t + :commands spacemacs/time-machine-transient-state/body + :init + (spacemacs/set-leader-keys + "gt" 'spacemacs/time-machine-transient-state/body) + :config + (progn + (spacemacs|define-transient-state time-machine + :title "Git Timemachine Transient State" + :doc " +[_p_/_N_] previous [_n_] next [_c_] current [_g_] goto nth rev [_Y_] copy hash [_q_] quit" + :on-enter (let (golden-ratio-mode) + (unless (bound-and-true-p git-timemachine-mode) + (call-interactively 'git-timemachine))) + :on-exit (when (bound-and-true-p git-timemachine-mode) + (git-timemachine-quit)) + :foreign-keys run + :bindings + ("c" git-timemachine-show-current-revision) + ("g" git-timemachine-show-nth-revision) + ("p" git-timemachine-show-previous-revision) + ("n" git-timemachine-show-next-revision) + ("N" git-timemachine-show-previous-revision) + ("Y" git-timemachine-kill-revision) + ("q" nil :exit t))))) + +(defun git/init-gitattributes-mode () + (use-package gitattributes-mode + :defer t)) + +(defun git/init-gitconfig-mode () + (use-package gitconfig-mode + :defer t)) + +(defun git/init-gitignore-mode () + (use-package gitignore-mode + :defer t)) + +(defun git/init-magit () + (use-package magit + :defer t + :init + (progn + (setq magit-completing-read-function + (if (configuration-layer/layer-usedp 'ivy) + 'ivy-completing-read + 'magit-builtin-completing-read)) + (setq magit-revision-show-gravatars '("^Author: " . "^Commit: ")) + ;; On Windows, we must use Git GUI to enter username and password + ;; See: https://github.com/magit/magit/wiki/FAQ#windows-cannot-push-via-https + (when (eq window-system 'w32) + (setenv "GIT_ASKPASS" "git-gui--askpass")) + ;; key bindings + (spacemacs/declare-prefix "gd" "diff") + (spacemacs/declare-prefix "gf" "file") + (spacemacs/set-leader-keys + "gb" 'spacemacs/git-blame-micro-state + "gfh" 'magit-log-buffer-file + "gm" 'magit-dispatch-popup + "gs" 'magit-status + "gS" 'magit-stage-file + "gU" 'magit-unstage-file) + ;; transient state + ;; TODO use transient state instead of old micro-state, IIRC we continue + ;; to use micro-state because of the re-entry keyword :on-enter which is + ;; not available in transient state + (spacemacs|define-micro-state git-blame + :title "Git Blame Transient State" + :doc " +Press [_b_] again to blame further in the history, [_q_] to go up or quit." + :on-enter (let (golden-ratio-mode) + (unless (bound-and-true-p magit-blame-mode) + (call-interactively 'magit-blame))) + :foreign-keys run + :bindings + ("b" magit-blame) + ;; here we use the :exit keyword because we should exit the + ;; micro-state only if the magit-blame-quit effectively disable + ;; the magit-blame mode. + ("q" nil :exit (progn (when (bound-and-true-p magit-blame-mode) + (magit-blame-quit)) + (not (bound-and-true-p magit-blame-mode)))))) + :config + (progn + ;; seems to be necessary at the time of release + (require 'git-rebase) + ;; bind function keys + ;; (define-key magit-mode-map (kbd "") 'magit-section-toggle) + (unless (configuration-layer/package-usedp 'evil-magit) + ;; use auto evilification if `evil-magit' is not used + (evilified-state-evilify-map magit-mode-map + :bindings + "gr" 'magit-refresh + "gR" 'magit-refresh-all) + (evilified-state-evilify-map magit-status-mode-map + :mode magit-status-mode + :bindings + (kbd "C-S-j") 'magit-section-forward + (kbd "C-S-k") 'magit-section-backward + (kbd "C-n") 'magit-section-forward + (kbd "C-p") 'magit-section-backward) + (evilified-state-evilify-map magit-refs-mode-map + :mode magit-refs-mode + :bindings + (kbd "C-S-j") 'magit-section-forward + (kbd "C-S-k") 'magit-section-backward + (kbd "C-n") 'magit-section-forward + (kbd "C-p") 'magit-section-backward) + (evilified-state-evilify-map magit-blame-mode-map + :mode magit-blame-mode + :bindings + (kbd "C-S-j") 'magit-section-forward + (kbd "C-S-k") 'magit-section-backward + (kbd "C-n") 'magit-section-forward + (kbd "C-p") 'magit-section-backward) + (evilified-state-evilify-map magit-hunk-section-map + :mode magit-status-mode + :bindings + (kbd "C-S-j") 'magit-section-forward + (kbd "C-S-k") 'magit-section-backward + (kbd "C-n") 'magit-section-forward + (kbd "C-p") 'magit-section-backward) + (evilified-state-evilify-map magit-diff-mode-map + :mode magit-diff-mode + :bindings + (kbd "C-S-j") 'magit-section-forward + (kbd "C-S-k") 'magit-section-backward + (kbd "C-n") 'magit-section-forward + (kbd "C-p") 'magit-section-backward) + (evilified-state-evilify-map magit-log-read-revs-map + :mode magit-log-read-revs + :bindings + (kbd "C-S-j") 'magit-section-forward + (kbd "C-S-k") 'magit-section-backward + (kbd "C-n") 'magit-section-forward + (kbd "C-p") 'magit-section-backward) + (evilified-state-evilify-map magit-log-mode-map + :mode magit-log-mode + :bindings + (kbd "C-S-j") 'magit-section-forward + (kbd "C-S-k") 'magit-section-backward + (kbd "C-n") 'magit-section-forward + (kbd "C-p") 'magit-section-backward) + (evilified-state-evilify-map magit-log-select-mode-map + :mode magit-log-select-mode + :bindings + (kbd "C-S-j") 'magit-section-forward + (kbd "C-S-k") 'magit-section-backward + (kbd "C-n") 'magit-section-forward + (kbd "C-p") 'magit-section-backward) + (evilified-state-evilify-map magit-cherry-mode-map + :mode magit-cherry-mode + :bindings + (kbd "C-S-j") 'magit-section-forward + (kbd "C-S-k") 'magit-section-backward + (kbd "C-n") 'magit-section-forward + (kbd "C-p") 'magit-section-backward) + (evilified-state-evilify-map magit-reflog-mode-map + :mode magit-reflog-mode + :bindings + (kbd "C-S-j") 'magit-section-forward + (kbd "C-S-k") 'magit-section-backward + (kbd "C-n") 'magit-section-forward + (kbd "C-p") 'magit-section-backward) + (evilified-state-evilify-map magit-process-mode-map + :mode magit-process-mode + :bindings + (kbd "C-S-j") 'magit-section-forward + (kbd "C-S-k") 'magit-section-backward + (kbd "C-n") 'magit-section-forward + (kbd "C-p") 'magit-section-backward) + (evilified-state-evilify-map magit-stash-mode-map + :mode magit-stash-mode + :bindings + (kbd "C-S-j") 'magit-section-forward + (kbd "C-S-k") 'magit-section-backward + (kbd "C-n") 'magit-section-forward + (kbd "C-p") 'magit-section-backward) + (evilified-state-evilify-map git-rebase-mode-map + :mode git-rebase-mode + :bindings + (kbd "C-S-j") 'magit-section-forward + (kbd "C-S-k") 'magit-section-backward + (kbd "C-n") 'magit-section-forward + (kbd "C-p") 'magit-section-backward + "J" 'git-rebase-move-line-down + "K" 'git-rebase-move-line-up + "u" 'git-rebase-undo + "y" 'git-rebase-insert) + ;; default state for additional modes + (dolist (mode '(magit-popup-mode + magit-popup-sequence-mode)) + (evil-set-initial-state mode 'emacs)) + (let ((refresh-key "gr") + (refresh-all-key "gR") + (delete-key (nth 0 (where-is-internal 'magit-delete-thing + magit-mode-map)))) + (evilified-state--configure-default-state 'magit-revision-mode) + ;; section maps + (eval `(evilified-state-evilify-map magit-tag-section-map + :pre-bindings + ,delete-key 'magit-tag-delete + :bindings + ,refresh-key 'magit-refresh + ,refresh-all-key 'magit-refresh-all)) + (eval `(evilified-state-evilify-map magit-untracked-section-map + :pre-bindings + ,delete-key 'magit-discard + :bindings + ,refresh-key 'magit-refresh + ,refresh-all-key 'magit-refresh-all)) + (eval `(evilified-state-evilify-map magit-branch-section-map + :pre-bindings + ,delete-key 'magit-branch-delete + :bindings + ,refresh-key 'magit-refresh + ,refresh-all-key 'magit-refresh-all)) + (eval `(evilified-state-evilify-map magit-remote-section-map + :pre-bindings + ,delete-key 'magit-remote-remove + :bindings + ,refresh-key 'magit-refresh + ,refresh-all-key 'magit-refresh-all)) + (eval `(evilified-state-evilify-map magit-file-section-map + :pre-bindings + ,delete-key 'magit-discard + :bindings + ,refresh-key 'magit-refresh + ,refresh-all-key 'magit-refresh-all)) + (eval `(evilified-state-evilify-map magit-hunk-section-map + :pre-bindings + ,delete-key 'magit-discard + :bindings + ,refresh-key 'magit-refresh + ,refresh-all-key 'magit-refresh-all)) + (eval `(evilified-state-evilify-map magit-unstaged-section-map + :pre-bindings + ,delete-key 'magit-discard + :bindings + ,refresh-key 'magit-refresh + ,refresh-all-key 'magit-refresh-all)) + (eval `(evilified-state-evilify-map magit-staged-section-map + :pre-bindings + ,delete-key 'magit-discard + :bindings + ,refresh-key 'magit-refresh + ,refresh-all-key 'magit-refresh-all)) + (eval `(evilified-state-evilify-map magit-commit-section-map + :pre-bindings + ,delete-key 'magit-discard + :bindings + ,refresh-key 'magit-refresh + ,refresh-all-key 'magit-refresh-all)) + (eval `(evilified-state-evilify-map magit-stashes-section-map + :pre-bindings + ,delete-key 'magit-stash-clear + :bindings + ,refresh-key 'magit-refresh + ,refresh-all-key 'magit-refresh-all)) + (eval `(evilified-state-evilify-map magit-stash-section-map + :pre-bindings + ,delete-key 'magit-stash-drop + :bindings + ,refresh-key 'magit-refresh + ,refresh-all-key 'magit-refresh-all)) + (eval `(evilified-state-evilify-map magit-module-commit-section-map + :bindings + ,refresh-key 'magit-refresh + ,refresh-all-key 'magit-refresh-all)) + (eval `(evilified-state-evilify-map magit-unpulled-section-map + :bindings + ,refresh-key 'magit-refresh + ,refresh-all-key 'magit-refresh-all)) + (eval `(evilified-state-evilify-map magit-unpushed-section-map + :bindings + ,refresh-key 'magit-refresh + ,refresh-all-key 'magit-refresh-all)))) + ;; confirm/abort + (when dotspacemacs-major-mode-leader-key + (add-hook 'with-editor-mode-hook 'evil-normalize-keymaps) + (let ((mm-key dotspacemacs-major-mode-leader-key)) + (dolist (state '(normal motion)) + (evil-define-key state with-editor-mode-map + (concat mm-key mm-key) 'with-editor-finish + (concat mm-key "a") 'with-editor-cancel + (concat mm-key "c") 'with-editor-finish + (concat mm-key "k") 'with-editor-cancel)))) + ;; whitespace + (define-key magit-status-mode-map (kbd "C-S-w") + 'spacemacs/magit-toggle-whitespace) + ;; full screen magit-status + (when git-magit-status-fullscreen + (setq magit-display-buffer-function 'magit-display-buffer-fullframe-status-v1))))) + +(defun git/init-magit-gitflow () + (use-package magit-gitflow + :commands turn-on-magit-gitflow + :init (progn + (add-hook 'magit-mode-hook 'turn-on-magit-gitflow) + (with-eval-after-load 'magit + (define-key magit-mode-map "%" 'magit-gitflow-popup))) + :config (spacemacs|diminish magit-gitflow-mode "Flow"))) + +(defun git/init-magit-svn () + (use-package magit-svn + :if git-enable-magit-svn-plugin + :commands turn-on-magit-svn + :init (add-hook 'magit-mode-hook 'turn-on-magit-svn) + :config + (progn + (evil-define-key 'emacs magit-status-mode-map + "N" 'magit-key-mode-popup-svn)))) + +(defun git/init-orgit ()) + +(defun git/init-smeargle () + (use-package smeargle + :defer t + :init + (progn + (spacemacs/declare-prefix "gH" "highlight") + (when (configuration-layer/package-usedp 'which-key) + ;; TODO abstract this to a function + (let ((descr + '(("smeargle" . "highlight by last update time") + ("smeargle-commits" . "highlight by age of changes") + ("smeargle-clear" . "clear")))) + (dolist (nd descr) + ;; ensure the target matches the whole string + (push (cons (concat "\\`" (car nd) "\\'") (cdr nd)) + which-key-description-replacement-alist)))) + (spacemacs/set-leader-keys + "gHc" 'smeargle-clear + "gHh" 'smeargle-commits + "gHt" 'smeargle)))) diff --git a/layers/+source-control/github/README.org b/layers/+source-control/github/README.org new file mode 100644 index 0000000..3713c08 --- /dev/null +++ b/layers/+source-control/github/README.org @@ -0,0 +1,105 @@ +#+TITLE: GitHub layer + +[[file:img/github.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features:]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#git-configuration][Git configuration]] + - [[#key-bindings][Key Bindings]] + - [[#magit-gh-pulls][magit-gh-pulls]] + - [[#gistel][gist.el]] + - [[#clone-repositories][Clone repositories]] + - [[#browse-files][Browse files]] + +* Description +This layers adds support for [[http://github.com][GitHub]]. + +** Features: +- [[https://github.com/sigma/magit-gh-pulls][magit-gh-pulls]]: handy =magit= add-on to manage GitHub pull requests. +- [[https://github.com/defunkt/gist.el][gist.el]]: full-featured mode to browse and post GitHub gists. +- [[https://github.com/osener/github-browse-file][github-browse-file]] and [[https://github.com/sshaw/git-link][git-link]]: quickly browse GitHub URL in your + browser. +- [[https://github.com/dgtized/github-clone.el][github-clone]] allows for easy cloning and forking of repositories. + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =github= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Git configuration +You will need to generate a [[https://github.com/settings/tokens][personal access token]] on GitHub. This token should +have the =gist= and =repo= permissions. Once this token is created, it needs to +be added to your =~/.gitconfig= + +#+BEGIN_SRC sh + git config --global github.oauth-token +#+END_SRC + +* Key Bindings +** magit-gh-pulls + +In a =magit status= buffer (~SPC g s~): + +| Key Binding | Description | +|-------------+-------------------------------------------------------------| +| ~# c~ | create a pull request | +| ~# g~ | get a list of (or reload) all PRs in the current repository | +| ~# f~ | fetch the commits associated with the current PR at point | +| ~# b~ | create a branch for the current PR at point | +| ~# m~ | merge the PR with current branch at point | +| ~# d~ | show a diff of the current pull request at point | +| ~# o~ | open PR at point in browser | + +Note that =magit-gh-pulls= will try to fast-forward the PRs whenever it is +possible. + +** gist.el + +| Key Binding | Description | +|-------------+-----------------------------------------------| +| ~SPC g g b~ | create a public gist with the buffer content | +| ~SPC g g B~ | create a private gist with the buffer content | +| ~SPC g g l~ | open the gist list buffer | +| ~SPC g g r~ | create a public gist with the region content | +| ~SPC g g R~ | create a private gist with the region content | + +In the gist list buffer: + +| Key Binding | Description | +|-------------+------------------------------| +| ~/~ | evil search | +| ~+~ | add buffer to gist | +| ~-~ | remove file for gist | +| ~b~ or ~o~ | open current gist in browser | +| ~f~ | fetch current gist | +| ~g~ | refresh the list | +| ~h~ | go left | +| ~j~ | go down | +| ~k~ | go up | +| ~K~ | kill current gist | +| ~l~ | go right | +| ~n~ | next search occurrence | +| ~N~ | next previous occurrence | +| ~v~ | =visual state= | +| ~V~ | =visual-line state= | +| ~y~ | print URL and copy it | + +** Clone repositories + +| Key Binding | Description | +|---------------+----------------------------------------------------------| +| ~SPC g h c /~ | search for a repository to clone it | +| ~SPC g h c c~ | clone and optionally fork repository | +| ~SPC g h c r~ | add a remote that is an existing fork of selected remote | +| ~SPC g h c f~ | fork remote in current user namespace | +| ~SPC g h c u~ | add upstream as remote | + +** Browse files + +| Key Binding | Description | +|-------------+--------------------------------------------------------------------| +| ~SPC g h o~ | browse to file on GitHub | diff --git a/layers/+source-control/github/img/github.png b/layers/+source-control/github/img/github.png new file mode 100644 index 0000000..111acbe Binary files /dev/null and b/layers/+source-control/github/img/github.png differ diff --git a/layers/+source-control/github/packages.el b/layers/+source-control/github/packages.el new file mode 100644 index 0000000..68b23b6 --- /dev/null +++ b/layers/+source-control/github/packages.el @@ -0,0 +1,87 @@ +;;; packages.el --- Github Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq github-packages + '( + gist + github-browse-file + github-clone + github-search + magit-gh-pulls + ;; this package does not exits, we need it to wrap + ;; the call to spacemacs/declare-prefix. + (spacemacs-github :location built-in) + )) + +(defun github/init-gist () + (use-package gist + :defer t + :init + (progn + (evilified-state-evilify gist-list-mode gist-list-menu-mode-map + "f" 'gist-fetch-current + "K" 'gist-kill-current + "o" 'gist-browse-current-url) + (spacemacs/declare-prefix "gg" "github gist") + (spacemacs/set-leader-keys + "ggb" 'gist-buffer + "ggB" 'gist-buffer-private + "ggl" 'gist-list + "ggr" 'gist-region + "ggR" 'gist-region-private)))) + +(defun github/init-github-browse-file () + (use-package github-browse-file + :defer t + :init (spacemacs/set-leader-keys "gho" 'github-browse-file))) + +(defun github/init-github-clone () + (use-package github-clone + :defer t + :init + (progn + (spacemacs/declare-prefix "ghc" "clone") + (spacemacs/set-leader-keys + "ghcc" 'github-clone + "ghcr" 'github-clone-add-existing-remote + "ghcf" 'github-clone-fork-remote + "ghcu" 'github-clone-add-source-remote)))) + +(defun github/init-github-search () + (use-package github-search + :commands (github-search-clone-repo github-search-user-clone-repo) + :init (spacemacs/set-leader-keys "ghc/" 'github-search-clone-repo))) + +;; magit-gh-pulls has to be loaded via a pre-config hook because the source code +;; makes assumptions about the status of the magit-mode keymaps that are +;; incompatible with the spacemacs' evilification feature. +;; To avoid errors, magit-gh-pulls must be loaded after magit, but before magit +;; is configured by spacemacs. + +(defun github/init-magit-gh-pulls () + (spacemacs|use-package-add-hook magit + :pre-config + (progn + (use-package magit-gh-pulls + :init + (progn + (defun spacemacs/load-gh-pulls-mode () + "Start `magit-gh-pulls-mode' only after a manual request." + (interactive) + (magit-gh-pulls-mode) + (magit-gh-pulls-popup)) + + (define-key magit-mode-map "#" 'spacemacs/load-gh-pulls-mode)) + :config + (spacemacs|diminish magit-gh-pulls-mode "Github-PR"))))) + +(defun github/init-spacemacs-github () + (spacemacs/declare-prefix "gh" "github")) diff --git a/layers/+source-control/perforce/README.org b/layers/+source-control/perforce/README.org new file mode 100644 index 0000000..7308835 --- /dev/null +++ b/layers/+source-control/perforce/README.org @@ -0,0 +1,75 @@ +#+TITLE: Perforce layer + +[[file:img/p4.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + +* Description + +This layer adds support for [[http://www.perforce.com/][Perforce]] (p4). + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =perforce= to the existing =dotspacemacs-configuration-layers= list in this +file. + +You'll have to install the =p4== command line tool from the [[http://www.perforce.com/downloads][download page]]. + +Don't forget to setup the environment variables: +- =P4_PORT= +- =P4_CLIENT= +- =P4_USER= +- =P4_PASSWD= + +* Key bindings + +| Key Binding | Description | +|-------------+--------------------------------------------------------------| +| ~SPC p 4 a~ | add a file in depot | +| ~SPC p 4 d~ | delete a file in depot | +| ~SPC p 4 D~ | p4-describe | +| ~SPC p 4 e~ | checkout a file | +| ~SPC p 4 r~ | revert a file | +| ~SPC p 4 R~ | refresh content of an file. 'sync -f' | +| ~SPC p 4 S~ | submit CL | +| ~SPC p 4 b~ | create, modify, or delete a branch view specification | +| ~SPC p 4 B~ | display list of branch specifications | +| ~SPC p 4 c~ | create or edit a client workspace specification and its view | +| ~SPC p 4 C~ | display list of pending and submitted CL | +| ~SPC p 4 E~ | change the filetype of an open file or move it to another CL | +| ~SPC p 4 @~ | p4-depot-find-file | +| ~SPC p 4 f~ | list revision history of files | +| ~SPC p 4 F~ | list files in the depot | +| ~SPC p 4 G~ | display current perforce client name | +| ~SPC p 4 g~ | synchronize client with depot | +| ~SPC p 4 h~ | p4-help | +| ~SPC p 4 H~ | list revisions most recently synced to the current workspace | +| ~SPC p 4 i~ | display client/server information | +| ~SPC p 4 I~ | integrate one set of files into another | +| ~SPC p 4 j~ | create or edit a job (defect) specification | +| ~SPC p 4 J~ | display list of all jobs | +| ~SPC p 4 l~ | create or edit a label specification | +| ~SPC p 4 L~ | display list of defined labels | +| ~SPC p 4 :~ | apply label to the contents of the client workspace | +| ~SPC p 4 m~ | move files from one location to another | +| ~SPC p 4 o~ | list open files and display file status | +| ~SPC p 4 p~ | write a depot file to a buffer | +| ~SPC p 4 P~ | p4-set-p4-port | +| ~SPC p 4 q~ | quit window | +| ~SPC p 4 y~ | resolve integrations and updates to workspace files | +| ~SPC p 4 s~ | identify differences between workspace and depot | +| ~SPC p 4 t~ | toggle perfore server check when opening files. | +| ~SPC p 4 u~ | create or edit user specification | +| ~SPC p 4 U~ | list perforce users | +| ~SPC p 4 v~ | emacs perforce integration version | +| ~SPC p 4 V~ | p4 blame | +| ~SPC p 4 w~ | show how file names are mapped by client view | +| ~SPC p 4 x~ | delete a file from the depot | +| ~SPC p 4 X~ | mark jobs done by specific CL | +| ~SPC p 4 z~ | p4-reconcile | +| ~SPC p 4 =~ | p4 diff | +| ~SPC p 4 +~ | p4 diff on all opened files | +| ~SPC p 4 -~ | p4 ediff | diff --git a/layers/+source-control/perforce/img/p4.png b/layers/+source-control/perforce/img/p4.png new file mode 100644 index 0000000..cbaaf05 Binary files /dev/null and b/layers/+source-control/perforce/img/p4.png differ diff --git a/layers/+source-control/perforce/packages.el b/layers/+source-control/perforce/packages.el new file mode 100644 index 0000000..c2c1e20 --- /dev/null +++ b/layers/+source-control/perforce/packages.el @@ -0,0 +1,109 @@ +;;; packages.el --- Perforce Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq perforce-packages '(p4)) + +(defun perforce/init-p4 () + (use-package p4 + :commands (p4-add + p4-branch + p4-branches + p4-client + p4-changes + p4-diff2 + p4-describe + p4-edit + p4-reopen + p4-depot-find-file + p4-filelog + p4-files + p4-get-client-name + p4-update + p4-help + p4-have + p4-info + p4-integ + p4-job + p4-jobs + p4-label + p4-labels + p4-labelsync + p4-move + p4-opened + p4-print + p4-set-p4-port + quit-window + p4-revert + p4-refresh + p4-resolve + p4-status + p4-submit + p4-toggle-vc-mode + p4-user + p4-users + p4-version + p4-annotate + p4-where + p4-delete + p4-fix + p4-reconcile + p4-diff + p4-diff-all-opened + p4-ediff) + :init + (progn + (spacemacs/declare-prefix "p4" "perforce") + (spacemacs/set-leader-keys + "p4a" 'p4-add + "p4b" 'p4-branch + "p4B" 'p4-branches + "p4c" 'p4-client + "p4C" 'p4-changes + "p4d" 'p4-diff2 + "p4D" 'p4-describe + "p4e" 'p4-edit + "p4E" 'p4-reopen + "p4@" 'p4-depot-find-file + "p4f" 'p4-filelog + "p4F" 'p4-files + "p4G" 'p4-get-client-name + "p4g" 'p4-update + "p4h" 'p4-help + "p4H" 'p4-have + "p4i" 'p4-info + "p4I" 'p4-integ + "p4j" 'p4-job + "p4J" 'p4-jobs + "p4l" 'p4-label + "p4L" 'p4-labels + "p4:" 'p4-labelsync + "p4m" 'p4-move + "p4o" 'p4-opened + "p4p" 'p4-print + "p4P" 'p4-set-p4-port + "p4q" 'quit-window + "p4r" 'p4-revert + "p4R" 'p4-refresh + "p4y" 'p4-resolve + "p4s" 'p4-status + "p4S" 'p4-submit + "p4t" 'p4-toggle-vc-mode + "p4u" 'p4-user + "p4U" 'p4-users + "p4v" 'p4-version + "p4V" 'p4-annotate + "p4w" 'p4-where + "p4x" 'p4-delete + "p4X" 'p4-fix + "p4z" 'p4-reconcile + "p4=" 'p4-diff + "p4+" 'p4-diff-all-opened + "p4-" 'p4-ediff)))) diff --git a/layers/+source-control/version-control/README.org b/layers/+source-control/version-control/README.org new file mode 100644 index 0000000..3bb2bfc --- /dev/null +++ b/layers/+source-control/version-control/README.org @@ -0,0 +1,88 @@ +#+TITLE: Version-Control layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#configuration][Configuration]] + - [[#differences-between-margin-programs][Differences between margin programs]] + - [[#key-bindings][Key Bindings]] + - [[#version-control-transient-state][Version Control Transient-state]] + +* Description +This layers adds general configuration for [[http://www.gnu.org/software/emacs/manual/html_node/emacs/Version-Control.html][Emacs VC]]. +It should work with all VC backends such as Git, Mercurial, Bazaar, SVN, etc... + +** Features +- highlights uncommitted changes in the fringe or margin with [[https://github.com/dgutov/diff-hl][diff-hl]], +git-gutter, or git-gutter+ +- adds vcs transient-state ~SPC g.~ to allow quick navigation and modification of +buffer hunks. + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =version-control= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Configuration +You can choose the package to facilitate the diff transient-state and show margins +by setting =version-control-diff-tool= + +#+BEGIN_SRC emacs-lisp +'(version-control :variables + version-control-diff-tool 'diff-hl) +#+END_SRC + +To automatically enable diff margins in all buffers, set +=version-control-global-margin= + +#+BEGIN_SRC emacs-lisp +'(version-control :variables + version-control-global-margin t) +#+END_SRC + +** Differences between margin programs +This layer contains generalized mappings for three diff margin packages: +diff-hl, git-gutter, and git-gutter+. + +There are some differences between packages that might have some people prefer +one over the other: + +| Feature | diff-hl | git-gutter | git-gutter+ | +|-------------------------------------+---------+------------+-------------| +| Show in fringe | X | X | X | +| Extended VCS support (e.g. hg, svn) | X | X | | +| Stage hunks from buffer | | X | X | +| Dired support | X | | | + +* Key Bindings + +| Key Binding | Description | +|-------------+---------------------------------| +| ~SPC g .~ | version control transient-state | +| ~SPC T d~ | toggle diff margins | +| ~SPC T C-d~ | toggle diff margins globally | + +** Version Control Transient-state + +| Key Binding | Description | +|-------------+------------------------------| +| ~SPC g . h~ | Show diff of hunk | +| ~SPC g . n~ | Next hunk | +| ~SPC g . N~ | Previous hunk | +| ~SPC g . p~ | Previous hunk | +| ~SPC g . r~ | Revert hunk | +| ~SPC g . s~ | Stage hunk | +| ~SPC g . t~ | Toggle margin indicators | +| ~SPC g . w~ | Stage file | +| ~SPC g . u~ | Unstage file | +| ~SPC g . d~ | Repo diff popup | +| ~SPC g . D~ | Show diffs of unstaged hunks | +| ~SPC g . c~ | Commit with popup | +| ~SPC g . C~ | Commit | +| ~SPC g . P~ | Push repo with popup | +| ~SPC g . f~ | Fetch for repo with popup | +| ~SPC g . F~ | Pull repo with popup | +| ~SPC g . l~ | Show repo log | diff --git a/layers/+source-control/version-control/config.el b/layers/+source-control/version-control/config.el new file mode 100644 index 0000000..25f5903 --- /dev/null +++ b/layers/+source-control/version-control/config.el @@ -0,0 +1,75 @@ +;;; config.el --- Version Control configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar version-control-global-margin t + "If non-nil, will show diff margins globally.") + +(defvar version-control-diff-tool 'git-gutter+ + "Options are `git-gutter', `git-gutter+', and `diff-hl' to show +version-control markers.") + +;; unchanged face +(defface git-gutter+-unchanged + '((t (:background "yellow"))) + "face for unchanged lines" + :group 'git-gutter+) +(defface git-gutter:unchanged + '((t (:background "yellow"))) + "face for unchanged lines" + :group 'git-gutter+) + +;; change face +(defface git-gutter+-modified + '((t (:foreground "magenta" :weight bold))) + "face for modified lines" + :group 'git-gutter+) +(defface git-gutter:modified + '((t (:foreground "magenta" :weight bold))) + "face for modified lines" + :group 'git-gutter+) +(defface diff-hl-change + '((default :foreground "blue3") + (((class color) (min-colors 88) (background light)) + :background "#ddddff") + (((class color) (min-colors 88) (background dark)) + :background "#333355")) + "Face used to highlight changed lines." + :group 'diff-hl) + +;; added face +(defface git-gutter+-added + '((t (:foreground "green" :weight bold))) + "face for added lines" + :group 'git-gutter+) +(defface git-gutter:added + '((t (:foreground "green" :weight bold))) + "face for added lines" + :group 'git-gutter+) +(defface diff-hl-insert + '((default :inherit diff-added) + (((class color)) :foreground "green4")) + "Face used to highlight inserted lines." + :group 'diff-hl) + +;; deleted face +(defface git-gutter+-deleted + '((t (:foreground "red" :weight bold))) + "face for deleted lines" + :group 'git-gutter+) +(defface git-gutter:deleted + '((t (:foreground "red" :weight bold))) + "face for deleted lines" + :group 'git-gutter+) +(defface diff-hl-delete + '((default :inherit diff-removed) + (((class color)) :foreground "red3")) + "Face used to highlight deleted lines." + :group 'diff-hl) diff --git a/layers/+source-control/version-control/funcs.el b/layers/+source-control/version-control/funcs.el new file mode 100644 index 0000000..9cd72c8 --- /dev/null +++ b/layers/+source-control/version-control/funcs.el @@ -0,0 +1,125 @@ +;;; funcs.el --- Version control functions File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spacemacs/vcs-next-hunk () + (interactive) + (let ((current-prefix-arg t)) + (call-interactively + (cl-case version-control-diff-tool + (diff-hl 'diff-hl-next-hunk) + (git-gutter 'git-gutter:next-hunk) + (git-gutter+ 'git-gutter+-next-hunk))))) + +(defun spacemacs/vcs-previous-hunk () + (interactive) + (let ((current-prefix-arg t)) + (call-interactively + (cl-case version-control-diff-tool + (diff-hl 'diff-hl-previous-hunk) + (git-gutter 'git-gutter:previous-hunk) + (git-gutter+ 'git-gutter+-previous-hunk))))) + +(defun spacemacs/vcs-revert-hunk () + (interactive) + (let ((current-prefix-arg t)) + (call-interactively + (cl-case version-control-diff-tool + (diff-hl 'diff-hl-revert-hunk) + (git-gutter 'git-gutter:revert-hunk) + (git-gutter+ 'git-gutter+-revert-hunks))))) + +(defun spacemacs/vcs-stage-hunk () + (interactive) + (if (eq 'diff-hl version-control-diff-tool) + (message "Staging not available") + (let ((current-prefix-arg t)) + (call-interactively + (cl-case version-control-diff-tool + (git-gutter 'git-gutter:stage-hunk) + (git-gutter+ 'git-gutter+-stage-hunks)))))) + +(defun spacemacs/vcs-show-hunk () + (interactive) + (let ((current-prefix-arg t)) + (call-interactively + (cl-case version-control-diff-tool + (diff-hl 'diff-hl-diff-goto-hunk) + (git-gutter 'git-gutter:popup-hunk) + (git-gutter+ 'git-gutter+-show-hunk-inline-at-point))))) + +(defun spacemacs/vcs-enable-margin () + (interactive) + (let ((current-prefix-arg t)) + (call-interactively + (cl-case version-control-diff-tool + (diff-hl 'diff-hl-mode) + (git-gutter 'git-gutter-mode) + (git-gutter+ 'git-gutter+-mode))))) + +(defun spacemacs/vcs-disable-margin () + (interactive) + (let ((current-prefix-arg nil)) + (call-interactively + (cl-case version-control-diff-tool + (diff-hl 'diff-hl-mode) + (git-gutter 'git-gutter-mode) + (git-gutter+ 'git-gutter+-mode))))) + +(defun spacemacs/vcs-enable-margin-globally () + (interactive) + (let ((current-prefix-arg t)) + (call-interactively + (cl-case version-control-diff-tool + (diff-hl 'global-diff-hl-mode) + (git-gutter 'global-git-gutter-mode) + (git-gutter+ 'global-git-gutter+-mode))))) + +(defun spacemacs/vcs-disable-margin-globally () + (interactive) + (let ((current-prefix-arg nil)) + (call-interactively + (cl-case version-control-diff-tool + (diff-hl 'global-diff-hl-mode) + (git-gutter 'global-git-gutter-mode) + (git-gutter+ 'global-git-gutter+-mode))))) + +(defun spacemacs/vcs-show-help () + (interactive) + (setq version-control--ms-doc-toggle + (logxor version-control--ms-doc-toggle 1))) + +(defun spacemacs/vcs-margin-p () + (interactive) + (cl-case version-control-diff-tool + (diff-hl diff-hl-mode) + (git-gutter (bound-and-true-p git-gutter-mode)) + (git-gutter+ (bound-and-true-p git-gutter+-mode)))) + +(defun spacemacs/vcs-margin-global-p () + (interactive) + (cl-case version-control-diff-tool + (diff-hl global-diff-hl-mode) + (git-gutter global-git-gutter-mode) + (git-gutter+ global-git-gutter+-mode))) + +(spacemacs|add-toggle version-control-margin + :status (spacemacs/vcs-margin-p) + :on (spacemacs/vcs-enable-margin) + :off (spacemacs/vcs-disable-margin) + :documentation "Enable diff margins." + :evil-leader "Td") + +(spacemacs|add-toggle version-control-margin-globally + :status (spacemacs/vcs-margin-global-p) + :on (spacemacs/vcs-enable-margin-globally) + :off (spacemacs/vcs-disable-margin-globally) + :documentation "Enable diff margins globally." + :evil-leader "T C-d") diff --git a/layers/+source-control/version-control/keybindings.el b/layers/+source-control/version-control/keybindings.el new file mode 100644 index 0000000..c903506 --- /dev/null +++ b/layers/+source-control/version-control/keybindings.el @@ -0,0 +1,42 @@ +;;; keybindings.el --- Version control keybindings +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(spacemacs|define-transient-state vcs + :title "VCS Transient State" + :doc " + Hunk Commands^^^^^^ Magit Commands +----------------------------^^^^^^ ------------------------------------------ + [_n_]^^^^ next hunk [_w_/_u_]^^ stage/unstage in current file + [_N_/_p_]^^ previous hunk [_c_/_C_]^^ commit with popup/direct commit + [_r_/_s_/_h_] revert/stage/show [_f_/_F_/_P_] fetch/pull/push popup + [_t_]^^^^ toggle diff signs [_l_/_D_]^^ log/diff popup" + :on-enter (spacemacs/vcs-enable-margin) + :bindings + ("C" magit-commit :exit t) + ("d" magit-ediff-popup :exit t) + ("D" magit-diff-unstaged :exit t) + ("F" magit-pull-popup :exit t) + ("P" magit-push-popup :exit t) + ("c" magit-commit-popup :exit t) + ("f" magit-fetch-popup :exit t) + ("l" magit-log-popup :exit t) + ("u" magit-unstage-file) + ("w" magit-stage-file) + ("n" spacemacs/vcs-next-hunk) + ("N" spacemacs/vcs-previous-hunk) + ("p" spacemacs/vcs-previous-hunk) + ("r" spacemacs/vcs-revert-hunk) + ("s" spacemacs/vcs-stage-hunk) + ("h" spacemacs/vcs-show-hunk) + ("t" spacemacs/toggle-version-control-margin) + ("q" nil :exit t)) +(spacemacs/set-leader-keys "g." 'spacemacs/vcs-transient-state/body) + diff --git a/layers/+source-control/version-control/packages.el b/layers/+source-control/version-control/packages.el new file mode 100644 index 0000000..8951882 --- /dev/null +++ b/layers/+source-control/version-control/packages.el @@ -0,0 +1,168 @@ +;;; packages.el --- Source Control Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq version-control-packages + '( + diff-mode + diff-hl + evil-unimpaired + git-gutter + git-gutter+ + git-gutter-fringe + git-gutter-fringe+ + )) + +(defun version-control/init-diff-mode () + (use-package diff-mode + :defer t + :config + (evilified-state-evilify diff-mode diff-mode-map + "j" 'diff-hunk-next + "k" 'diff-hunk-prev))) + +(defun version-control/init-diff-hl () + (use-package diff-hl + :init + (progn + (setq diff-hl-side 'left) + (when (eq version-control-diff-tool 'diff-hl) + (when (configuration-layer/package-usedp 'magit) + (add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh)) + (when version-control-global-margin + (global-diff-hl-mode)) + (diff-hl-margin-mode) + (spacemacs|do-after-display-system-init + (setq diff-hl-side 'right) + (diff-hl-margin-mode -1)))))) + +(defun version-control/post-init-evil-unimpaired () + (define-key evil-normal-state-map (kbd "[ h") 'spacemacs/vcs-previous-hunk) + (define-key evil-normal-state-map (kbd "] h") 'spacemacs/vcs-next-hunk)) + +(defun version-control/init-git-gutter () + (use-package git-gutter + :commands (global-git-gutter-mode git-gutter-mode) + :init + (progn + ;; If you enable global minor mode + (when (and (eq version-control-diff-tool 'git-gutter) + version-control-global-margin) + (global-git-gutter-mode t)) + ;; If you would like to use git-gutter.el and linum-mode + (if dotspacemacs-line-numbers + (git-gutter:linum-setup)) + (setq git-gutter:update-interval 2 + git-gutter:modified-sign " " + git-gutter:added-sign "+" + git-gutter:deleted-sign "-" + git-gutter:diff-option "-w" + git-gutter:hide-gutter t + git-gutter:ask-p nil + git-gutter:verbosity 0 + git-gutter:handled-backends '(git hg bzr svn) + git-gutter:hide-gutter t)) + :config + (spacemacs|hide-lighter git-gutter-mode))) + +(defun version-control/init-git-gutter-fringe () + (use-package git-gutter-fringe + :commands git-gutter-mode + :init + (progn + (spacemacs|do-after-display-system-init + (with-eval-after-load 'git-gutter + (require 'git-gutter-fringe))) + (setq git-gutter-fr:side 'right-fringe)) + :config + (progn + ;; custom graphics that works nice with half-width fringes + (fringe-helper-define 'git-gutter-fr:added nil + "..X...." + "..X...." + "XXXXX.." + "..X...." + "..X...." + ) + (fringe-helper-define 'git-gutter-fr:deleted nil + "......." + "......." + "XXXXX.." + "......." + "......." + ) + (fringe-helper-define 'git-gutter-fr:modified nil + "..X...." + ".XXX..." + "XX.XX.." + ".XXX..." + "..X...." + )))) + +(defun version-control/init-git-gutter+ () + (use-package git-gutter+ + :commands (global-git-gutter+-mode git-gutter+-mode) + :init + (progn + ;; If you enable global minor mode + (when (and (eq version-control-diff-tool 'git-gutter+) + version-control-global-margin) + (add-hook 'magit-pre-refresh-hook 'git-gutter+-refresh) + (global-git-gutter+-mode t)) + (setq + git-gutter+-modified-sign " " + git-gutter+-added-sign "+" + git-gutter+-deleted-sign "-" + git-gutter+-diff-option "-w" + git-gutter+-hide-gutter t)) + ;; identify magit changes + :config + (spacemacs|hide-lighter git-gutter+-mode) + ;; (set-face-foreground 'git-gutter+-modified "black") + ;; (set-face-foreground 'git-gutter+-added "black") + ;; (set-face-foreground 'git-gutter+-deleted "black") + ;; (set-face-background 'git-gutter+-modified "orange1") + ;; (set-face-background 'git-gutter+-added "green4") + ;; (set-face-background 'git-gutter+-deleted "red3") + )) + +(defun version-control/init-git-gutter-fringe+ () + (use-package git-gutter-fringe+ + :commands git-gutter+-mode + :init + (progn + (spacemacs|do-after-display-system-init + (with-eval-after-load 'git-gutter+ + (require 'git-gutter-fringe+))) + (setq git-gutter-fr+-side 'right-fringe)) + :config + (progn + ;; custom graphics that works nice with half-width fringes + (fringe-helper-define 'git-gutter-fr+-added nil + "..X...." + "..X...." + "XXXXX.." + "..X...." + "..X...." + ) + (fringe-helper-define 'git-gutter-fr+-deleted nil + "......." + "......." + "XXXXX.." + "......." + "......." + ) + (fringe-helper-define 'git-gutter-fr+-modified nil + "..X...." + ".XXX..." + "XX.XX.." + ".XXX..." + "..X...." + )))) diff --git a/layers/+spacemacs/spacemacs-completion/config.el b/layers/+spacemacs/spacemacs-completion/config.el new file mode 100644 index 0000000..faa3128 --- /dev/null +++ b/layers/+spacemacs/spacemacs-completion/config.el @@ -0,0 +1,30 @@ +;;; config.el --- Spacemacs Completion Layer configuration File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + +;; Helm + +(defface spacemacs-helm-navigation-ms-face + `((t :background ,(face-attribute 'error :foreground) + :foreground "black")) + "Face for helm header when helm transient-state is activated." + :group 'spacemacs) + +;; from https://www.reddit.com/r/emacs/comments/2z7nbv/lean_helm_window/ +(with-eval-after-load 'helm + (defvar helm-source-header-default-background + (face-attribute 'helm-source-header :background)) + (defvar helm-source-header-default-foreground + (face-attribute 'helm-source-header :foreground)) + (defvar helm-source-header-default-box + (face-attribute 'helm-source-header :box)) + (defvar helm-source-header-default-height + (face-attribute 'helm-source-header :height) )) diff --git a/layers/+spacemacs/spacemacs-completion/funcs.el b/layers/+spacemacs/spacemacs-completion/funcs.el new file mode 100644 index 0000000..0f64588 --- /dev/null +++ b/layers/+spacemacs/spacemacs-completion/funcs.el @@ -0,0 +1,213 @@ +;;; funcs.el --- Spacemacs Completion Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + + +;; Helm + +(defun spacemacs/helm-faces () + "Describe face." + (interactive) + (require 'helm-elisp) + (let ((default (or (face-at-point) (thing-at-point 'symbol)))) + (helm :sources (helm-def-source--emacs-faces + (format "%s" (or default "default"))) + :buffer "*helm faces*"))) + +(defun spacemacs//hide-cursor-in-helm-buffer () + "Hide the cursor in helm buffers." + (with-helm-buffer + (setq cursor-in-non-selected-windows nil))) + +(defun spacemacs//set-dotted-directory () + "Set the face of diretories for `.' and `..'" + (set-face-attribute 'helm-ff-dotted-directory + nil + :foreground nil + :background nil + :inherit 'helm-ff-directory)) + +(defun spacemacs//helm-make-source (f &rest args) + "Function to be used as advice to activate fuzzy matching for all sources." + (let ((source-type (cadr args)) + (props (cddr args))) + (unless (eq source-type 'helm-source-async) + (plist-put props :fuzzy-match (eq 'always dotspacemacs-helm-use-fuzzy)))) + (apply f args)) + +;; Helm Header line + +(defun spacemacs//helm-hide-minibuffer-maybe () + "Hide minibuffer in Helm session if we use the header line as input field." + (when (with-helm-buffer helm-echo-input-in-header-line) + (let ((ov (make-overlay (point-min) (point-max) nil nil t))) + (overlay-put ov 'window (selected-window)) + (overlay-put ov 'face + (let ((bg-color (face-background 'default nil))) + `(:background ,bg-color :foreground ,bg-color))) + (setq-local cursor-type nil)))) + +(defun helm-toggle-header-line () + "Hide the `helm' header if there is only one source." + (when dotspacemacs-helm-no-header + (if (> (length helm-sources) 1) + (set-face-attribute + 'helm-source-header + nil + :foreground helm-source-header-default-foreground + :background helm-source-header-default-background + :box helm-source-header-default-box + :height helm-source-header-default-height) + (set-face-attribute + 'helm-source-header + nil + :foreground (face-attribute 'default :background) + :background (face-attribute 'default :background) + :box nil + :height 0.1)))) + +;; helm navigation on hjkl +(defun spacemacs//helm-hjkl-navigation (style) + "Set navigation on 'hjkl' for the given editing STYLE." + (cond + ((or (eq 'vim style) + (and (eq 'hybrid style) + hybrid-mode-enable-hjkl-bindings)) + (define-key helm-map (kbd "C-j") 'helm-next-line) + (define-key helm-map (kbd "C-k") 'helm-previous-line) + (define-key helm-map (kbd "C-h") 'helm-next-source) + (define-key helm-map (kbd "C-S-h") 'describe-key) + (define-key helm-map (kbd "C-l") (kbd "RET")) + (with-eval-after-load 'helm-files + (dolist (keymap (list helm-find-files-map helm-read-file-map)) + (define-key keymap (kbd "C-l") 'helm-execute-persistent-action) + (define-key keymap (kbd "C-h") 'helm-find-files-up-one-level) + ;; rebind `describe-key' for convenience + (define-key keymap (kbd "C-S-h") 'describe-key)))) + (t + (define-key helm-map (kbd "C-j") 'helm-execute-persistent-action) + (define-key helm-map (kbd "C-k") 'helm-delete-minibuffer-contents) + (define-key helm-map (kbd "C-h") nil) + (define-key helm-map + (kbd "C-l") 'helm-recenter-top-bottom-other-window)))) + +;; Helm Window position + +(defvar spacemacs-helm-display-help-buffer-regexp '("*.*Helm.*Help.**")) +(defvar spacemacs-helm-display-buffer-regexp + `("*.*helm.**" + (display-buffer-in-side-window) + (inhibit-same-window . t) + (side . ,dotspacemacs-helm-position) + (window-width . 0.6) + (window-height . 0.4))) +(defvar spacemacs-display-buffer-alist nil) + +(defun spacemacs//display-helm-window (buffer) + "Display the Helm window respecting `dotspacemacs-helm-position'." + (let ((display-buffer-alist + (list spacemacs-helm-display-help-buffer-regexp + ;; this or any specialized case of Helm buffer must be + ;; added AFTER `spacemacs-helm-display-buffer-regexp'. + ;; Otherwise, `spacemacs-helm-display-buffer-regexp' will + ;; be used before + ;; `spacemacs-helm-display-help-buffer-regexp' and display + ;; configuration for normal Helm buffer is applied for helm + ;; help buffer, making the help buffer unable to be + ;; displayed. + spacemacs-helm-display-buffer-regexp))) + (helm-default-display-buffer buffer))) + +(defun spacemacs//unprevent-minibuffer-escape () + "Workaround for a helm-evil incompatibility. +See https://github.com/syl20bnr/spacemacs/issues/3700" + (when helm-prevent-escaping-from-minibuffer + (define-key evil-motion-state-map + [down-mouse-1] 'evil-mouse-drag-region))) + +(defun spacemacs//prevent-minibuffer-escape () + "Workaround for a helm-evil incompatibility. +See https://github.com/syl20bnr/spacemacs/issues/3700" + (when helm-prevent-escaping-from-minibuffer + (define-key evil-motion-state-map [down-mouse-1] nil))) + +;; Helm Transient state + +(defun spacemacs//define-helm-action-functions () + "Define Spacemacs functions to pick actions." + (dotimes (n 10) + (let ((func (intern (format "spacemacs/helm-action-%d" n))) + (doc (format "Select helm action #%d" n))) + (eval `(defun ,func () + ,doc + (intern) + (helm-select-nth-action ,(1- n))))))) + +(defun spacemacs/helm-ts-edit () + "Switch in edit mode depending on the current helm buffer." + (interactive) + (cond + ((string-equal "*helm-ag*" helm-buffer) + (helm-ag-edit)))) + +(defun spacemacs//helm-navigation-ts-on-enter () + "Initialization of helm transient-state." + ;; faces + (spacemacs//helm-navigation-ts-set-face) + (setq spacemacs--helm-navigation-ts-face-cookie-minibuffer + (face-remap-add-relative + 'minibuffer-prompt + 'spacemacs-helm-navigation-ts-face))) + +(defun spacemacs//helm-navigation-ts-set-face () + "Set the face for helm header in helm navigation transient-state" + (with-helm-window + (setq spacemacs--helm-navigation-ts-face-cookie-header + (face-remap-add-relative + 'helm-header + 'spacemacs-helm-navigation-ts-face)))) + +(defun spacemacs//helm-navigation-ts-on-exit () + "Action to perform when exiting helm transient-state." + (with-helm-window + (face-remap-remove-relative + spacemacs--helm-navigation-ts-face-cookie-header)) + (face-remap-remove-relative + spacemacs--helm-navigation-ts-face-cookie-minibuffer)) + +(defun spacemacs/helm-transient-state-select-action () + "Display the Helm actions page." + (interactive) + (call-interactively 'helm-select-action) + (spacemacs//helm-navigation-ts-set-face)) + + +;; Ivy + +(defun spacemacs//ivy-hjkl-navigation (style) + "Set navigation on 'hjkl' for the given editing STYLE." + (cond + ((or (eq 'vim style) + (and (eq 'hybrid style) + hybrid-mode-enable-hjkl-bindings)) + (define-key ivy-minibuffer-map (kbd "C-j") 'ivy-next-line) + (define-key ivy-minibuffer-map (kbd "C-k") 'ivy-previous-line) + (define-key ivy-minibuffer-map (kbd "C-h") (kbd "DEL")) + ;; Move C-h to C-S-h + (define-key ivy-minibuffer-map (kbd "C-S-h") help-map) + (define-key ivy-minibuffer-map (kbd "C-l") 'ivy-alt-done) + (define-key ivy-minibuffer-map (kbd "") + 'minibuffer-keyboard-quit)) + (t + (define-key ivy-minibuffer-map (kbd "C-j") 'ivy-alt-done) + (define-key ivy-minibuffer-map (kbd "C-k") 'ivy-kill-line) + (define-key ivy-minibuffer-map (kbd "C-h") nil) + (define-key ivy-minibuffer-map (kbd "C-l") nil)))) diff --git a/layers/+spacemacs/spacemacs-completion/packages.el b/layers/+spacemacs/spacemacs-completion/packages.el new file mode 100644 index 0000000..fff2ecb --- /dev/null +++ b/layers/+spacemacs/spacemacs-completion/packages.el @@ -0,0 +1,361 @@ +;;; packages.el --- Spacemacs Completion Layer packages File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq spacemacs-completion-packages + '( + (default-helm-config :location built-in) + (default-ivy-config :location built-in) + (ido :location built-in) + ido-vertical-mode + )) + +(defun spacemacs-completion/init-default-helm-config () + (setq helm-prevent-escaping-from-minibuffer t + helm-bookmark-show-location t + helm-display-header-line nil + helm-split-window-in-side-p t + helm-always-two-windows t + helm-echo-input-in-header-line t + helm-imenu-execute-action-at-once-if-one nil + helm-org-format-outline-path t + helm-display-function 'spacemacs//display-helm-window) + (with-eval-after-load 'helm + (spacemacs|hide-lighter helm-mode) + (when (and dotspacemacs-helm-resize + (or (eq dotspacemacs-helm-position 'bottom) + (eq dotspacemacs-helm-position 'top))) + (setq helm-autoresize-min-height 10) + (helm-autoresize-mode 1)) + ;; setup hooks + (add-hook 'helm-minibuffer-set-up-hook + 'spacemacs//helm-hide-minibuffer-maybe) + (add-hook 'helm-before-initialize-hook 'helm-toggle-header-line) + (spacemacs/add-to-hook 'helm-after-initialize-hook + '(spacemacs//prevent-minibuffer-escape + spacemacs//hide-cursor-in-helm-buffer)) + (add-hook 'helm-cleanup-hook #'spacemacs//unprevent-minibuffer-escape) + (add-hook 'helm-find-files-before-init-hook + 'spacemacs//set-dotted-directory) + (add-hook 'spacemacs-editing-style-hook 'spacemacs//helm-hjkl-navigation) + ;; setup advices + ;; fuzzy matching for all the sourcess + (unless (eq dotspacemacs-helm-use-fuzzy 'source) + (advice-add 'helm-make-source :around #'spacemacs//helm-make-source)) + + (defadvice spacemacs/post-theme-init + (after spacemacs/helm-header-line-adv activate) + "Update defaults for `helm' header line whenever a new theme is loaded" + ;; TODO factorize face definition with those defined in config.el + (setq helm-source-header-default-foreground + (face-attribute 'helm-source-header :foreground) + helm-source-header-default-background + (face-attribute 'helm-source-header :background) + helm-source-header-default-box + (face-attribute 'helm-source-header :box) + helm-source-header-default-height + (face-attribute 'helm-source-header :height))) + ;; ensure that the correct bindings are set at startup + (spacemacs//helm-hjkl-navigation dotspacemacs-editing-style) + ;; Transient state + (spacemacs//define-helm-action-functions) + (spacemacs|define-transient-state helm-navigation + :title "Helm Transient State" + :doc " + [_j_/_k_] next/prev candidate [_v_]^^ persistent action [_e_]^^ edit occurrences + [_h_/_l_] prev/next source [_1_.._0_] action 1..10 [_t_/_T_] toggle visible/all mark + [_q_]^^ quit [_a_]^^ action selection pg" + :foreign-keys run + :on-enter (spacemacs//helm-navigation-ts-on-enter) + :on-exit (spacemacs//helm-navigation-ts-on-exit) + :bindings + ("1" spacemacs/helm-action-1 :exit t) + ("2" spacemacs/helm-action-2 :exit t) + ("3" spacemacs/helm-action-3 :exit t) + ("4" spacemacs/helm-action-4 :exit t) + ("5" spacemacs/helm-action-5 :exit t) + ("6" spacemacs/helm-action-6 :exit t) + ("7" spacemacs/helm-action-7 :exit t) + ("8" spacemacs/helm-action-8 :exit t) + ("9" spacemacs/helm-action-9 :exit t) + ("0" spacemacs/helm-action-10 :exit t) + ("" helm-select-action :exit t) + ("TAB" helm-select-action :exit t) + ("" helm-maybe-exit-minibuffer :exit t) + ;; ("?" nil :doc (spacemacs//helm-navigation-ts-full-doc)) + ("a" spacemacs/helm-transient-state-select-action) + ("e" spacemacs/helm-ts-edit) + ("g" helm-beginning-of-buffer) + ("G" helm-end-of-buffer) + ("h" helm-previous-source) + ("j" helm-next-line) + ("k" helm-previous-line) + ("l" helm-next-source) + ("q" nil :exit t) + ("t" helm-toggle-visible-mark) + ("T" helm-toggle-all-marks) + ("v" helm-execute-persistent-action)) + (define-key helm-map (kbd "M-SPC") + 'spacemacs/helm-navigation-transient-state/body) + (define-key helm-map (kbd "s-M-SPC") + 'spacemacs/helm-navigation-transient-state/body) + ;; Swap default TAB and C-z commands. + ;; For GUI. + (with-eval-after-load 'helm-files + (define-key helm-map (kbd "") 'helm-execute-persistent-action) + (define-key helm-find-files-map + (kbd "S-") 'helm-find-files-up-one-level) + (define-key helm-find-files-map + (kbd "") 'helm-find-files-up-one-level) + ;; For terminal. + (define-key helm-map (kbd "TAB") 'helm-execute-persistent-action) + (define-key helm-find-files-map + (kbd "S-TAB") 'helm-find-files-up-one-level) + (define-key helm-map (kbd "C-z") 'helm-select-action)))) + +(defun spacemacs-completion/init-default-ivy-config () + (with-eval-after-load 'ivy + (setq ivy-height 15 + ivy-re-builders-alist '((t . ivy--regex-ignore-order))) + (spacemacs|hide-lighter ivy-mode) + ;; setup hooks + (add-hook 'spacemacs-editing-style-hook 'spacemacs//ivy-hjkl-navigation) + ;; key bindings + ;; ensure that the correct bindings are set at startup + (spacemacs//ivy-hjkl-navigation dotspacemacs-editing-style) + ;; Transient state + ;; ivy-hydra disabled for now, waiting to see how the dependency management + ;; evolves upstream + ;; (require 'ivy-hydra) + (spacemacs|define-transient-state ivy + :doc " + Move/Resize^^^^ | Select Action^^^^ | Call^^ | Cancel^^ | Toggles +--^-^-^-^-------------|--^-^-^-^------------|--^---^-----------|--^-^---------|--------------------- + [_j_/_k_] by line | [_s_/_w_] next/prev | [_RET_] & done | [_i_] & ins | [_C_] calling: %s(if ivy-calling \"on\" \"off\") + [_g_/_G_] first/last | [_a_]^ ^ list all | [_TAB_] alt done | [_q_] & quit | [_m_] matcher: %s(ivy--matcher-desc) + [_d_/_u_] pg down/up | ^ ^ ^ ^ | [_c_] & cont | ^ ^ | [_f_] case-fold: %`ivy-case-fold-search + [_<_/_>_] resize | ^ ^ ^ ^ | [_o_] occur | ^ ^ | [_t_] truncate: %`truncate-lines + [_h_/_l_] out/in dir | ^ ^ ^ ^ | ^ ^ | ^ ^ | ^ ^ + +Current Action: %s(ivy-action-name) +" + :foreign-keys run + :bindings + ;; arrows + ("j" ivy-next-line) + ("k" ivy-previous-line) + ("l" ivy-alt-done) + ("h" spacemacs/counsel-up-directory-no-error) + ("g" ivy-beginning-of-buffer) + ("G" ivy-end-of-buffer) + ("d" ivy-scroll-up-command) + ("u" ivy-scroll-down-command) + ;; actions + ("q" keyboard-escape-quit :exit t) + ("C-g" keyboard-escape-quit :exit t) + ("" keyboard-escape-quit :exit t) + ("i" nil) + ("C-o" nil) + ("TAB" ivy-alt-done :exit nil) + ;; ("C-j" ivy-alt-done :exit nil) + ;; ("d" ivy-done :exit t) + ("RET" ivy-done :exit t) + ("c" ivy-call) + ("C-m" ivy-done :exit t) + ("C" ivy-toggle-calling) + ("m" ivy-toggle-fuzzy) + (">" ivy-minibuffer-grow) + ("<" ivy-minibuffer-shrink) + ("w" ivy-prev-action) + ("s" ivy-next-action) + ("a" ivy-read-action) + ("t" (setq truncate-lines (not truncate-lines))) + ("f" ivy-toggle-case-fold) + ("o" ivy-occur :exit t)) + (define-key ivy-minibuffer-map "\C-o" 'spacemacs/ivy-transient-state/body) + )) + +(defun spacemacs-completion/init-ido () + (setq ido-save-directory-list-file + (concat spacemacs-cache-directory "ido.last") + ;; enable fuzzy matching + ido-enable-flex-matching t) + (ido-mode t)) + +(defun spacemacs-completion/init-ido-vertical-mode () + (use-package ido-vertical-mode + :init + (progn + (ido-vertical-mode t) + (defun spacemacs//ido-minibuffer-setup () + "Setup the minibuffer." + ;; Since ido is implemented in a while loop where each + ;; iteration setup a whole new minibuffer, we have to keep + ;; track of any activated ido navigation transient-state and force + ;; the reactivation at each iteration. + (when spacemacs--ido-navigation-ms-enabled + (spacemacs/ido-navigation-micro-state))) + (add-hook 'ido-minibuffer-setup-hook 'spacemacs//ido-minibuffer-setup) + + (defun spacemacs//ido-setup () + (when spacemacs--ido-navigation-ms-face-cookie-minibuffer + (face-remap-remove-relative + spacemacs--ido-navigation-ms-face-cookie-minibuffer)) + ;; be sure to wipe any previous transient-state flag + (setq spacemacs--ido-navigation-ms-enabled nil) + ;; overwrite the key bindings for ido vertical mode only + (define-key ido-completion-map (kbd "C-") 'ido-select-text) + ;; use M-RET in terminal + (define-key ido-completion-map "\M-\r" 'ido-select-text) + (define-key ido-completion-map (kbd "C-h") 'ido-delete-backward-updir) + (define-key ido-completion-map (kbd "C-j") 'ido-next-match) + (define-key ido-completion-map (kbd "C-k") 'ido-prev-match) + (define-key ido-completion-map (kbd "C-l") 'ido-exit-minibuffer) + (define-key ido-completion-map (kbd "C-n") 'ido-next-match) + (define-key ido-completion-map (kbd "C-p") 'ido-prev-match) + (define-key ido-completion-map (kbd "C-S-h") 'ido-prev-match-dir) + (define-key ido-completion-map (kbd "C-S-j") 'next-history-element) + (define-key ido-completion-map (kbd "C-S-k") 'previous-history-element) + (define-key ido-completion-map (kbd "C-S-l") 'ido-next-match-dir) + (define-key ido-completion-map (kbd "C-S-n") 'next-history-element) + (define-key ido-completion-map (kbd "C-S-p") 'previous-history-element) + ;; ido-other window maps + (define-key ido-completion-map (kbd "C-o") 'spacemacs/ido-invoke-in-other-window) + (define-key ido-completion-map (kbd "C-s") 'spacemacs/ido-invoke-in-vertical-split) + (define-key ido-completion-map (kbd "C-t") 'spacemacs/ido-invoke-in-new-frame) + (define-key ido-completion-map (kbd "C-v") 'spacemacs/ido-invoke-in-horizontal-split) + ;; more natural navigation keys: up, down to change current item + ;; left to go up dir + ;; right to open the selected item + (define-key ido-completion-map (kbd "") 'ido-prev-match) + (define-key ido-completion-map (kbd "") 'ido-next-match) + (define-key ido-completion-map (kbd "") 'ido-delete-backward-updir) + (define-key ido-completion-map (kbd "") 'ido-exit-minibuffer) + ;; initiate transient-state + (define-key ido-completion-map (kbd "M-SPC") 'spacemacs/ido-navigation-micro-state) + (define-key ido-completion-map (kbd "s-M-SPC") 'spacemacs/ido-navigation-micro-state) + ) + (add-hook 'ido-setup-hook 'spacemacs//ido-setup) + + (defun spacemacs/ido-invoke-in-other-window () + "signals ido mode to switch to (or create) another window after exiting" + (interactive) + (setq ido-exit-minibuffer-target-window 'other) + (ido-exit-minibuffer)) + + (defun spacemacs/ido-invoke-in-horizontal-split () + "signals ido mode to split horizontally and switch after exiting" + (interactive) + (setq ido-exit-minibuffer-target-window 'horizontal) + (ido-exit-minibuffer)) + + (defun spacemacs/ido-invoke-in-vertical-split () + "signals ido mode to split vertically and switch after exiting" + (interactive) + (setq ido-exit-minibuffer-target-window 'vertical) + (ido-exit-minibuffer)) + + (defun spacemacs/ido-invoke-in-new-frame () + "signals ido mode to create a new frame after exiting" + (interactive) + (setq ido-exit-minibuffer-target-window 'frame) + (ido-exit-minibuffer)) + + (defadvice ido-read-internal + (around ido-read-internal-with-minibuffer-other-window activate) + (let* (ido-exit-minibuffer-target-window + (this-buffer (current-buffer)) + (result ad-do-it)) + (cond + ((equal ido-exit-minibuffer-target-window 'other) + (if (= 1 (count-windows)) + (spacemacs/split-window-horizontally-and-switch) + (other-window 1))) + ((equal ido-exit-minibuffer-target-window 'horizontal) + (spacemacs/split-window-horizontally-and-switch)) + + ((equal ido-exit-minibuffer-target-window 'vertical) + (spacemacs/split-window-vertically-and-switch)) + ((equal ido-exit-minibuffer-target-window 'frame) + (make-frame))) + ;; why? Some ido commands, such as textmate.el's + ;; textmate-goto-symbol don't switch the current buffer + (switch-to-buffer this-buffer) + result)) + + (defvar spacemacs--ido-navigation-ms-enabled nil + "Flag which is non nil when ido navigation transient-state is enabled.") + + (defvar spacemacs--ido-navigation-ms-face-cookie-minibuffer nil + "Cookie pointing to the local face remapping.") + + (defface spacemacs-ido-navigation-ms-face + `((t :background ,(face-attribute 'error :foreground) + :foreground "black" + :weight bold)) + "Face for ido minibuffer prompt when ido transient-state is activated." + :group 'spacemacs) + + (defun spacemacs//ido-navigation-ms-set-face () + "Set faces for ido navigation transient-state." + (setq spacemacs--ido-navigation-ms-face-cookie-minibuffer + (face-remap-add-relative + 'minibuffer-prompt + 'spacemacs-ido-navigation-ms-face))) + + (defun spacemacs//ido-navigation-ms-on-enter () + "Initialization of ido transient-state." + (setq spacemacs--ido-navigation-ms-enabled t) + (spacemacs//ido-navigation-ms-set-face)) + + (defun spacemacs//ido-navigation-ms-on-exit () + "Action to perform when exiting ido transient-state." + (face-remap-remove-relative + spacemacs--ido-navigation-ms-face-cookie-minibuffer)) + + (defun spacemacs//ido-navigation-ms-full-doc () + "Full documentation for ido navigation transient-state." + " + [?] display this help + [e] enter dired + [j] [k] next/previous match + [J] [K] sub/parent directory + [h] delete backward or parent directory + [l] select match + [n] [p] next/previous directory in history + [o] open in other window + [s] open in a new horizontal split + [t] open in other frame + [v] open in a new vertical split + [q] quit") + + (spacemacs|define-transient-state ido-navigation + :title "ido Transient State" + :foreign-keys run + :on-enter (spacemacs//ido-navigation-ms-on-enter) + :on-exit (spacemacs//ido-navigation-ms-on-exit) + :bindings + ;;("?" nil (spacemacs//ido-navigation-ms-full-doc)) + ("" ido-exit-minibuffer :exit t) + ("" nil :exit t) + ("e" ido-select-text :exit t) + ("h" ido-delete-backward-updir) + ("j" ido-next-match) + ("J" ido-next-match-dir) + ("k" ido-prev-match) + ("K" ido-prev-match-dir) + ("l" ido-exit-minibuffer :exit t) + ("n" ido-next-match-dir) + ("o" spacemacs/ido-invoke-in-other-window :exit t) + ("p" ido-prev-match-dir) + ("q" nil :exit t) + ("s" spacemacs/ido-invoke-in-vertical-split :exit t) + ("t" spacemacs/ido-invoke-in-new-frame :exit t) + ("v" spacemacs/ido-invoke-in-horizontal-split :exit t))))) diff --git a/layers/+spacemacs/spacemacs-editing-visual/packages.el b/layers/+spacemacs/spacemacs-editing-visual/packages.el new file mode 100644 index 0000000..05eabf7 --- /dev/null +++ b/layers/+spacemacs/spacemacs-editing-visual/packages.el @@ -0,0 +1,409 @@ +;;; packages.el --- Spacemacs Editing Visual Layer packages File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq spacemacs-editing-visual-packages + '( + ;; default + adaptive-wrap + auto-highlight-symbol + column-enforce-mode + hide-comnt + highlight-indentation + highlight-numbers + highlight-parentheses + ;; waiting for an overlay bug to be fixed + ;; see https://github.com/syl20bnr/spacemacs/issues/2529 + (hl-anything :excluded t) + indent-guide + rainbow-delimiters + volatile-highlights + )) + +;; Initialization of packages + +(defun spacemacs-editing-visual/init-adaptive-wrap () + (use-package adaptive-wrap + :config + (progn + (add-hook 'visual-line-mode-hook 'adaptive-wrap-prefix-mode)))) + +(defun spacemacs-editing-visual/init-auto-highlight-symbol () + (use-package auto-highlight-symbol + :defer t + :init + (progn + (setq ahs-case-fold-search nil + ahs-default-range 'ahs-range-whole-buffer + ;; by default disable auto-highlight of symbol + ;; current symbol can always be highlighted with `SPC s h' + ahs-idle-timer 0 + ahs-idle-interval 0.25 + ahs-inhibit-face-list nil + spacemacs--symbol-highlight-transient-state-doc + " + %s [_n_] next [_N_/_p_] previous [_r_] change range [_R_] reset [_e_] iedit + %s [_d_/_D_] next/previous definition") + + ;; since we are creating our own maps, + ;; prevent the default keymap from getting created + (setq auto-highlight-symbol-mode-map (make-sparse-keymap)) + + (spacemacs|add-toggle automatic-symbol-highlight + :status (timerp ahs-idle-timer) + :on (progn + (auto-highlight-symbol-mode) + (setq ahs-idle-timer + (run-with-idle-timer ahs-idle-interval t + 'ahs-idle-function))) + :off (when (timerp ahs-idle-timer) + (auto-highlight-symbol-mode) + (cancel-timer ahs-idle-timer) + (setq ahs-idle-timer 0)) + :documentation "Automatic highlight of current symbol." + :evil-leader "tha") + (spacemacs/add-to-hooks 'auto-highlight-symbol-mode '(prog-mode-hook + markdown-mode-hook))) + :config + (progn + (spacemacs|hide-lighter auto-highlight-symbol-mode) + (defvar-local spacemacs-last-ahs-highlight-p nil + "Info on the last searched highlighted symbol.") + (defvar-local spacemacs--ahs-searching-forward t) + + (defun spacemacs/goto-last-searched-ahs-symbol () + "Go to the last known occurrence of the last symbol searched with +`auto-highlight-symbol'." + (interactive) + (if spacemacs-last-ahs-highlight-p + (progn (goto-char (nth 1 spacemacs-last-ahs-highlight-p)) + (spacemacs/ahs-highlight-now-wrapper) + (spacemacs/symbol-highlight-transient-state/body)) + (message "No symbol has been searched for now."))) + + (defun spacemacs/integrate-evil-search (forward) + ;; isearch-string is last searched item. Next time + ;; "n" is hit we will use this. + (setq isearch-string + (concat "\\<" (evil-find-thing forward 'symbol) "\\>") + isearch-regexp + (concat "\\<" (evil-find-thing forward 'symbol) "\\>")) + ;; Next time "n" is hit, go the correct direction. + (setq isearch-forward forward) + ;; ahs does a case sensitive search. We could set + ;; this, but it would break the user's current + ;; sensitivity settings. We could save the setting, + ;; then next time the user starts a search we could + ;; restore the setting. + ;;(setq case-fold-search nil) + ;; Place the search term into the search rings. + (isearch-update-ring isearch-string t) + (evil-push-search-history isearch-string forward) + ;; Use this search term for empty pattern "%s//replacement/" + ;; Append case sensitivity + (setq evil-ex-last-was-search nil + evil-ex-substitute-pattern `(,(concat isearch-string "\\C") + nil (0 0)))) + + (defun spacemacs/ensure-ahs-enabled-locally () + "Ensures ahs is enabled for the local buffer." + (unless + (bound-and-true-p ahs-mode-line) + (auto-highlight-symbol-mode) + )) + + (defun spacemacs/ahs-highlight-now-wrapper () + "Safe wrapper for ahs-highlight-now" + (eval '(progn + (spacemacs/ensure-ahs-enabled-locally) + (ahs-highlight-now)) nil)) + + (defun spacemacs/enter-ahs-forward () + "Go to the next occurrence of symbol under point with +`auto-highlight-symbol'" + (interactive) + (setq spacemacs--ahs-searching-forward t) + (spacemacs/quick-ahs-forward)) + + (defun spacemacs/enter-ahs-backward () + "Go to the previous occurrence of symbol under point with +`auto-highlight-symbol'" + (interactive) + (setq spacemacs--ahs-searching-forward nil) + (spacemacs/quick-ahs-forward)) + + (defun spacemacs/quick-ahs-forward () + "Go to the next occurrence of symbol under point with +`auto-highlight-symbol'" + (interactive) + (spacemacs//quick-ahs-move t)) + + (defun spacemacs/quick-ahs-backward () + "Go to the previous occurrence of symbol under point with +`auto-highlight-symbol'" + (interactive) + (spacemacs//quick-ahs-move nil)) + + (defun spacemacs//quick-ahs-move (forward) + "Go to the next occurrence of symbol under point with +`auto-highlight-symbol'" + + (if (eq forward spacemacs--ahs-searching-forward) + (progn + (spacemacs/integrate-evil-search t) + (spacemacs/ahs-highlight-now-wrapper) + (evil-set-jump) + (spacemacs/symbol-highlight-transient-state/body) + (ahs-forward)) + (progn + (spacemacs/integrate-evil-search nil) + (spacemacs/ahs-highlight-now-wrapper) + (evil-set-jump) + (spacemacs/symbol-highlight-transient-state/body) + (ahs-backward)))) + + (with-eval-after-load 'evil + (define-key evil-motion-state-map (kbd "*") + 'spacemacs/enter-ahs-forward) + (define-key evil-motion-state-map (kbd "#") + 'spacemacs/enter-ahs-backward)) + + (defun spacemacs/symbol-highlight () + "Highlight the symbol under point with `auto-highlight-symbol'." + (interactive) + (spacemacs/ahs-highlight-now-wrapper) + (setq spacemacs-last-ahs-highlight-p (ahs-highlight-p)) + (spacemacs/symbol-highlight-transient-state/body) + (spacemacs/integrate-evil-search nil)) + + (defun spacemacs//ahs-ms-on-exit () + ;; Restore user search direction state as ahs has exitted in a state + ;; good for , but not for 'n' and 'N'" + (setq isearch-forward spacemacs--ahs-searching-forward)) + + (defun spacemacs/symbol-highlight-reset-range () + "Reset the range for `auto-highlight-symbol'." + (interactive) + (ahs-change-range ahs-default-range)) + + (spacemacs/set-leader-keys + "sh" 'spacemacs/symbol-highlight + "sH" 'spacemacs/goto-last-searched-ahs-symbol) + + ;; micro-state to easily jump from a highlighted symbol to the others + (dolist (sym '(ahs-forward + ahs-forward-definition + ahs-backward + ahs-backward-definition + ahs-back-to-start + ahs-change-range)) + (let* ((advice (intern (format "spacemacs/%s" (symbol-name sym))))) + (eval `(defadvice ,sym (around ,advice activate) + (spacemacs/ahs-highlight-now-wrapper) + ad-do-it + (spacemacs/ahs-highlight-now-wrapper) + (setq spacemacs-last-ahs-highlight-p (ahs-highlight-p)))))) + + (defun symbol-highlight-doc () + (let* ((i 0) + (overlay-count (length ahs-overlay-list)) + (overlay (format "%s" (nth i ahs-overlay-list))) + (current-overlay (format "%s" ahs-current-overlay)) + (st (ahs-stat)) + (plighter (ahs-current-plugin-prop 'lighter)) + (plugin (format "%s" + (cond ((string= plighter "HS") "Display") + ((string= plighter "HSA") "Buffer") + ((string= plighter "HSD") "Function")))) + (face (cond ((string= plighter "HS") ahs-plugin-defalt-face) + ((string= plighter "HSA") ahs-plugin-whole-buffer-face) + ((string= plighter "HSD") ahs-plugin-bod-face)))) + (while (not (string= overlay current-overlay)) + (setq i (1+ i)) + (setq overlay (format "%s" (nth i ahs-overlay-list)))) + (let* ((x/y (format "[%s/%s]" (- overlay-count i) overlay-count)) + (hidden (if (< 0 (- overlay-count (nth 4 st))) "*" ""))) + (concat + (propertize (format " %s " plugin) 'face face) + (propertize (format " %s%s " x/y hidden) 'face + `(:foreground "#ffffff" :background "#000000")))))) + + (defun ahs-to-iedit () + (interactive) + (cond + ((and (not (eq dotspacemacs-editing-style 'emacs)) + (configuration-layer/package-usedp 'evil-iedit-state)) + (evil-iedit-state/iedit-mode) + (iedit-restrict-region (ahs-current-plugin-prop 'start) + (ahs-current-plugin-prop 'end))) + ((and (eq dotspacemacs-editing-style 'emacs) + (configuration-layer/package-usedp 'iedit)) + (iedit-mode) + (iedit-restrict-region (ahs-current-plugin-prop 'start) + (ahs-current-plugin-prop 'end))) + (t (ahs-edit-mode t)))) + ;; transient state + (defun spacemacs//symbol-highlight-ts-doc () + (spacemacs//transient-state-make-doc + 'symbol-highlight + (format spacemacs--symbol-highlight-transient-state-doc + (symbol-highlight-doc) + (make-string (length (symbol-highlight-doc)) 32)))) + (spacemacs|define-transient-state symbol-highlight + :title "Symbol Highlight Transient State" + :dynamic-hint (spacemacs//symbol-highlight-ts-doc) + :before-exit (spacemacs//ahs-ms-on-exit) + :bindings + ("d" ahs-forward-definition) + ("D" ahs-backward-definition) + ("e" ahs-to-iedit :exit t) + ("n" spacemacs/quick-ahs-forward) + ("N" spacemacs/quick-ahs-backward) + ("p" spacemacs/quick-ahs-backward) + ("R" ahs-back-to-start) + ("r" ahs-change-range) + ("q" nil :exit t))))) + +(defun spacemacs-editing-visual/init-column-enforce-mode () + (use-package column-enforce-mode + :commands (column-enforce-mode global-column-enforce-mode) + :init + (progn + (spacemacs|add-toggle highlight-long-lines + :status column-enforce-mode + :prefix columns + :on (column-enforce-n (or columns column-enforce-column)) + :on-message (format "long-lines enabled for %s columns." (or columns column-enforce-column)) + :off (column-enforce-mode -1) + :documentation "Highlight the characters past the 80th column." + :evil-leader "t8") + (spacemacs|add-toggle highlight-long-lines-globally + :mode global-column-enforce-mode + :documentation "Globally Highlight the characters past the 80th column." + :evil-leader "t C-8")) + :config (spacemacs|diminish column-enforce-mode "⑧" "8"))) + +(defun spacemacs-editing-visual/init-hide-comnt () + (use-package hide-comnt + :commands hide/show-comments-toggle + :init (spacemacs/set-leader-keys "ch" 'hide/show-comments-toggle))) + +(defun spacemacs-editing-visual/init-highlight-indentation () + (use-package highlight-indentation + :defer t + :init + (progn + (spacemacs|add-toggle highlight-indentation + :mode highlight-indentation-mode + :documentation "Highlight indentation levels." + :evil-leader "thi") + (spacemacs|add-toggle highlight-indentation-current-column + :mode highlight-indentation-current-column-mode + :documentation "Highlight indentation level at point." + :evil-leader "thc")) + :config + (progn + (spacemacs|diminish highlight-indentation-mode " ⓗi" " hi") + (spacemacs|diminish highlight-indentation-current-column-mode " ⓗc" " hc")))) + +(defun spacemacs-editing-visual/init-highlight-numbers () + (use-package highlight-numbers + :defer t + :init + (progn + (add-hook 'prog-mode-hook 'highlight-numbers-mode) + (add-hook 'asm-mode-hook (lambda () (highlight-numbers-mode -1)))))) + +(defun spacemacs-editing-visual/init-highlight-parentheses () + (use-package highlight-parentheses + :defer t + :init + (progn + (when (member dotspacemacs-highlight-delimiters '(all current)) + (add-hook 'prog-mode-hook #'highlight-parentheses-mode)) + (setq hl-paren-delay 0.2) + (spacemacs/set-leader-keys "tCp" 'highlight-parentheses-mode) + (setq hl-paren-colors '("Springgreen3" + "IndianRed1" + "IndianRed3" + "IndianRed4"))) + :config + (spacemacs|hide-lighter highlight-parentheses-mode) + (set-face-attribute 'hl-paren-face nil :weight 'ultra-bold))) + +(defun spacemacs-editing-visual/init-hl-anything () + (use-package hl-anything + :init + (progn + (hl-highlight-mode) + (setq-default hl-highlight-save-file + (concat spacemacs-cache-directory ".hl-save")) + (spacemacs/set-leader-keys + "hc" 'hl-unhighlight-all-local + "hC" 'hl-unhighlight-all-global + "hh" 'hl-highlight-thingatpt-local + "hH" 'hl-highlight-thingatpt-global + "hn" 'hl-find-next-thing + "hN" 'hl-find-prev-thing + "hr" 'hl-restore-highlights + "hs" 'hl-save-highlights)) + :config (spacemacs|hide-lighter hl-highlight-mode))) + +(defun spacemacs-editing-visual/init-indent-guide () + (use-package indent-guide + :defer t + :init + (progn + (setq indent-guide-delay 0.3) + (spacemacs|add-toggle indent-guide + :mode indent-guide-mode + :documentation + "Highlight indentation level at point. (alternative to highlight-indentation)." + :evil-leader "ti") + (spacemacs|add-toggle indent-guide-globally + :mode indent-guide-global-mode + :documentation + "Highlight indentation level at point globally. (alternative to highlight-indentation)." + :evil-leader "t TAB")) + :config + (spacemacs|diminish indent-guide-mode " ⓘ" " i"))) + +(defun spacemacs-editing-visual/init-rainbow-delimiters () + (use-package rainbow-delimiters + :defer t + :init + (progn + (spacemacs/set-leader-keys "tCd" 'rainbow-delimiters-mode) + (when (member dotspacemacs-highlight-delimiters '(any all)) + (spacemacs/add-to-hooks 'rainbow-delimiters-mode '(prog-mode-hook)))))) + +(defun spacemacs-editing-visual/init-volatile-highlights () + (use-package volatile-highlights + :config + (progn + ;; additional extensions + ;; evil + (vhl/define-extension 'evil + 'evil-move + 'evil-paste-after + 'evil-paste-before + 'evil-paste-pop) + (with-eval-after-load 'evil + (vhl/install-extension 'evil) + (vhl/load-extension 'evil)) + ;; undo-tree + (vhl/define-extension 'undo-tree + 'undo-tree-move + 'undo-tree-yank) + (with-eval-after-load 'undo-tree + (vhl/install-extension 'undo-tree) + (vhl/load-extension 'undo-tree)) + (volatile-highlights-mode) + (spacemacs|hide-lighter volatile-highlights-mode)))) diff --git a/layers/+spacemacs/spacemacs-editing/funcs.el b/layers/+spacemacs/spacemacs-editing/funcs.el new file mode 100644 index 0000000..dc4a806 --- /dev/null +++ b/layers/+spacemacs/spacemacs-editing/funcs.el @@ -0,0 +1,71 @@ +;;; funcs.el --- Spacemacs editing Layer functions File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + +;; smartparens + +(defun spacemacs/smartparens-pair-newline (id action context) + (save-excursion + (newline) + (indent-according-to-mode))) + +(defun spacemacs/smartparens-pair-newline-and-indent (id action context) + (spacemacs/smartparens-pair-newline id action context) + (indent-according-to-mode)) + +(defun spacemacs/smart-closing-parenthesis () + (interactive) + (let* ((sp-navigate-close-if-unbalanced t) + (current-pos (point)) + (current-line (line-number-at-pos current-pos)) + (next-pos (save-excursion + (sp-up-sexp) + (point))) + (next-line (line-number-at-pos next-pos))) + (cond + ((and (= current-line next-line) + (not (= current-pos next-pos))) + (sp-up-sexp)) + (t + (insert-char ?\)))))) + +(defun spacemacs//conditionally-enable-smartparens-mode () + "Enable `smartparens-mode' in the minibuffer, during `eval-expression'." + (if (eq this-command 'eval-expression) + (smartparens-mode))) + +(defun spacemacs//adaptive-smartparent-pair-overlay-face () + (set-face-attribute 'sp-pair-overlay-face nil + :inherit 'lazy-highlight + :background nil + :foreground nil)) + + +;; uuidgen +;; TODO spacemacs/uuidgen-3 and spacemacs/uuidgen-5 + +(defun spacemacs/uuidgen-1 (arg) + "Return a time based UUID (UUIDv1). + If ARG is non nil then use CID format." + (interactive "P") + (let ((uuid (uuidgen-1))) + (if arg + (insert-uuid-cid uuid) + (insert uuid)))) + +(defun spacemacs/uuidgen-4 (arg) + "Return an UUID from random numbers (UUIDv4). + If ARG is non nil then use CID format." + (interactive "P") + (let ((uuid (uuidgen-4))) + (if arg + (insert-uuid-cid uuid) + (insert uuid)))) diff --git a/layers/+spacemacs/spacemacs-editing/local/spacemacs-whitespace-cleanup/spacemacs-whitespace-cleanup.el b/layers/+spacemacs/spacemacs-editing/local/spacemacs-whitespace-cleanup/spacemacs-whitespace-cleanup.el new file mode 100644 index 0000000..7e3b7d1 --- /dev/null +++ b/layers/+spacemacs/spacemacs-editing/local/spacemacs-whitespace-cleanup/spacemacs-whitespace-cleanup.el @@ -0,0 +1,91 @@ +;;; spacemacs-whitespace-cleanup.el --- Cleanup whitspace automatically. + +;; Author: Sylvain Benner +;; Keywords: editing, whitespace, spacemacs +;; Version: 0.1 + +;; This file 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, or (at your option) +;; any later version. + +;; This file 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., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: +;; This package adds a minor mode to automatically cleanup whitespace. +;; It requires Spacemacs and depends on the value of the variable +;; `dotspacemacs-whitespace-cleanup' (see documentation in dotfile). + +;;; Code: + +(defvar spacemacs-whitespace-cleanup-globally nil + "If non nil then `spacemacs-whitespace-cleanup-mode' is applied globally.") + +;;;###autoload +(define-minor-mode spacemacs-whitespace-cleanup-mode + "Minor mode to clean whitespace. + +The minor mode is based on the value of the dotfile variable + `dotspacemacs-whitespace-cleanup' to determine the behavior +of the cleanup." + :lighter " CleanW" + :group 'spacemacs + (if spacemacs-whitespace-cleanup-mode + (spacemacs-whitespace-cleanup//turn-on + spacemacs-whitespace-cleanup-globally) + (spacemacs-whitespace-cleanup//turn-off + spacemacs-whitespace-cleanup-globally))) + +(define-global-minor-mode global-spacemacs-whitespace-cleanup-mode + spacemacs-whitespace-cleanup-mode + (lambda () + (let ((spacemacs-whitespace-cleanup-globally t)) + (spacemacs-whitespace-cleanup-mode))) + :group 'spacemacs + :require 'spacemacs-whitespace-cleanup-mode) + +(defun spacemacs-whitespace-cleanup/on-message (&optional global) + "Return a string to display when the mode is activated." + (pcase dotspacemacs-whitespace-cleanup + (`all + (format "whitespace-cleanup enabled%s (all whitespace)" + (if global " globally" ""))) + (`trailing + (format "whitespace-cleanup enabled%s (trailing whitespace)" + (if global " globally" ""))) + (`changed + (format "whitespace-cleanup enabled%s (changed lines)" + (if global " globally" ""))))) + +(defun spacemacs-whitespace-cleanup//turn-on (&optional global) + "Turn on `spacemacs-whitespace-cleanup-mode'." + (pcase dotspacemacs-whitespace-cleanup + (`all + (add-hook 'before-save-hook 'whitespace-cleanup nil (not global))) + (`trailing + (add-hook 'before-save-hook 'delete-trailing-whitespace nil (not global))) + (`changed + (when (fboundp 'ws-butler-mode) + (if global (ws-butler-global-mode) (ws-butler-mode)))))) + +(defun spacemacs-whitespace-cleanup//turn-off (&optional global) + "Turn off `spacemacs-whitespace-cleanup-mode'." + (pcase dotspacemacs-whitespace-cleanup + (`all + (remove-hook 'before-save-hook 'whitespace-cleanup (not global))) + (`trailing + (remove-hook 'before-save-hook 'delete-trailing-whitespace (not global))) + (`changed + (when (fboundp 'ws-butler-mode) + (if global (ws-butler-global-mode -1) (ws-butler-mode -1)))))) + +(provide 'spacemacs-whitespace-cleanup) +;;; spacemacs-whitespace-cleanup.el ends here. diff --git a/layers/+spacemacs/spacemacs-editing/packages.el b/layers/+spacemacs/spacemacs-editing/packages.el new file mode 100644 index 0000000..4907c15 --- /dev/null +++ b/layers/+spacemacs/spacemacs-editing/packages.el @@ -0,0 +1,359 @@ +;;; packages.el --- Spacemacs Editing Layer packages File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq spacemacs-editing-packages + '(aggressive-indent + avy + (bracketed-paste :toggle (version<= emacs-version "25.0.92")) + clean-aindent-mode + eval-sexp-fu + expand-region + (hexl :location built-in) + hungry-delete + link-hint + lorem-ipsum + move-text + (origami :toggle (eq 'origami dotspacemacs-folding-method)) + smartparens + (spacemacs-whitespace-cleanup :location local) + undo-tree + uuidgen + ws-butler)) + +;; Initialization of packages + +(defun spacemacs-editing/init-aggressive-indent () + (use-package aggressive-indent + :defer t + :init + (progn + (spacemacs|add-toggle aggressive-indent + :mode aggressive-indent-mode + :documentation "Always keep code indented." + :evil-leader "tI") + (spacemacs|add-toggle aggressive-indent-globally + :mode aggressive-indent-mode + :documentation "Always keep code indented globally." + :evil-leader "t C-I")) + :config + (progn + (add-hook 'diff-auto-refine-mode-hook 'spacemacs/toggle-aggressive-indent-off) + (spacemacs|diminish aggressive-indent-mode " Ⓘ" " I")))) + +(defun spacemacs-editing/init-avy () + (use-package avy + :defer t + :commands (spacemacs/avy-open-url spacemacs/avy-goto-url avy-pop-mark) + :init + (progn + (setq avy-all-windows 'all-frames) + (setq avy-background t) + (spacemacs/set-leader-keys + "jb" 'avy-pop-mark + "jj" 'evil-avy-goto-char + "jJ" 'evil-avy-goto-char-2 + "jl" 'evil-avy-goto-line + "ju" 'spacemacs/avy-goto-url + "jw" 'evil-avy-goto-word-or-subword-1 + "xo" 'spacemacs/avy-open-url)) + :config + (progn + (defun spacemacs/avy-goto-url() + "Use avy to go to an URL in the buffer." + (interactive) + (avy--generic-jump "https?://" nil 'pre)) + (defun spacemacs/avy-open-url () + "Use avy to select an URL in the buffer and open it." + (interactive) + (save-excursion + (spacemacs/avy-goto-url) + (browse-url-at-point)))))) + +(defun spacemacs-editing/init-bracketed-paste () + (use-package bracketed-paste + :defer t + :init + ;; Enable bracketed-paste for tty + (add-hook 'tty-setup-hook 'bracketed-paste-enable))) + +(defun spacemacs-editing/init-clean-aindent-mode () + (use-package clean-aindent-mode + :config (clean-aindent-mode))) + +(defun spacemacs-editing/init-eval-sexp-fu () + ;; ignore obsolete function warning generated on startup + (let ((byte-compile-not-obsolete-funcs (append byte-compile-not-obsolete-funcs '(preceding-sexp)))) + (require 'eval-sexp-fu))) + +(defun spacemacs-editing/init-expand-region () + (use-package expand-region + :defer t + :init (spacemacs/set-leader-keys "v" 'er/expand-region) + :config + (progn + ;; add search capability to expand-region + (when (configuration-layer/package-usedp 'helm-ag) + (defadvice er/prepare-for-more-expansions-internal + (around helm-ag/prepare-for-more-expansions-internal activate) + ad-do-it + (let ((new-msg (concat (car ad-return-value) + ", / to search in project, " + "f to search in files, " + "b to search in opened buffers")) + (new-bindings (cdr ad-return-value))) + (cl-pushnew + '("/" (lambda () + (call-interactively + 'spacemacs/helm-project-smart-do-search-region-or-symbol))) + new-bindings) + (cl-pushnew + '("f" (lambda () + (call-interactively + 'spacemacs/helm-files-smart-do-search-region-or-symbol))) + new-bindings) + (cl-pushnew + '("b" (lambda () + (call-interactively + 'spacemacs/helm-buffers-smart-do-search-region-or-symbol))) + new-bindings) + (setq ad-return-value (cons new-msg new-bindings))))) + (setq expand-region-contract-fast-key "V" + expand-region-reset-fast-key "r")))) + +(defun spacemacs-editing/init-hexl () + (use-package hexl + :defer t + :init + (progn + (spacemacs/set-leader-keys "fh" 'hexl-find-file) + (spacemacs/set-leader-keys-for-major-mode 'hexl-mode + "d" 'hexl-insert-decimal-char + "c" 'hexl-insert-octal-char + "x" 'hexl-insert-hex-char + "X" 'hexl-insert-hex-string + "g" 'hexl-goto-address) + (evil-define-key 'motion hexl-mode-map + "]]" 'hexl-end-of-1k-page + "[[" 'hexl-beginning-of-1k-page + "h" 'hexl-backward-char + "l" 'hexl-forward-char + "j" 'hexl-next-line + "k" 'hexl-previous-line + "$" 'hexl-end-of-line + "^" 'hexl-beginning-of-line + "0" 'hexl-beginning-of-line)))) + +(defun spacemacs-editing/init-hungry-delete () + (use-package hungry-delete + :defer t + :init + (spacemacs|add-toggle hungry-delete + :mode hungry-delete-mode + :documentation "Delete consecutive horizontal whitespace with a single key." + :evil-leader "td") + :config + (progn + (setq-default hungry-delete-chars-to-skip " \t\f\v") ; only horizontal whitespace + (define-key hungry-delete-mode-map (kbd "DEL") 'hungry-delete-backward) + (define-key hungry-delete-mode-map (kbd "S-DEL") 'delete-backward-char)))) + +(defun spacemacs-editing/init-link-hint () + (use-package link-hint + :defer t + :init + (spacemacs/set-leader-keys + "xo" 'link-hint-open-link + "xO" 'link-hint-open-multiple-links))) + +(defun spacemacs-editing/init-lorem-ipsum () + (use-package lorem-ipsum + :commands (lorem-ipsum-insert-list + lorem-ipsum-insert-paragraphs + lorem-ipsum-insert-sentences) + :init + (progn + (spacemacs/declare-prefix "il" "lorem ipsum") + (spacemacs/set-leader-keys + "ill" 'lorem-ipsum-insert-list + "ilp" 'lorem-ipsum-insert-paragraphs + "ils" 'lorem-ipsum-insert-sentences)))) + +(defun spacemacs-editing/init-move-text () + (use-package move-text + :defer t + :init + (spacemacs|define-transient-state move-text + :title "Move Text Transient State" + :bindings + ("J" move-text-down "move down") + ("K" move-text-up "move up")) + (spacemacs/set-leader-keys + "xJ" 'spacemacs/move-text-transient-state/move-text-down + "xK" 'spacemacs/move-text-transient-state/move-text-up))) + +(defun spacemacs-editing/init-origami () + (use-package origami + :defer t + :init + (progn + (global-origami-mode) + (define-key evil-normal-state-map "za" 'origami-forward-toggle-node) + (define-key evil-normal-state-map "zc" 'origami-close-node) + (define-key evil-normal-state-map "zC" 'origami-close-node-recursively) + (define-key evil-normal-state-map "zO" 'origami-open-node-recursively) + (define-key evil-normal-state-map "zo" 'origami-open-node) + (define-key evil-normal-state-map "zr" 'origami-open-all-nodes) + (define-key evil-normal-state-map "zm" 'origami-close-all-nodes) + (define-key evil-normal-state-map "zs" 'origami-show-only-node) + (define-key evil-normal-state-map "zn" 'origami-next-fold) + (define-key evil-normal-state-map "zp" 'origami-previous-fold) + (define-key evil-normal-state-map "zR" 'origami-reset) + (define-key evil-normal-state-map (kbd "z ") 'origami-recursively-toggle-node) + (define-key evil-normal-state-map (kbd "z TAB") 'origami-recursively-toggle-node) + + (spacemacs|define-transient-state fold + :title "Code Fold Transient State" + :doc " + Close^^ Open^^ Toggle^^ Goto^^ Other^^ + ───────^^───────── ─────^^─────────── ─────^^───────── ──────^^────── ─────^^───────── + [_c_] at point [_o_] at point [_a_] at point [_n_] next [_s_] single out + [_C_] recursively [_O_] recursively [_A_] all [_p_] previous [_R_] reset + [_m_] all [_r_] all [_TAB_] like org ^^ [_q_] quit" + :foreign-keys run + :on-enter (unless (bound-and-true-p origami-mode) (origami-mode 1)) + :bindings + ("a" origami-forward-toggle-node) + ("A" origami-toggle-all-nodes) + ("c" origami-close-node) + ("C" origami-close-node-recursively) + ("o" origami-open-node) + ("O" origami-open-node-recursively) + ("r" origami-open-all-nodes) + ("m" origami-close-all-nodes) + ("n" origami-next-fold) + ("p" origami-previous-fold) + ("s" origami-show-only-node) + ("R" origami-reset) + ("TAB" origami-recursively-toggle-node) + ("" origami-recursively-toggle-node) + ("q" nil :exit t) + ("C-g" nil :exit t) + ("" nil :exit t)) + ;; Note: The key binding for the fold transient state is defined in + ;; evil config + ))) + +(defun spacemacs-editing/init-smartparens () + (use-package smartparens + :defer t + :commands (sp-split-sexp sp-newline sp-up-sexp) + :init + (progn + ;; settings + (setq sp-show-pair-delay 0.2 + ;; fix paren highlighting in normal mode + sp-show-pair-from-inside t + sp-cancel-autoskip-on-backward-movement nil + sp-highlight-pair-overlay nil + sp-highlight-wrap-overlay nil + sp-highlight-wrap-tag-overlay nil) + (spacemacs/add-to-hooks (if dotspacemacs-smartparens-strict-mode + 'smartparens-strict-mode + 'smartparens-mode) + '(prog-mode-hook comint-mode-hook)) + ;; enable smartparens-mode in `eval-expression' + (add-hook 'minibuffer-setup-hook 'spacemacs//conditionally-enable-smartparens-mode) + ;; toggles + (spacemacs|add-toggle smartparens + :mode smartparens-mode + :documentation "Enable smartparens." + :evil-leader "tp") + (spacemacs|add-toggle smartparens-globally + :mode smartparens-mode + :documentation "Enable smartparens globally." + :evil-leader "t C-p") + ;; key bindings + (spacemacs/set-leader-keys + "js" 'sp-split-sexp + "jn" 'sp-newline)) + :config + (progn + (require 'smartparens-config) + (spacemacs|diminish smartparens-mode " ⓟ" " p") + (spacemacs//adaptive-smartparent-pair-overlay-face) + (add-hook 'spacemacs-post-theme-change-hook + 'spacemacs//adaptive-smartparent-pair-overlay-face) + (show-smartparens-global-mode +1) + ;; don't create a pair with single quote in minibuffer + (sp-local-pair 'minibuffer-inactive-mode "'" nil :actions nil) + (sp-pair "{" nil :post-handlers + '(:add (spacemacs/smartparens-pair-newline-and-indent "RET"))) + (sp-pair "[" nil :post-handlers + '(:add (spacemacs/smartparens-pair-newline-and-indent "RET"))) + (when dotspacemacs-smart-closing-parenthesis + (define-key evil-insert-state-map ")" + 'spacemacs/smart-closing-parenthesis))))) + +(defun spacemacs-editing/init-spacemacs-whitespace-cleanup () + (use-package spacemacs-whitespace-cleanup + :commands (spacemacs-whitespace-cleanup-mode + global-spacemacs-whitespace-cleanup-mode) + :init + (progn + (spacemacs|add-toggle whitespace-cleanup + :mode spacemacs-whitespace-cleanup-mode + :documentation "Automatic whitespace clean up." + :on-message (spacemacs-whitespace-cleanup/on-message) + :evil-leader "tW") + (spacemacs|add-toggle global-whitespace-cleanup + :mode global-spacemacs-whitespace-cleanup-mode + :status spacemacs-whitespace-cleanup-mode + :on (let ((spacemacs-whitespace-cleanup-globally t)) + (spacemacs-whitespace-cleanup-mode)) + :off (let ((spacemacs-whitespace-cleanup-globally t)) + (spacemacs-whitespace-cleanup-mode -1)) + :on-message (spacemacs-whitespace-cleanup/on-message t) + :documentation "Global automatic whitespace clean up." + :evil-leader "t C-S-w") + (with-eval-after-load 'ws-butler + (when dotspacemacs-whitespace-cleanup + (spacemacs/toggle-global-whitespace-cleanup-on)))) + :config + (progn + (spacemacs|diminish spacemacs-whitespace-cleanup-mode " Ⓦ" " W") + (spacemacs|diminish global-spacemacs-whitespace-cleanup-mode + " Ⓦ" " W")))) + +(defun spacemacs-editing/init-undo-tree () + (use-package undo-tree + :init + (global-undo-tree-mode) + (setq undo-tree-visualizer-timestamps t) + (setq undo-tree-visualizer-diff t) + :config + (spacemacs|hide-lighter undo-tree-mode))) + +(defun spacemacs-editing/init-uuidgen () + (use-package uuidgen + :commands (uuidgen-1 uuidgen-4) + :init + (progn + (spacemacs/declare-prefix "iU" "uuid") + (spacemacs/set-leader-keys + "iU1" 'spacemacs/uuidgen-1 + "iU4" 'spacemacs/uuidgen-4 + "iUU" 'spacemacs/uuidgen-4)))) + +(defun spacemacs-editing/init-ws-butler () + ;; not deferred on purpose, init-spacemacs-whitespace-cleanup need + ;; it to be loaded. + (use-package ws-butler + :config (spacemacs|hide-lighter ws-butler-mode))) diff --git a/layers/+spacemacs/spacemacs-evil/funcs.el b/layers/+spacemacs/spacemacs-evil/funcs.el new file mode 100644 index 0000000..78f0235 --- /dev/null +++ b/layers/+spacemacs/spacemacs-evil/funcs.el @@ -0,0 +1,76 @@ +;;; funcs.el --- Spacemacs Evil Layer functions File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar spacemacs--evil-iedit-insert-states-default nil + "Default value of the list of additional states enabled in \ +`evil-iedit-insert-state'.") + +(defvar spacemacs--evil-iedit-insert-states-hybrid nil + "List of additional states enabled in `evil-iedit-insert-state' when +`hybrid-mode' is active.") + +(defun spacemacs//enable-hs-minor-mode () + "Enable hs-minor-mode for code folding." + (ignore-errors + (hs-minor-mode) + (spacemacs|hide-lighter hs-minor-mode))) + +(defun spacemacs//iedit-insert-state-hybrid (style) + "If STYLE is hybrid, update `evil-iedit-insert-state' definition to enable +`evil-hybrid-state' instead of `evil-insert-state'. +Otherwise, revert to the default behavior (i.e. enable `evil-insert-state')." + ;; Populate variables on the first invocation. + (unless spacemacs--evil-iedit-insert-states-default + (setq spacemacs--evil-iedit-insert-states-default + (evil-get-property evil-state-properties 'iedit-insert :enable)) + (setq spacemacs--evil-iedit-insert-states-hybrid + (mapcar (lambda (item) + (if (eq item 'insert) 'hybrid item)) + spacemacs--evil-iedit-insert-states-default))) + (let ((states (if (eq style 'hybrid) + spacemacs--evil-iedit-insert-states-hybrid + spacemacs--evil-iedit-insert-states-default))) + (evil-put-property 'evil-state-properties 'iedit-insert + :enable states))) + + +;; evil-search-highlight-persist + +(defun spacemacs/evil-search-clear-highlight () + "Clear evil-search or evil-ex-search persistent highlights." + (interactive) + (case evil-search-module + ('isearch (evil-search-highlight-persist-remove-all)) + ('evil-search (evil-ex-nohighlight)))) + +(defun spacemacs//adaptive-evil-highlight-persist-face () + (set-face-attribute 'evil-search-highlight-persist-highlight-face nil + :inherit 'lazy-highlight + :background nil + :foreground nil)) + +(defun spacemacs/linum-relative-toggle () + (interactive) + (if (not (bound-and-true-p linum-relative-mode)) + (linum-mode)) + (linum-relative-toggle)) + + +;; vi-tilde-fringe + +(defun spacemacs/disable-vi-tilde-fringe () + "Disable `vi-tilde-fringe' in the current buffer." + (vi-tilde-fringe-mode -1)) + +(defun spacemacs/disable-vi-tilde-fringe-read-only () + "Disable `vi-tilde-fringe' in the current buffer if it is read only." + (when buffer-read-only + (spacemacs/disable-vi-tilde-fringe))) diff --git a/layers/+spacemacs/spacemacs-evil/local/evil-unimpaired/evil-unimpaired.el b/layers/+spacemacs/spacemacs-evil/local/evil-unimpaired/evil-unimpaired.el new file mode 100644 index 0000000..d58dee6 --- /dev/null +++ b/layers/+spacemacs/spacemacs-evil/local/evil-unimpaired/evil-unimpaired.el @@ -0,0 +1,111 @@ +;;; evil-unimpaired.el --- Pairs of handy bracket mappings. + +;; Author: Sylvain Benner +;; Keywords: evil, vim-unimpaired, spacemacs +;; Version: 0.1 +;; Package-Requires: ((dash "2.12.0") (f "0.18.0")) + +;; This file 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, or (at your option) +;; any later version. + +;; This file 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., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; This is a port of vim-unimpaired https://github.com/tpope/vim-unimpaired +;; `evil-unimpaired' provides pairs of handy bracket mappings to quickly navigate +;; to previous/next thing and more. + +;;; Code: + +(require 'dash) +(require 'f) + +(defun evil-unimpaired//find-relative-filename (offset) + (when buffer-file-name + (let* ((directory (f-dirname buffer-file-name)) + (files (f--files directory (not (s-matches? "^\\.?#" it)))) + (index (+ (-elem-index buffer-file-name files) offset)) + (file (and (>= index 0) (nth index files)))) + (when file + (f-expand file directory))))) + +(defun evil-unimpaired/previous-file () + (interactive) + (-if-let (filename (evil-unimpaired//find-relative-filename -1)) + (find-file filename) + (user-error "No previous file"))) + +(defun evil-unimpaired/next-file () + (interactive) + (-if-let (filename (evil-unimpaired//find-relative-filename 1)) + (find-file filename) + (user-error "No next file"))) + +(defun evil-unimpaired/paste-above () + (interactive) + (evil-insert-newline-above) + (evil-paste-after 1)) + +(defun evil-unimpaired/paste-below () + (interactive) + (evil-insert-newline-below) + (evil-paste-after 1)) + +(defun evil-unimpaired/insert-space-above (count) + (interactive "p") + (dotimes (_ count) (save-excursion (evil-insert-newline-above)))) + +(defun evil-unimpaired/insert-space-below (count) + (interactive "p") + (dotimes (_ count) (save-excursion (evil-insert-newline-below)))) + +(defun evil-unimpaired/next-frame () + (interactive) + (raise-frame (next-frame))) + +(defun evil-unimpaired/previous-frame () + (interactive) + (raise-frame (previous-frame))) + +;; from tpope's unimpaired +(define-key evil-normal-state-map (kbd "[ SPC") + 'evil-unimpaired/insert-space-above) +(define-key evil-normal-state-map (kbd "] SPC") + 'evil-unimpaired/insert-space-below) +(define-key evil-normal-state-map (kbd "[ e") 'move-text-up) +(define-key evil-normal-state-map (kbd "] e") 'move-text-down) +(define-key evil-visual-state-map (kbd "[ e") ":move'<--1") +(define-key evil-visual-state-map (kbd "] e") ":move'>+1") +;; (define-key evil-visual-state-map (kbd "[ e") 'move-text-up) +;; (define-key evil-visual-state-map (kbd "] e") 'move-text-down) +(define-key evil-normal-state-map (kbd "[ b") 'previous-buffer) +(define-key evil-normal-state-map (kbd "] b") 'next-buffer) +(define-key evil-normal-state-map (kbd "[ f") 'evil-unimpaired/previous-file) +(define-key evil-normal-state-map (kbd "] f") 'evil-unimpaired/next-file) +(define-key evil-normal-state-map (kbd "] l") 'spacemacs/next-error) +(define-key evil-normal-state-map (kbd "[ l") 'spacemacs/previous-error) +(define-key evil-normal-state-map (kbd "] q") 'spacemacs/next-error) +(define-key evil-normal-state-map (kbd "[ q") 'spacemacs/previous-error) +(define-key evil-normal-state-map (kbd "[ t") 'evil-unimpaired/previous-frame) +(define-key evil-normal-state-map (kbd "] t") 'evil-unimpaired/next-frame) +(define-key evil-normal-state-map (kbd "[ w") 'previous-multiframe-window) +(define-key evil-normal-state-map (kbd "] w") 'next-multiframe-window) +;; select pasted text +(define-key evil-normal-state-map (kbd "g p") (kbd "` [ v ` ]")) +;; paste above or below with newline +(define-key evil-normal-state-map (kbd "[ p") 'evil-unimpaired/paste-above) +(define-key evil-normal-state-map (kbd "] p") 'evil-unimpaired/paste-below) + +(provide 'evil-unimpaired) +;;; evil-unimpaired.el ends here. diff --git a/layers/+spacemacs/spacemacs-evil/packages.el b/layers/+spacemacs/spacemacs-evil/packages.el new file mode 100644 index 0000000..19a4c15 --- /dev/null +++ b/layers/+spacemacs/spacemacs-evil/packages.el @@ -0,0 +1,291 @@ +;;; packages.el --- Spacemacs Evil Layer packages File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq spacemacs-evil-packages + '(evil-anzu + evil-args + evil-ediff + evil-exchange + evil-iedit-state + evil-indent-plus + evil-lisp-state + ;; for testing purpose, contribute by reporting bugs and sending PRs + ;; to https://github.com/gabesoft/evil-mc + ;; To enable it add `(global-evil-mc-mode)' to user-config function + evil-mc + evil-nerd-commenter + evil-matchit + evil-numbers + evil-search-highlight-persist + evil-surround + ;; Temporarily disabled, pending the resolution of + ;; https://github.com/7696122/evil-terminal-cursor-changer/issues/8 + ;; evil-terminal-cursor-changer + evil-tutor + (evil-unimpaired :location (recipe :fetcher local)) + evil-visual-mark-mode + (hs-minor-mode :location built-in) + linum-relative + vi-tilde-fringe + )) + +(defun spacemacs-evil/init-evil-anzu () + (use-package evil-anzu + :init + (global-anzu-mode t) + :config + (progn + (spacemacs|hide-lighter anzu-mode) + (setq anzu-search-threshold 1000 + anzu-cons-mode-line-p nil) + ;; powerline integration + (when (configuration-layer/package-usedp 'spaceline) + (defun spacemacs/anzu-update-mode-line (here total) + "Custom update function which does not propertize the status." + (when anzu--state + (let ((status (cl-case anzu--state + (search (format "(%s/%d%s)" + (anzu--format-here-position here total) + total (if anzu--overflow-p "+" ""))) + (replace-query (format "(%d replace)" total)) + (replace (format "(%d/%d)" here total))))) + status))) + (setq anzu-mode-line-update-function 'spacemacs/anzu-update-mode-line))))) + +(defun spacemacs-evil/init-evil-args () + (use-package evil-args + :init + (progn + ;; bind evil-args text objects + (define-key evil-inner-text-objects-map "a" 'evil-inner-arg) + (define-key evil-outer-text-objects-map "a" 'evil-outer-arg)))) + +(defun spacemacs-evil/init-evil-ediff () + (use-package evil-ediff + :after (ediff) + :if (memq dotspacemacs-editing-style '(hybrid vim)))) + +(defun spacemacs-evil/init-evil-exchange () + (use-package evil-exchange + :init (evil-exchange-install))) + +(defun spacemacs-evil/init-evil-iedit-state () + (use-package evil-iedit-state + :commands (evil-iedit-state evil-iedit-state/iedit-mode) + :init + (progn + (setq iedit-current-symbol-default t + iedit-only-at-symbol-boundaries t + iedit-toggle-key-default nil) + (spacemacs/set-leader-keys "se" 'evil-iedit-state/iedit-mode)) + :config + ;; activate leader in iedit and iedit-insert states + (define-key evil-iedit-state-map + (kbd dotspacemacs-leader-key) spacemacs-default-map) + (spacemacs//iedit-insert-state-hybrid dotspacemacs-editing-style) + (add-hook 'spacemacs-editing-style-hook + #'spacemacs//iedit-insert-state-hybrid))) + +(defun spacemacs-evil/init-evil-indent-plus () + (use-package evil-indent-plus + :init (evil-indent-plus-default-bindings))) + +(defun spacemacs-evil/init-evil-lisp-state () + (use-package evil-lisp-state + :init (setq evil-lisp-state-global t) + :config (spacemacs/set-leader-keys "k" evil-lisp-state-map))) + +(defun spacemacs-evil/init-evil-mc () + (use-package evil-mc + :defer t + :init + ;; remove emc prefix when there is not multiple cursors + (setq evil-mc-mode-line + `(:eval (when (> (evil-mc-get-cursor-count) 1) + (format ,(propertize " %s:%d" 'face 'cursor) + evil-mc-mode-line-prefix + (evil-mc-get-cursor-count))))))) + +;; other commenting functions in funcs.el with keybinds in keybindings.el +(defun spacemacs-evil/init-evil-nerd-commenter () + (use-package evil-nerd-commenter + :commands evilnc-comment-operator + :init + (progn + ;; double all the commenting functions so that the inverse operations + ;; can be called without setting a flag + (defun spacemacs/comment-or-uncomment-lines-inverse (&optional arg) + (interactive "p") + (let ((evilnc-invert-comment-line-by-line t)) + (evilnc-comment-or-uncomment-lines arg))) + + (defun spacemacs/comment-or-uncomment-lines (&optional arg) + (interactive "p") + (let ((evilnc-invert-comment-line-by-line nil)) + (evilnc-comment-or-uncomment-lines arg))) + + (defun spacemacs/copy-and-comment-lines-inverse (&optional arg) + (interactive "p") + (let ((evilnc-invert-comment-line-by-line t)) + (evilnc-copy-and-comment-lines arg))) + + (defun spacemacs/copy-and-comment-lines (&optional arg) + (interactive "p") + (let ((evilnc-invert-comment-line-by-line nil)) + (evilnc-copy-and-comment-lines arg))) + + (defun spacemacs/quick-comment-or-uncomment-to-the-line-inverse + (&optional arg) + (interactive "p") + (let ((evilnc-invert-comment-line-by-line t)) + (evilnc-comment-or-uncomment-to-the-line arg))) + + (defun spacemacs/quick-comment-or-uncomment-to-the-line (&optional arg) + (interactive "p") + (let ((evilnc-invert-comment-line-by-line nil)) + (evilnc-comment-or-uncomment-to-the-line arg))) + + (defun spacemacs/comment-or-uncomment-paragraphs-inverse (&optional arg) + (interactive "p") + (let ((evilnc-invert-comment-line-by-line t)) + (evilnc-comment-or-uncomment-paragraphs arg))) + + (defun spacemacs/comment-or-uncomment-paragraphs (&optional arg) + (interactive "p") + (let ((evilnc-invert-comment-line-by-line nil)) + (evilnc-comment-or-uncomment-paragraphs arg))) + + (define-key evil-normal-state-map "gc" 'evilnc-comment-operator) + (define-key evil-normal-state-map "gy" 'spacemacs/copy-and-comment-lines) + + (spacemacs/set-leader-keys + ";" 'evilnc-comment-operator + "cl" 'spacemacs/comment-or-uncomment-lines + "cL" 'spacemacs/comment-or-uncomment-lines-inverse + "cp" 'spacemacs/comment-or-uncomment-paragraphs + "cP" 'spacemacs/comment-or-uncomment-paragraphs-inverse + "ct" 'spacemacs/quick-comment-or-uncomment-to-the-line + "cT" 'spacemacs/quick-comment-or-uncomment-to-the-line-inverse + "cy" 'spacemacs/copy-and-comment-lines + "cY" 'spacemacs/copy-and-comment-lines-inverse)))) + +(defun spacemacs-evil/init-evil-matchit () + (use-package evil-matchit + :defer t)) + +(defun spacemacs-evil/init-evil-numbers () + (use-package evil-numbers + :config + (progn + (spacemacs|define-transient-state evil-numbers + :title "Evil Numbers Transient State" + :doc "\n[_+_/_=_] increase number [_-_] decrease [0..9] prefix [_q_] quit" + :bindings + ("+" evil-numbers/inc-at-pt) + ("=" evil-numbers/inc-at-pt) + ("-" evil-numbers/dec-at-pt) + ("q" nil :exit t)) + (spacemacs/set-leader-keys + "n+" 'spacemacs/evil-numbers-transient-state/evil-numbers/inc-at-pt + "n=" 'spacemacs/evil-numbers-transient-state/evil-numbers/inc-at-pt + "n-" 'spacemacs/evil-numbers-transient-state/evil-numbers/dec-at-pt)))) + +(defun spacemacs-evil/init-evil-search-highlight-persist () + (use-package evil-search-highlight-persist + :init + (progn + (global-evil-search-highlight-persist) + ;; (set-face-attribute ) + (spacemacs/set-leader-keys "sc" 'spacemacs/evil-search-clear-highlight) + (define-key evil-search-highlight-persist-map (kbd "C-x SPC") 'rectangle-mark-mode) + (evil-ex-define-cmd "nohlsearch" + 'evil-search-highlight-persist-remove-all) + (spacemacs//adaptive-evil-highlight-persist-face) + (add-hook 'spacemacs-post-theme-change-hook 'spacemacs//adaptive-evil-highlight-persist-face)))) + +(defun spacemacs-evil/init-evil-surround () + (use-package evil-surround + :init + (progn + (global-evil-surround-mode 1) + ;; `s' for surround instead of `substitute' + ;; see motivation for this change in the documentation + (evil-define-key 'visual evil-surround-mode-map "s" 'evil-surround-region) + (evil-define-key 'visual evil-surround-mode-map "S" 'evil-substitute)))) + +(defun spacemacs-evil/init-evil-terminal-cursor-changer () + (use-package evil-terminal-cursor-changer + :if (not (display-graphic-p)) + :init (setq evil-visual-state-cursor 'box + evil-insert-state-cursor 'bar + evil-emacs-state-cursor 'hbar))) + +(defun spacemacs-evil/init-evil-tutor () + (use-package evil-tutor + :commands (evil-tutor-start + evil-tutor-resume) + :init + (progn + (setq evil-tutor-working-directory + (concat spacemacs-cache-directory ".tutor/")) + (spacemacs/set-leader-keys "hT" 'evil-tutor-start)))) + +(defun spacemacs-evil/init-evil-unimpaired () + ;; No laziness here, unimpaired bindings should be available right away. + (use-package evil-unimpaired)) + +(defun spacemacs-evil/init-evil-visual-mark-mode () + (use-package evil-visual-mark-mode + :defer t + :init + (spacemacs|add-toggle evil-visual-mark-mode + :mode evil-visual-mark-mode + :documentation "Enable evil visual marks mode." + :evil-leader "t`"))) + +(defun spacemacs-evil/init-hs-minor-mode () + (add-hook 'prog-mode-hook 'spacemacs//enable-hs-minor-mode)) + +(defun spacemacs-evil/init-linum-relative () + (use-package linum-relative + :commands (linum-relative-toggle linum-relative-on) + :init + (progn + (when (eq dotspacemacs-line-numbers 'relative) + (linum-relative-on)) + (spacemacs/set-leader-keys "tr" 'spacemacs/linum-relative-toggle)) + :config + (progn + (setq linum-relative-current-symbol "")))) + +(defun spacemacs-evil/init-vi-tilde-fringe () + (spacemacs|do-after-display-system-init + (use-package vi-tilde-fringe + :init + (progn + (global-vi-tilde-fringe-mode) + (spacemacs|add-toggle vi-tilde-fringe + :mode global-vi-tilde-fringe-mode + :documentation + "Globally display a ~ on empty lines in the fringe." + :evil-leader "T~") + ;; don't enable it on some special buffers + (with-current-buffer spacemacs-buffer-name (spacemacs/disable-vi-tilde-fringe)) + (add-hook 'which-key-init-buffer-hook 'spacemacs/disable-vi-tilde-fringe) + ;; after a major mode is loaded, check if the buffer is read only + ;; if so, disable vi-tilde-fringe-mode + (add-hook 'after-change-major-mode-hook + 'spacemacs/disable-vi-tilde-fringe-read-only) + ;; TODO move this hook if/when we have a layer for eww + (spacemacs/add-to-hooks 'spacemacs/disable-vi-tilde-fringe + '(eww-mode-hook))) + :config + (spacemacs|hide-lighter vi-tilde-fringe-mode)))) diff --git a/layers/+spacemacs/spacemacs-language/packages.el b/layers/+spacemacs/spacemacs-language/packages.el new file mode 100644 index 0000000..a12874d --- /dev/null +++ b/layers/+spacemacs/spacemacs-language/packages.el @@ -0,0 +1,48 @@ +;;; packages.el --- Spacemacs Language Layer packages File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq spacemacs-language-packages + '((define-word :toggle (not (bound-and-true-p osx-use-dictionary-app))) + google-translate)) + +(defun spacemacs-language/init-define-word () + (use-package define-word + :defer t + :init + (spacemacs/set-leader-keys + "xwd" 'define-word-at-point))) + +(defun spacemacs-language/init-google-translate () + (use-package google-translate + :commands (spacemacs/set-google-translate-languages) + :init + (progn + (defun spacemacs/set-google-translate-languages (source target) + "Set source language for google translate. +For instance pass En as source for English." + (interactive + "sEnter source language (ie. en): \nsEnter target language (ie. en): " + source target) + (message + (format "Set google translate source language to %s and target to %s" + source target)) + (setq google-translate-default-source-language (downcase source)) + (setq google-translate-default-target-language (downcase target))) + (spacemacs/set-leader-keys + "xgl" 'spacemacs/set-google-translate-languages + "xgQ" 'google-translate-query-translate-reverse + "xgq" 'google-translate-query-translate + "xgT" 'google-translate-at-point-reverse + "xgt" 'google-translate-at-point) + (setq google-translate-enable-ido-completion t) + (setq google-translate-show-phonetic t) + (setq google-translate-default-source-language "en") + (setq google-translate-default-target-language "fr")))) diff --git a/layers/+spacemacs/spacemacs-layouts/config.el b/layers/+spacemacs/spacemacs-layouts/config.el new file mode 100644 index 0000000..43d5b89 --- /dev/null +++ b/layers/+spacemacs/spacemacs-layouts/config.el @@ -0,0 +1,35 @@ +;;; config.el --- Spacemacs Layouts Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(defvar spacemacs-layouts-directory + (expand-file-name (concat spacemacs-cache-directory "layouts/")) + "Save layouts in this directory.") + +(defvar layouts-enable-autosave nil + "If true, saves perspectives to file per `layouts-autosave-delay'") + +(defvar layouts-autosave-delay 900 + "Delay in seconds between each layouts auto-save.") + +(defvar spacemacs--ts-full-hint-toggle 0 + "Toggle display of transient states documentations.") + +(defvar spacemacs--last-selected-layout dotspacemacs-default-layout-name + "Previously selected layout.") + +(defvar spacemacs--custom-layout-alist nil + "List of custom layouts with their bound keys. + Do not modify directly, use provided `spacemacs|define-custom-layout'") + +(defvar spacemacs--layouts-autosave-timer nil + "Timer for layouts auto-save.") diff --git a/layers/+spacemacs/spacemacs-layouts/funcs.el b/layers/+spacemacs/spacemacs-layouts/funcs.el new file mode 100644 index 0000000..93816a1 --- /dev/null +++ b/layers/+spacemacs/spacemacs-layouts/funcs.el @@ -0,0 +1,591 @@ +;;; funcs.el --- Spacemacs Layouts Layer functions File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + +;; General Persp functions + +(defun spacemacs//current-layout-name () + "Get name of the current perspective." + (safe-persp-name (get-frame-persp))) + +(defun spacemacs//layout-autosave () + "Perspectives mode autosave. +Autosaves perspectives layouts every `persp-autosave-interal' seconds. +Cancels autosave on exiting perspectives mode." + (if (and persp-mode layouts-enable-autosave) + (progn + (message "Perspectives mode autosaving enabled.") + (setq spacemacs--layouts-autosave-timer + (run-with-timer + layouts-autosave-delay + layouts-autosave-delay + (lambda () + (message "Saving perspectives to file.") + (persp-save-state-to-file))))) + (when spacemacs--layouts-autosave-timer + (cancel-timer spacemacs--layouts-autosave-timer) + (setq spacemacs--layouts-autosave-timer nil)))) + +(defun spacemacs//layout-not-contains-buffer-p (buffer) + "Return non-nil if current layout doesn't contain BUFFER." + (not (persp-contain-buffer-p buffer))) + +(defun spacemacs/jump-to-last-layout () + "Open the previously selected layout, if it exists." + (interactive) + (unless (eq 'non-existent + (gethash spacemacs--last-selected-layout + *persp-hash* 'non-existent)) + (persp-switch spacemacs--last-selected-layout))) + +(defun spacemacs/alternate-buffer-in-persp () + "Switch back and forth between current and last buffer in the +current perspective." + (interactive) + (with-persp-buffer-list () + (switch-to-buffer (other-buffer (current-buffer) t)))) + +(defun spacemacs-layouts/non-restricted-buffer-list-helm () + (interactive) + (let ((ido-make-buffer-list-hook (remove #'persp-restrict-ido-buffers ido-make-buffer-list-hook))) + (helm-mini))) + +(defun spacemacs-layouts/non-restricted-buffer-list-ivy () + (interactive) + (let ((ivy-ignore-buffers (remove #'spacemacs//layout-not-contains-buffer-p ivy-ignore-buffers))) + (ivy-switch-buffer))) + + +;; Persp transient-state + +(defun spacemacs//layouts-ts-toggle-hint () + "Toggle the full hint docstring for the layouts transient-state." + (interactive) + (setq spacemacs--ts-full-hint-toggle + (logxor spacemacs--ts-full-hint-toggle 1))) + +(defun spacemacs//layout-format-name (name pos) + "Format the layout name given by NAME for display in mode-line." + (let* ((layout-name (if (file-directory-p name) + (file-name-nondirectory (directory-file-name name)) + name)) + (string-name (format "%s" layout-name)) + (current (equal name (spacemacs//current-layout-name))) + (caption (concat (number-to-string (if (eq 9 pos) 0 (1+ pos))) + ":" string-name))) + (if current + (propertize (concat "[" caption "]") 'face 'warning) + caption))) + +(defun spacemacs//layouts-ts-hint () + "Return a one liner string containing all the layout names." + (let* ((persp-list (or (persp-names-current-frame-fast-ordered) + (list persp-nil-name))) + (formatted-persp-list + (concat " " + (mapconcat (lambda (persp) + (spacemacs//layout-format-name + persp (position persp persp-list))) + persp-list " | ")))) + (concat + formatted-persp-list + (if (equal 1 spacemacs--ts-full-hint-toggle) + spacemacs--layouts-ts-full-hint + (concat " ([" + (propertize "?" 'face 'hydra-face-red) + "] help)"))))) + +(defun spacemacs/layout-switch-by-pos (pos) + "Switch to perspective of position POS." + (let ((persp-to-switch + (nth pos (persp-names-current-frame-fast-ordered)))) + (if persp-to-switch + (persp-switch persp-to-switch) + (when (y-or-n-p + (concat "Perspective in this position doesn't exist.\n" + "Do you want to create one? ")) + (let ((persp-reset-windows-on-nil-window-conf t)) + (persp-switch nil) + (spacemacs/home-delete-other-windows)))))) + +;; Define all `spacemacs/persp-switch-to-X' functions +(dolist (i (number-sequence 9 0 -1)) + (eval `(defun ,(intern (format "spacemacs/persp-switch-to-%s" i)) nil + ,(format "Switch to layout %s." i) + (interactive) + (spacemacs/layout-switch-by-pos ,(if (eq 0 i) 9 (1- i)))))) + +(defun spacemacs/layout-goto-default () + "Go to `dotspacemacs-default-layout-name` layout" + (interactive) + (when dotspacemacs-default-layout-name + (persp-switch dotspacemacs-default-layout-name))) + +(defun spacemacs/layouts-ts-rename () + "Rename a layout and get back to the perspectives transient-state." + (interactive) + (call-interactively 'persp-rename) + (spacemacs/layouts-transient-state/body)) + +(defun spacemacs/layouts-ts-close () + "Kill current perspective" + (interactive) + (persp-kill-without-buffers (spacemacs//current-layout-name))) + +(defun spacemacs/layouts-ts-close-other () + (interactive) + (call-interactively 'spacemacs/helm-persp-close) + (spacemacs/layouts-transient-state/body)) + +(defun spacemacs/layouts-ts-kill () + "Kill current perspective" + (interactive) + (persp-kill (spacemacs//current-layout-name))) + +(defun spacemacs/layouts-ts-kill-other () + (interactive) + (call-interactively 'spacemacs/helm-persp-kill) + (spacemacs/layouts-transient-state/body)) + + +;; Custom Persp transient-state + +(defun spacemacs//custom-layout-func-name (name) + "Return the name of the custom-perspective function for NAME." + (intern (concat "spacemacs/custom-perspective-" name))) + +(defmacro spacemacs|define-custom-layout (name &rest props) + "Define a custom-perspective called NAME. + +FUNC is a FUNCTION defined using NAME and the result of +`spacemacs//custom-layout-func-name', it takes care of +creating the perspective NAME and executing the expressions given +in the :body property to this macro. + +NAME is a STRING. + +Available PROPS: + +`:binding STRING' + Key to be bound to the function FUNC + +`:body EXPRESSIONS' + One or several EXPRESSIONS that are going to be evaluated after + we change into the perspective NAME." + (declare (indent 1)) + (let* ((name (if (symbolp name) + (symbol-value name) + name)) + (func (spacemacs//custom-layout-func-name name)) + (binding-prop (car (spacemacs/mplist-get props :binding))) + (binding (if (symbolp binding-prop) + (symbol-value binding-prop) + binding-prop)) + (body (spacemacs/mplist-get props :body)) + (already-defined? (cdr (assoc binding + spacemacs--custom-layout-alist)))) + `(progn + (defun ,func () + ,(format "Open custom perspective %s" name) + (interactive) + (let ((initialize (not (gethash ,name *persp-hash*)))) + (persp-switch ,name) + (when initialize + (delete-other-windows) + ,@body))) + ;; Check for Clashes + (if ,already-defined? + (unless (equal ,already-defined? ,name) + (spacemacs-buffer/warning "Replacing existing binding \"%s\" for %s with %s" + ,binding ,already-defined? ,name) + (setq spacemacs--custom-layout-alist + (delete (assoc ,binding spacemacs--custom-layout-alist) + spacemacs--custom-layout-alist)) + (push '(,binding . ,name) spacemacs--custom-layout-alist)) + (push '(,binding . ,name) spacemacs--custom-layout-alist))))) + +(defun spacemacs/select-custom-layout () + "Update the custom-perspectives transient-state and then activate it." + (interactive) + (spacemacs//update-custom-layouts) + (spacemacs/custom-layouts-transient-state/body)) + +(defun spacemacs//custom-layouts-ms-documentation () + "Return the docstring for the custom perspectives transient-state." + (if spacemacs--custom-layout-alist + (mapconcat (lambda (custom-persp) + (format "[%s] %s" + (car custom-persp) (cdr custom-persp))) + spacemacs--custom-layout-alist " ") + (spacemacs-buffer/warning (format "`spacemacs--custom-layout-alist' variable is empty" )))) + +(defun spacemacs//update-custom-layouts () + "Ensure the custom-perspectives transient-state is updated. +Takes each element in the list `spacemacs--custom-layout-alist' +format so they are supported by the +`spacemacs/custom-layouts-transient-state' macro." + (let (bindings) + (dolist (custom-persp spacemacs--custom-layout-alist bindings) + (let* ((binding (car custom-persp)) + (name (cdr custom-persp)) + (func-name (spacemacs//custom-layout-func-name name))) + (push (list binding func-name :exit t) bindings))) + (eval `(spacemacs|define-transient-state custom-layouts + :doc (concat (spacemacs//custom-layouts-ms-documentation)) + :bindings + ,@bindings)))) + + +;; Helm integration + +(defun spacemacs/persp-helm-mini () + "As `helm-mini' but restricts visible buffers by perspective." + (interactive) + (with-persp-buffer-list () + (helm-mini))) + +(defun spacemacs//helm-perspectives-source () + (helm-build-in-buffer-source + (concat "Current Perspective: " (spacemacs//current-layout-name)) + :data (persp-names) + :fuzzy-match t + :action + '(("Switch to perspective" . persp-switch) + ("Close perspective(s)" . (lambda (candidate) + (mapcar + 'persp-kill-without-buffers + (helm-marked-candidates)))) + ("Kill perspective(s)" . (lambda (candidate) + (mapcar 'persp-kill + (helm-marked-candidates))))))) +(defun spacemacs/helm-perspectives () + "Control Panel for perspectives. Has many actions. +If match is found +f1: (default) Select perspective +f2: Close Perspective(s) <- mark with C-SPC to close more than one-window +f3: Kill Perspective(s) + +If match is not found + Creates perspective + +Closing doesn't kill buffers inside the perspective while killing +perspectives does." + (interactive) + (helm + :buffer "*Helm Perspectives*" + :sources + `(,(spacemacs//helm-perspectives-source) + ,(helm-build-dummy-source "Create new perspective" + :requires-pattern t + :action + '(("Create new perspective" . + (lambda (name) + (let ((persp-reset-windows-on-nil-window-conf t)) + (persp-switch name) + (unless (member name (persp-names-current-frame-fast-ordered)) + (spacemacs/home)))))))))) + +;; ability to use helm find files but also adds to current perspective +(defun spacemacs/helm-persp-close () + "Kills perspectives without killing the buffers" + (interactive) + (helm + :buffer "*Helm Kill Perspectives (without killing buffers)*" + :sources + (helm-build-in-buffer-source + (concat "Current Perspective: " (spacemacs//current-layout-name)) + :data (persp-names) + :fuzzy-match t + :action + '(("Close perspective(s)" . (lambda (candidate) + (mapcar + 'persp-kill-without-buffers + (helm-marked-candidates)))))))) + +(defun spacemacs/helm-persp-kill () + "Kills perspectives with all their buffers" + (interactive) + (helm + :buffer "*Helm Kill Perspectives with all their buffers*" + :sources (helm-build-in-buffer-source + (s-concat "Current Perspective: " + (spacemacs//current-layout-name)) + :data (persp-names) + :fuzzy-match t + :action + '(("Kill perspective(s)" . + (lambda (candidate) + (mapcar 'persp-kill + (helm-marked-candidates)))))))) + +(defun spacemacs/helm-persp-switch-project (arg) + (interactive "P") + (helm + :sources + (helm-build-in-buffer-source "*Helm Switch Project Layout*" + :data (lambda () + (if (projectile-project-p) + (cons (abbreviate-file-name (projectile-project-root)) + (projectile-relevant-known-projects)) + projectile-known-projects)) + :fuzzy-match helm-projectile-fuzzy-match + :mode-line helm-read-file-name-mode-line-string + :action '(("Switch to Project Perspective" . + (lambda (project) + (let ((persp-reset-windows-on-nil-window-conf t)) + (persp-switch project) + (let ((projectile-completion-system 'helm)) + (projectile-switch-project-by-name project))))))) + :buffer "*Helm Projectile Layouts*")) + + +;; Ivy integration + +(defun spacemacs/ivy-persp-switch-project (arg) + (interactive "P") + (ivy-read "Switch to Project Perspective: " + (if (projectile-project-p) + (cons (abbreviate-file-name (projectile-project-root)) + (projectile-relevant-known-projects)) + projectile-known-projects) + :action (lambda (project) + (let ((persp-reset-windows-on-nil-window-conf t)) + (persp-switch project) + (let ((projectile-completion-system 'ivy)) + (projectile-switch-project-by-name project)))))) + + +;; Eyebrowse + +;; Eyebrowse uses window-state objects (as returned by `window-state-get') to +;; store window configurations, so here are some utility functions to help us +;; analyse window-states. +;; it might make more sense to move these functions to a more general place + +(defun spacemacs/window-state-window-p (object) + "Return t if OBJECT is a window, as represented in window-state objects. +Note: this function doesn't test for real window objects, but for +representations of a window in a window-state object as returned by +`window-state-get'." + (and (listp object) + (memq (car object) '(leaf vc hc)))) + +(defun spacemacs/window-state-get-buffer (window) + "Get WINDOW's buffer. +WINDOW is the representation of a window in a window-state object. +The returned value is the representation of a buffer in a window-state +object." + (cdr (assq 'buffer window))) + +(defun spacemacs/window-state-get-buffer-name (window) + "Get WINDOW's buffer's name. +WINDOW is the representation of a window in a window-state object." + (car (spacemacs/window-state-get-buffer window))) + +(defun spacemacs/window-state-walk-windows-1 (window fn) + "Helper function for `spacemacs/window-state-walk-windows'." + ;; WINDOW is a misleading name. WINDOW is a list that can represent a window, + ;; or a concatenation of several windows. window-state objects are weird. + (let ((child-windows + (-filter #'spacemacs/window-state-window-p window)) + (bare-window + ;; if WINDOW contains more than one window, take only the first window + (--take-while (not (spacemacs/window-state-window-p it)) + window))) + (--each child-windows + (spacemacs/window-state-walk-windows-1 it fn)) + (push (funcall fn bare-window) result))) + +(defun spacemacs/window-state-walk-windows (state fn) + "Execute FN once for each window in STATE and make a list of the results. +FN is a function to execute. +STATE is a window-state object." + (let (result) + (spacemacs/window-state-walk-windows-1 (cdr state) fn) + result)) + +(defun spacemacs/window-state-all-windows (state) + "Get all windows contained in STATE. +STATE is a window-state object. +The returned windows are not actual window objects. They are windows as +represented in window-state objects." + (spacemacs/window-state-walk-windows state #'identity)) + +(defun spacemacs/window-state-get-buffer-names (state) + "Get names of all buffers saved in STATE. +STATE is a window-state object as returned by `window-state-get'." + (delq nil (spacemacs/window-state-walk-windows state #'spacemacs/window-state-get-buffer-name))) + +(defun spacemacs/window-state-get-buffers (state) + "Get all buffers saved in STATE. +STATE is a window-state object as returned by `window-state-get'." + ;; delq nil - removes buffers stored in STATE that don't exist anymore + (delq nil (mapcar #'get-buffer (spacemacs/window-state-get-buffer-names state)))) + +(defun spacemacs/find-workspace (buffer) + "Find Eyebrowse workspace containing BUFFER. + If several workspaces contain BUFFER, return the first one. Workspaces are + ordered by slot number. + If no workspace contains + BUFFER, return nil." + ;; the second element of a workspace is its window-state object + (--find (memq buffer (spacemacs/window-state-get-buffers (cadr it))) + (eyebrowse--get 'window-configs))) + +(defun spacemacs/display-in-workspace (buffer alist) + "Display BUFFER's workspace. + Return BUFFER's window, if exists, otherwise nil. + If BUFFER is already visible in current workspace, just return its window + without switching workspaces." + (or (get-buffer-window buffer) + (-when-let (workspace (spacemacs/find-workspace buffer)) + (eyebrowse-switch-to-window-config (car workspace)) + (get-buffer-window buffer)))) + +(defun spacemacs/goto-buffer-workspace (buffer) + "Switch to BUFFER's window in BUFFER's workspace. + If BUFFER isn't displayed in any workspace, display it in the current + workspace, preferably in the current window." + (interactive "B") + (pop-to-buffer buffer '((;; reuse buffer window from some workspace + spacemacs/display-in-workspace + ;; fallback to display in current window + display-buffer-same-window) + (inhibit-same-window . nil)))) + + +;; Eyebrowse transient state + +(defun spacemacs//workspaces-ts-toggle-hint () + "Toggle the full hint docstring for the workspaces transient-state." + (interactive) + (setq spacemacs--ts-full-hint-toggle + (logxor spacemacs--ts-full-hint-toggle 1))) + +(defun spacemacs/workspaces-ts-rename () + "Rename a workspace and get back to transient-state." + (interactive) + (eyebrowse-rename-window-config (eyebrowse--get 'current-slot) nil) + (spacemacs/workspaces-transient-state/body)) + +(defun spacemacs//workspace-format-name (workspace) + "Return a propertized string given a WORKSPACE name." + (let* ((current (eq (eyebrowse--get 'current-slot) (car workspace))) + (name (nth 2 workspace)) + (number (car workspace)) + (caption (if (< 0 (length name)) + (concat (int-to-string number) ":" name) + (int-to-string number)))) + (if current + (propertize (concat "[" caption "]") 'face 'warning) + caption))) + +(defun spacemacs//workspaces-ts-hint () + "Return a one liner string containing all the workspaces names." + (concat + " " + (mapconcat 'spacemacs//workspace-format-name + (eyebrowse--get 'window-configs) " | ") + (if (equal 1 spacemacs--ts-full-hint-toggle) + spacemacs--workspaces-ts-full-hint + (concat " ([" + (propertize "?" 'face 'hydra-face-red) + "] help)")))) + + +;; Eyebrowse and Persp integration + +(defun spacemacs//get-persp-workspace (&optional persp frame) + "Get the correct workspace parameters for perspective. +PERSP is the perspective, and defaults to the current perspective. +FRAME is the frame where the parameters are expected to be used, and +defaults to the current frame." + (let ((param-names (if (display-graphic-p frame) + '(gui-eyebrowse-window-configs + gui-eyebrowse-current-slot + gui-eyebrowse-last-slot) + '(term-eyebrowse-window-configs + term-eyebrowse-current-slot + term-eyebrowse-last-slot)))) + (--map (persp-parameter it persp) param-names))) + +(defun spacemacs//set-persp-workspace (workspace-params &optional persp frame) + "Set workspace parameters for perspective. +WORKSPACE-PARAMS should be a list containing 3 elements in this order: +- window-configs, as returned by (eyebrowse--get 'window-configs) +- current-slot, as returned by (eyebrowse--get 'current-slot) +- last-slot, as returned by (eyebrowse--get 'last-slot) +PERSP is the perspective, and defaults to the current perspective. +FRAME is the frame where the parameters came from, and defaults to the +current frame. + +Each perspective has two sets of workspace parameters: one set for +graphical frames, and one set for terminal frames." + (let ((param-names (if (display-graphic-p frame) + '(gui-eyebrowse-window-configs + gui-eyebrowse-current-slot + gui-eyebrowse-last-slot) + '(term-eyebrowse-window-configs + term-eyebrowse-current-slot + term-eyebrowse-last-slot)))) + (--zip-with (set-persp-parameter it other persp) + param-names workspace-params))) + +(defun spacemacs/load-eyebrowse-for-perspective (type &optional frame) + "Load an eyebrowse workspace according to a perspective's parameters. + FRAME's perspective is the perspective that is considered, defaulting to + the current frame's perspective. + If the perspective doesn't have a workspace, create one." + (when (eq type 'frame) + (let* ((workspace-params (spacemacs//get-persp-workspace (get-frame-persp frame) frame)) + (window-configs (nth 0 workspace-params)) + (current-slot (nth 1 workspace-params)) + (last-slot (nth 2 workspace-params))) + (if window-configs + (progn + (eyebrowse--set 'window-configs window-configs frame) + (eyebrowse--set 'current-slot current-slot frame) + (eyebrowse--set 'last-slot last-slot frame) + (eyebrowse--load-window-config current-slot)) + (eyebrowse--set 'window-configs nil frame) + (eyebrowse-init frame) + (spacemacs/save-eyebrowse-for-perspective frame))))) + +(defun spacemacs/load-eyebrowse-after-loading-layout (_state-file _phash persp-names) + "Bridge between `persp-after-load-state-functions' and +`spacemacs/load-eyebrowse-for-perspective'. + +_PHASH is the hash were the loaded perspectives were placed, and +PERSP-NAMES are the names of these perspectives." + (let ((cur-persp (get-current-persp))) + ;; load eyebrowse for current perspective only if it was one of the loaded + ;; perspectives + (when (member (or (and cur-persp (persp-name cur-persp)) + persp-nil-name) + persp-names) + (spacemacs/load-eyebrowse-for-perspective 'frame)))) + +(defun spacemacs/update-eyebrowse-for-perspective (&rest _args) + "Update and save current frame's eyebrowse workspace to its perspective." + (let* ((current-slot (eyebrowse--get 'current-slot)) + (current-tag (nth 2 (assoc current-slot (eyebrowse--get 'window-configs))))) + (eyebrowse--update-window-config-element + (eyebrowse--current-window-config current-slot current-tag))) + (spacemacs/save-eyebrowse-for-perspective)) + +(defun spacemacs/save-eyebrowse-for-perspective (&optional frame) + "Save FRAME's eyebrowse workspace to FRAME's perspective. +FRAME defaults to the current frame." + (spacemacs//set-persp-workspace (list (eyebrowse--get 'window-configs frame) + (eyebrowse--get 'current-slot frame) + (eyebrowse--get 'last-slot frame)) + (get-frame-persp frame) + frame)) diff --git a/layers/+spacemacs/spacemacs-layouts/packages.el b/layers/+spacemacs/spacemacs-layouts/packages.el new file mode 100644 index 0000000..2559a7c --- /dev/null +++ b/layers/+spacemacs/spacemacs-layouts/packages.el @@ -0,0 +1,230 @@ +;;; packages.el --- Spacemacs Layouts Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq spacemacs-layouts-packages + '(eyebrowse + helm + ivy + persp-mode + spaceline + swiper)) + + + +(defun spacemacs-layouts/init-eyebrowse () + (use-package eyebrowse + :init + (progn + (setq eyebrowse-wrap-around t) + (eyebrowse-mode) + ;; transient state + (spacemacs|transient-state-format-hint workspaces + spacemacs--workspaces-ts-full-hint + "\n\n + Go to^^^^^^ Actions^^ + ─────^^^^^^─────────────────────── ───────^^────────────────────── + [_0_,_9_]^^ nth/new workspace [_d_] close current workspace + [_C-0_,_C-9_]^^ nth/new workspace [_R_] rename current workspace + [__]^^^^ last workspace [_?_] toggle help\n + [_l_]^^^^ layouts + [_n_/_C-l_]^^ next workspace + [_N_/_p_/_C-h_] prev workspace\n") + + (spacemacs|define-transient-state workspaces + :title "Workspaces Transient State" + :hint-is-doc t + :dynamic-hint (spacemacs//workspaces-ts-hint) + :bindings + ("?" spacemacs//workspaces-ts-toggle-hint) + ("0" eyebrowse-switch-to-window-config-0 :exit t) + ("1" eyebrowse-switch-to-window-config-1 :exit t) + ("2" eyebrowse-switch-to-window-config-2 :exit t) + ("3" eyebrowse-switch-to-window-config-3 :exit t) + ("4" eyebrowse-switch-to-window-config-4 :exit t) + ("5" eyebrowse-switch-to-window-config-5 :exit t) + ("6" eyebrowse-switch-to-window-config-6 :exit t) + ("7" eyebrowse-switch-to-window-config-7 :exit t) + ("8" eyebrowse-switch-to-window-config-8 :exit t) + ("9" eyebrowse-switch-to-window-config-9 :exit t) + ("C-0" eyebrowse-switch-to-window-config-0) + ("C-1" eyebrowse-switch-to-window-config-1) + ("C-2" eyebrowse-switch-to-window-config-2) + ("C-3" eyebrowse-switch-to-window-config-3) + ("C-4" eyebrowse-switch-to-window-config-4) + ("C-5" eyebrowse-switch-to-window-config-5) + ("C-6" eyebrowse-switch-to-window-config-6) + ("C-7" eyebrowse-switch-to-window-config-7) + ("C-8" eyebrowse-switch-to-window-config-8) + ("C-9" eyebrowse-switch-to-window-config-9) + ("" eyebrowse-last-window-config) + ("C-h" eyebrowse-prev-window-config) + ("C-i" eyebrowse-last-window-config) + ("C-l" eyebrowse-next-window-config) + ("d" eyebrowse-close-window-config) + ("l" spacemacs/layouts-transient-state/body :exit t) + ("n" eyebrowse-next-window-config) + ("N" eyebrowse-prev-window-config) + ("p" eyebrowse-prev-window-config) + ("R" spacemacs/workspaces-ts-rename :exit t) + ("w" eyebrowse-switch-to-window-config :exit t)) + ;; note: we don't need to declare the `SPC l w' binding, it is + ;; declare in the layout transient state + (spacemacs/set-leader-keys "bW" 'spacemacs/goto-buffer-workspace) + ;; hooks + (add-hook 'persp-before-switch-functions + #'spacemacs/update-eyebrowse-for-perspective) + (add-hook 'eyebrowse-post-window-switch-hook + #'spacemacs/save-eyebrowse-for-perspective) + (add-hook 'persp-activated-functions + #'spacemacs/load-eyebrowse-for-perspective) + (add-hook 'persp-before-save-state-to-file-functions #'spacemacs/update-eyebrowse-for-perspective) + (add-hook 'persp-after-load-state-functions #'spacemacs/load-eyebrowse-after-loading-layout) + ;; vim-style tab switching + (define-key evil-motion-state-map "gt" 'eyebrowse-next-window-config) + (define-key evil-motion-state-map "gT" 'eyebrowse-prev-window-config)))) + + + +(defun spacemacs-layouts/post-init-helm () + (spacemacs/set-leader-keys + "Bb" 'spacemacs-layouts/non-restricted-buffer-list-helm + "pl" 'spacemacs/helm-persp-switch-project)) + + + +(defun spacemacs-layouts/post-init-ivy () + (spacemacs/set-leader-keys + "Bb" 'spacemacs-layouts/non-restricted-buffer-list-ivy)) + + + +(defun spacemacs-layouts/init-persp-mode () + (use-package persp-mode + :diminish persp-mode + :init + (progn + (setq persp-auto-resume-time (if (or dotspacemacs-auto-resume-layouts + spacemacs-force-resume-layouts) + 1 -1) + persp-nil-name dotspacemacs-default-layout-name + persp-reset-windows-on-nil-window-conf nil + persp-set-last-persp-for-new-frames nil + persp-save-dir spacemacs-layouts-directory + persp-set-ido-hooks t) + + (defun spacemacs//activate-persp-mode () + "Always activate persp-mode, unless it is already active. + (e.g. don't re-activate during `dotspacemacs/sync-configuration-layers' - + see issues #5925 and #3875)" + (unless (bound-and-true-p persp-mode) + (persp-mode))) + (spacemacs/defer-until-after-user-config #'spacemacs//activate-persp-mode) + + ;; layouts transient state + ;; TODO move helm specific key bindings to helm layer + ;; (see ivy for how to do it) + (spacemacs|transient-state-format-hint layouts + spacemacs--layouts-ts-full-hint + "\n\n + Go to^^^^^^ Actions^^ + ─────^^^^^^────────────────────────────── ───────^^────────────────────────────────────────────────── + [_0_,_9_]^^ nth/new layout [_a_]^^ add buffer + [_C-0_,_C-9_]^^ nth/new layout [_A_]^^ add all from layout + [__]^^^^ last layout [_d_]^^ close current layout + [_b_]^^^^ buffer in layout [_D_]^^ close other layout + [_h_]^^^^ default layout [_r_]^^ remove current buffer + [_l_]^^^^ layout w/helm/ivy [_R_]^^ rename current layout + [_L_]^^^^ layouts in file [_s_/_S_] save all layouts/save by names + [_n_/_C-l_]^^ next layout [_t_]^^ show a buffer without adding it to current layout + [_N_/_p_/_C-h_] prev layout [_x_]^^ kill current w/buffers + [_o_]^^^^ custom layout [_X_]^^ kill other w/buffers + [_w_]^^^^ workspaces transient state [_?_]^^ toggle help\n") + + (spacemacs|define-transient-state layouts + :title "Layouts Transient State" + :hint-is-doc t + :dynamic-hint (spacemacs//layouts-ts-hint) + :bindings + ;; need to exit in case number doesn't exist + ("?" spacemacs//layouts-ts-toggle-hint) + ("1" spacemacs/persp-switch-to-1 :exit t) + ("2" spacemacs/persp-switch-to-2 :exit t) + ("3" spacemacs/persp-switch-to-3 :exit t) + ("4" spacemacs/persp-switch-to-4 :exit t) + ("5" spacemacs/persp-switch-to-5 :exit t) + ("6" spacemacs/persp-switch-to-6 :exit t) + ("7" spacemacs/persp-switch-to-7 :exit t) + ("8" spacemacs/persp-switch-to-8 :exit t) + ("9" spacemacs/persp-switch-to-9 :exit t) + ("0" spacemacs/persp-switch-to-0 :exit t) + ("C-1" spacemacs/persp-switch-to-1) + ("C-2" spacemacs/persp-switch-to-2) + ("C-3" spacemacs/persp-switch-to-3) + ("C-4" spacemacs/persp-switch-to-4) + ("C-5" spacemacs/persp-switch-to-5) + ("C-6" spacemacs/persp-switch-to-6) + ("C-7" spacemacs/persp-switch-to-7) + ("C-8" spacemacs/persp-switch-to-8) + ("C-9" spacemacs/persp-switch-to-9) + ("C-0" spacemacs/persp-switch-to-0) + ("" spacemacs/jump-to-last-layout) + ("" nil :exit t) + ("C-h" persp-prev) + ("C-l" persp-next) + ("a" persp-add-buffer :exit t) + ("A" persp-import-buffers :exit t) + ("b" spacemacs/persp-helm-mini :exit t) + ("d" spacemacs/layouts-ts-close) + ("D" spacemacs/layouts-ts-close-other :exit t) + ("h" spacemacs/layout-goto-default :exit t) + ("l" spacemacs/helm-perspectives :exit t) + ("L" persp-load-state-from-file :exit t) + ("n" persp-next) + ("N" persp-prev) + ("o" spacemacs/select-custom-layout :exit t) + ("p" persp-prev) + ("r" persp-remove-buffer :exit t) + ("R" spacemacs/layouts-ts-rename :exit t) + ("s" persp-save-state-to-file :exit t) + ("S" persp-save-to-file-by-names :exit t) + ("t" persp-temporarily-display-buffer :exit t) + ("w" spacemacs/workspaces-transient-state/body :exit t) + ("x" spacemacs/layouts-ts-kill) + ("X" spacemacs/layouts-ts-kill-other :exit t)) + (spacemacs/set-leader-keys "l" 'spacemacs/layouts-transient-state/body) + ;; custom layouts + (spacemacs|define-custom-layout "@Spacemacs" + :binding "e" + :body + (spacemacs/find-dotfile))) + :config + (progn + (defadvice persp-activate (before spacemacs//save-toggle-layout activate) + (setq spacemacs--last-selected-layout persp-last-persp-name)) + (add-hook 'persp-mode-hook 'spacemacs//layout-autosave) + (spacemacs/declare-prefix "b" "persp-buffers") + (spacemacs/declare-prefix "B" "global-buffers") + ;; Override SPC TAB to only change buffers in perspective + (spacemacs/set-leader-keys + "TAB" 'spacemacs/alternate-buffer-in-persp + "ba" 'persp-add-buffer + "br" 'persp-remove-buffer)))) + + + +(defun spacemacs-layouts/post-init-spaceline () + (setq spaceline-display-default-perspective + dotspacemacs-display-default-layout)) + + + +(defun spacemacs-layouts/post-init-swiper () + (spacemacs/set-leader-keys "pl" 'spacemacs/ivy-persp-switch-project)) diff --git a/layers/+spacemacs/spacemacs-misc/packages.el b/layers/+spacemacs/spacemacs-misc/packages.el new file mode 100644 index 0000000..31aa5f2 --- /dev/null +++ b/layers/+spacemacs/spacemacs-misc/packages.el @@ -0,0 +1,35 @@ +;;; packages.el --- Spacemacs Misc. Layer packages File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq spacemacs-misc-packages + '( + dumb-jump + request + )) + +(defun spacemacs-misc/init-dumb-jump () + (use-package dumb-jump + :defer t + :init + (progn + ;; not activating `dumb-jump-mode' because it only adds key bindings, and + ;; they conflict with existing bindings (see + ;; https://github.com/syl20bnr/spacemacs/issues/7107) + + (spacemacs/set-leader-keys "jq" #'dumb-jump-quick-look) + ;; Since it's dumb, we add it to the end of the default jump handlers. At + ;; the time of writing it is the only default jump handler. (gtags remains + ;; mode-local) + (add-to-list 'spacemacs-default-jump-handlers 'dumb-jump-go 'append)))) + +(defun spacemacs-misc/init-request () + (setq request-storage-directory + (concat spacemacs-cache-directory "request/"))) diff --git a/layers/+spacemacs/spacemacs-org/local/space-doc/space-doc.el b/layers/+spacemacs/spacemacs-org/local/space-doc/space-doc.el new file mode 100644 index 0000000..8463fe8 --- /dev/null +++ b/layers/+spacemacs/spacemacs-org/local/space-doc/space-doc.el @@ -0,0 +1,456 @@ +;;; space-doc.el --- Spacemacs documentation minor mode. +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;; Description: +;; This package provides: +;; - `space-doc-mode' - buffer local minor mode +;; for viewing the Spacemacs documentation files. +;; The mode hides org meta tags to improve readability. +;; - `org-mode' link-type "https" that opens the local +;; copies of the Spacemacs documentation files with +;; `spacemacs/view-org-file' and supports GitHub style +;; heading links. +;; +;; For example, the link: +;; https://github.com/syl20bnr/spacemacs/blob/develop/layers/org/README.org#links +;; Will be handled similary to as if it was: +;; file:~/.emacs.d/layers/org/README.org::*links +;; Also the `space-doc' mode will be applied. + +;;; License: GPLv3 +;;; Code: +(require 'face-remap) +(require 'org) +(require 'org-compat) +(require 'centered-buffer-mode) + +(defgroup space-doc nil "Minor mode for viewing Spacemacs documentation files." + :group 'convenience) + +(define-minor-mode space-doc-mode + "Buffer local minor mode for viewing Spacemacs documentation files. +This mode: + - hides `org-mode' meta tags like #+TITLE: while +keeping their content visible. + - Improves emphasized region apparence. + - enables buffer local link opening with `spacemacs//space-doc-open'. +================================================= += THE MODE IS CUSTOMIZABLE - read Spacemacs FAQ = +=================================================" + :init-value nil + :lighter " SD" + :group 'space-doc + (spacemacs//space-doc-centered-buffer-mode-goto-origin space-doc-mode) + (if (derived-mode-p 'org-mode) + (let ((inhibit-read-only t)) + (spacemacs//space-doc-set-cache +1) + (dolist (modificator spacemacs-space-doc-modificators-functions) + (when (member (car modificator) + spacemacs-space-doc-modificators) + (funcall (cdr modificator) space-doc-mode)))) + ;; Force `org-mode' to replace font text properties with the default ones. + (unless space-doc-mode (org-font-lock-ensure)) + (message (format "space-doc-mode error:%s isn't an org-mode buffer" + (buffer-name))) + (setq space-doc-mode nil))) + +;; NOTE: Dont forget to update Spacemacs FAQ if you modify this list! +(defcustom spacemacs-space-doc-modificators + '(org-indent-mode + view-mode + hide-line-numbers + alternative-emphasis + alternative-tags-look + link-protocol + org-block-line-face-remap + org-kbd-face-remap + resize-inline-images) + "List of `space-doc' modificators." + :type '(set (const center-buffer-mode) + (const org-indent-mode) + (const view-mode) + (const hide-line-numbers) + (const alternative-emphasis) + (const alternative-tags-look) + (const link-protocol) + (const org-block-line-face-remap) + (const org-kbd-face-remap) + (const resize-inline-images)) + :group 'space-doc) + +(defcustom spacemacs-space-doc-center-buffer-mode-min-aspect-ratio + 1.7 + "Minimal `frame' aspect ration (`frame-pixel-width' divided by `frame-pixel-height') +for `spacemacs-centered-buffer-mode' to be automatically enabled. +NOTE: If `center-buffer-mode' isn't a member of `spacemacs-space-doc-modificators' +list `spacemacs-centered-buffer-mode' will not be enabled." + :type 'number + :group 'space-doc) + +(defvar spacemacs-space-doc-modificators-functions + '((center-buffer-mode . spacemacs//space-doc-center-buffer-mode) + (org-indent-mode . spacemacs//space-doc-org-indent-mode) + (view-mode . spacemacs//space-doc-view-mode) + (hide-line-numbers . spacemacs//space-doc-hide-line-numbers) + (alternative-emphasis . spacemacs//space-doc-alternative-emphasis) + (alternative-tags-look . spacemacs//space-doc-alternative-tags-look) + (link-protocol . spacemacs//space-doc-link-protocol) + (org-block-line-face-remap . spacemacs//space-doc-org-block-line-face-remap) + (org-kbd-face-remap . spacemacs//space-doc-org-kbd-face-remap) + (resize-inline-images . spacemacs//space-doc-resize-inline-images)) + "alist of `space-doc' modificator (tag . function) for `org-mode' buffers. +The functions work with a current buffer and accept ENABLE(flag) argument. +If the argument has non-nil value - enable the modifications introduced +by the function. Otherwise - disable. The tags used in `spacemacs-space-doc-modificators'") + +(defun spacemacs//space-doc-centered-buffer-mode-goto-origin (flag) + "Switch to the origin buffer if `spacemacs-centere-buffer-mode' is +enabled. Set the value of `space-doc-mode' variable in the origin +buffer to FLAG." + (when spacemacs-centered-buffer-mode + (let ((old-flag space-doc-mode)) + (spacemacs-centered-buffer-mode -1) + (setq space-doc-mode old-flag)))) + +(defun spacemacs//space-doc-center-buffer-mode (&optional flag) + "Enable `spacemacs-centered-buffer-mode' if flag is non nil, disable it otherwise. +This functions is aimed to be used with `spacemacs-space-doc-modificators'." + (when (and flag + (not spacemacs-centered-buffer-mode) + (>= (/ (* (frame-pixel-width) 1.0) (frame-pixel-height)) + spacemacs-space-doc-center-buffer-mode-min-aspect-ratio)) + ;; `spacemacs-centered-buffer-mode' is heavy so it's better to make if deferred. + ;; Also it has to be run when the `window-body-width' is properly calculated. + (run-with-idle-timer 0 nil 'spacemacs-centered-buffer-mode)) + (spacemacs-centered-buffer-mode -1)) + +(defun spacemacs//space-doc-org-indent-mode (&optional flag) + "Enable `org-indent-mode' if flag is non nil, disable it otherwise. +This functions is aimed to be used with `spacemacs-space-doc-modificators'." + (org-indent-mode (if flag 1 -1))) + +(defun spacemacs//space-doc-view-mode (&optional flag) + "Enable `view-mode' if flag is non nil, disable it otherwise. +This functions is aimed to be used with `spacemacs-space-doc-modificators'." + (view-mode (if flag 1 -1))) + +(cl-defstruct spacemacs--space-doc-cache-struct + marker-face + btn-marker-face + kbd-marker) + +(defvar-local spacemacs--space-doc-cache nil + "Global variable of struct `spacemacs-space-doc-cache-struct'. +It is set by `spacemacs//space-doc-set-cache'.") + +(defun spacemacs//space-doc-set-cache (&optional flag) + "Set `spacemacs--space-doc-cache'. +This functions is aimed to be used with `spacemacs-space-doc-modificators'." + (setq spacemacs--space-doc-cache + (if flag + (let* ((kbd-bg (or (face-background 'org-kbd) + (face-background 'region) + 'unspecified)) + (table-bg (or (face-background 'org-table) + (face-background 'default) + 'unspecified)) + (marker-face + `(:inherit org-table + :foreground ,table-bg)) + (btn-marker-face + `(:inherit org-kbd + :distant-foreground ,kbd-bg + :foreground ,kbd-bg)) + (kbd-marker + (dolist (el org-emphasis-alist) + (when (member 'org-kbd el) + (return (car el)))))) + (make-spacemacs--space-doc-cache-struct + :marker-face marker-face + :btn-marker-face btn-marker-face + :kbd-marker kbd-marker))))) + +(defun spacemacs//space-doc-hide-line-numbers (&optional enable) + "If ENABLE is non-nil then toggle off the line numbers. +This functions is aimed to be used with `spacemacs-space-doc-modificators'." + (if enable + (spacemacs/toggle-line-numbers-off) + (when dotspacemacs-line-numbers + (spacemacs/toggle-line-numbers-on)))) + +(defun spacemacs//space-doc-org-do-emphasis-faces-advice (found) + "If FOUND has non-nil value then modify emphasized regions +appearances in the current buffer. The function uses +`match-data' set by `org-do-emphasis-faces' function." + ;; `org-do-emphasis-faces' returns non-nil value when it + ;; found a region to emphasize. + (when (and space-doc-mode + found + (not (and + (match-string 4) + (string-empty-p + (replace-regexp-in-string "\\*+" + "" + (match-string 4)))))) + (spacemacs//space-doc-emphasis-region + (match-beginning 2) + (match-end 2))) + found) + +(defun spacemacs//space-doc-advice-org-do-emphasis-faces (&optional enable) + "Advise org-do-emphasis-faces. +If ENABLE is non-nil, add advice `org-do-emphasis-faces' function with +`spacemacs//space-doc-org-do-emphasis-faces-advice'. +NOTE: `org-do-emphasis-faces' is lazy and will emphasize only part of the +current buffer so piggybacking it should be pretty performant solution." + (when enable + (advice-add 'org-do-emphasis-faces + :after + #'spacemacs//space-doc-org-do-emphasis-faces-advice))) + +(defun spacemacs//space-doc-add-region-edge-text-property (begin end property &optional face) + "Add text PROPERTY to the first and last character of the BEGIN END text region +with `add-text-properties' or if FACE has non-nil value `add-face-text-property'." + (let ((edge-sub-regs (list (list (1+ begin) begin) + (list (1- end) end)))) + (dolist (edge-sub-reg edge-sub-regs) + (funcall (if face + 'add-face-text-property + 'add-text-properties) + (car edge-sub-reg) + (cadr edge-sub-reg) + property)))) + +(defun spacemacs//space-doc-emphasis-region (begin end) + "Emphasis region based on its leading character. +The character should be one of the markers from `org-emphasis-alist'." + (let ((kbd-face (spacemacs--space-doc-cache-struct-btn-marker-face + spacemacs--space-doc-cache)) + (marker-face (spacemacs--space-doc-cache-struct-marker-face + spacemacs--space-doc-cache))) + (if (string= (buffer-substring-no-properties begin + (1+ begin)) + (spacemacs--space-doc-cache-struct-kbd-marker + spacemacs--space-doc-cache)) + (spacemacs//space-doc-add-region-edge-text-property begin end kbd-face t) + (if (save-excursion + (goto-char begin) + (beginning-of-line) + (looking-at-p org-table-any-line-regexp)) + ;; If inside table. + (spacemacs//space-doc-add-region-edge-text-property begin end marker-face t) + (spacemacs//space-doc-add-region-edge-text-property + begin + end + '(invisible spacemacs--space-doc-invisible-marker)))))) + +(defun spacemacs//space-doc-alternative-emphasis (&optional enable) + "Emphasis overlays. +If ENABLE is non-nil, change the look of regions which have already +been emphasized by `org-do-emphasis-faces' in the current buffer. +Otherwise revert to the normal look. +This functions is aimed to be used with `spacemacs-space-doc-modificators'." + (if enable + (progn + (spacemacs//space-doc-advice-org-do-emphasis-faces enable) + (add-to-invisibility-spec 'spacemacs--space-doc-invisible-marker) + (dolist (emphasized-region + (spacemacs//space-doc-find-regions-by-text-property + 'org-emphasis t)) + (spacemacs//space-doc-emphasis-region + (car emphasized-region) + (cadr emphasized-region)))) + (remove-from-invisibility-spec 'spacemacs--space-doc-invisible-marker))) + +(defun spacemacs//space-doc-org-kbd-face-remap (&optional enable) + "Remove boxes from key bindings. +If ENABLE is non-nil, removes boxes from the `org-kbd'face in the current +`org-mode' buffer. +Otherwise, reverts them to default. +This functions is aimed to be used with `spacemacs-space-doc-modificators'." + (if enable + (set (make-local-variable + 'spacemacs--space-doc-org-kbd-face-remap-cookie) + (face-remap-add-relative 'org-kbd + `(:box nil))) + (when (bound-and-true-p spacemacs--space-doc-org-kbd-face-remap-cookie) + (face-remap-remove-relative + spacemacs--space-doc-org-kbd-face-remap-cookie)))) + +(defun spacemacs//space-doc-resize-inline-images (&optional enable) + "Resize inline images. +If ENABLE is non nil then resize inline images. +This functions is aimed to be used with `spacemacs-space-doc-modificators'." + ;; resizing is always performed even when the image is smaller + ;; so we don't resize in README.org buffers for now + (let ((org-image-actual-width + (and enable + (not (string-match-p ".*README.org\\'" (buffer-file-name))) + 600))) + (org-display-inline-images))) + +(defun spacemacs//space-doc-tags-fontify (startish endish &optional verbose) + "Fontify `org-mode' tags in the fuzzy region that starts + before STARTISH and end after ENDISH. VERBOSE ignored." + ;; TODO add more types of tags or meta-line if needed. + (let ((invisible-org-meta-tags-list + `(;; Hide TITLE tag. + "\\([ \t]*\\#\\+TITLE\\:\[ \t]*\\)" + ;; Hide CAPTION logo meta line. + "\\(\n.*\\#\\+CAPTION\\:.*\\)" + ;; Hide TOC-ORG tag and spaces before it. + ;; Use modified `toc-org-toc-org-regexp' because + ;; the original one matches whole string. + ,(concat "\\([ \t]*:toc\\([@_][0-9]\\|\\([@_][0-9]" + "[@_][a-zA-Z]+\\)\\)?:\\($\\|[^ ]*:$\\)\\)") + ;; Hide empty line before #+BEGIN_SRC tag if + ;; background color of the `org-block-begin-line' + ;; face is unspecified. + ,(unless (face-background 'org-block-begin-line) + "\n\\(\n\\)[ \t]*\\#\\+begin_src.*$") + ;; Hide empty line after #+END_SRC tag if + ;; background color of the `org-block-end-line' + ;; face is unspecified and the next line isn't + ;;an org headline. + ,(unless (face-background 'org-block-end-line) + "^[ \t]*\\#\\+end_src.*\n\\(\n\\)[^\\*]"))) + (start (save-excursion (goto-char (or startish + (point-min))) + (point-at-bol -2))) + (end (save-excursion (goto-char (or endish + (point-max))) + (point-at-eol 2)))) + ;; Remove nils. + (setq invisible-org-meta-tags-list + (remove nil invisible-org-meta-tags-list)) + ;; Make `org-mode' meta tags invisible. + (dolist (tag invisible-org-meta-tags-list) + (save-excursion + (goto-char start) + (while (re-search-forward tag end t) + (add-text-properties (match-beginning 1) + (match-end 1) + (list 'invisible 'spacemacs--space-doc-invisible-marker))))))) + +(defun spacemacs//space-doc-font-lock-fontify-region-function (start end &optional verbose) + "Wrapper around `font-lock-default-fontify-region' function for the buffer local value of +`font-lock-fontify-region-function'. Makes sure that `font-lock-default-fontify-region' +text property persist after `org-mode' shenanigans. +NOTE: Not using `advice-add' because it is global modification. +FIXME: Find cleaner solution." + (font-lock-default-fontify-region start end verbose) + (spacemacs//space-doc-tags-fontify start end verbose)) + +(defun spacemacs//space-doc-alternative-tags-look (&optional enable) + "Modify meta tag appearance. +If ENABLE is non-nil, modify `org-mode' meta tags appearance in the current +buffer. +This functions is aimed to be used with `spacemacs-space-doc-modificators'." + (if enable + (setq-local font-lock-fontify-region-function + 'spacemacs//space-doc-font-lock-fontify-region-function) + (kill-local-variable 'font-lock-fontify-region-function))) + +(defun spacemacs//space-doc-org-block-line-face-remap (&optional enable) + "Hide drawers. +If ENABLE is non-nil, hide text of the code block meta lines in the current +buffer. If the blocks have background color text won't be masked because it +makes them look ugly with some themes. +If ENABLE has nil, revert to the default. +This functions is aimed to be used with `spacemacs-space-doc-modificators'." + (if enable + (let* ((default-bg (or (face-background 'default) + 'unspecified)) + (org-bb-bg (or (face-background 'org-block-begin-line) + (face-background 'org-meta-line))) + (hide-bb-text-face `(:inherit org-block-begin-line + :foreground ,default-bg + :distant-foreground ,default-bg)) + (org-bn-bg (or (face-background 'org-block-end-line) + (face-background 'org-meta-line))) + (hide-bn-text-face `(:inherit org-block-end-line + :foreground ,default-bg + :distant-foreground ,default-bg))) + (unless org-bb-bg + (set (make-local-variable + 'spacemacs--space-doc-org-block-begin-line-face-remap-cookie) + (face-remap-add-relative 'org-block-begin-line + hide-bb-text-face))) + (unless org-bn-bg + (set (make-local-variable + 'spacemacs--space-doc-org-block-end-line-face-remap-cookie) + (face-remap-add-relative 'org-block-end-line + hide-bn-text-face)))) + (when (bound-and-true-p + spacemacs--space-doc-org-block-begin-line-face-remap-cookie) + (face-remap-remove-relative + spacemacs--space-doc-org-block-begin-line-face-remap-cookie)) + (when (bound-and-true-p + spacemacs--space-doc-org-block-end-line-face-remap-cookie) + (face-remap-remove-relative + spacemacs--space-doc-org-block-end-line-face-remap-cookie)))) + +(defun spacemacs//space-doc-link-protocol (&optional enable) + "Open HTTPS links in the curren buffer. +If ENABLE is non-nil, use `spacemacs//space-doc-open' to open HTTPS links +in the current `org-mode' buffer. +Otherwise open them in the browser(default behavior). +This functions is aimed to be used with `spacemacs-space-doc-modificators'." + (if enable + (progn + ;; Make `space-doc' https link opener buffer local + ;; and enable it only when `space-doc' mode is enabled. + (make-local-variable 'org-link-types) + (make-local-variable 'org-link-protocols) + (org-add-link-type "https" 'spacemacs//space-doc-open)) + (kill-local-variable 'org-link-types) + (kill-local-variable 'org-link-protocols)) + ;; Trigger `org-mode' internal updates. + ;; NOTE: might be unnecessary. + (org-add-link-type nil)) + +(defun spacemacs//space-doc-open (path) + "Open PATH link. +If PATH argument is a link to an .org file that is located in the Spacemacs +GitHub repository then visit the local copy of the file with +`spacemacs/view-org-file'. +Open all other links with `browse-url'." + (let ((git-url-root-regexp + (concat "\\/\\/github\\.com\\/syl20bnr\\/spacemacs\\/blob" + "\\/[^/]+\\/\\(.*\\.org\\)\\(\\#.*\\)?"))) + (if (string-match git-url-root-regexp path) + (spacemacs/view-org-file (concat spacemacs-start-directory + (match-string 1 path)) + (or (match-string 2 path) + "^") + 'subtree) + (browse-url (concat "https://" path))))) + +(defun spacemacs//space-doc-find-regions-by-text-property + (property value &optional start end) + "Return a list of pairs (region-beginning region-end) in +the current buffer. If START or END has non-nil value - use them as +boundaries. +NOTE: It can find only fontified regions." + (let ((p-min (or start (point-min))) + (p-max (or end (point-max))) + (r-end nil) + (ret (list))) + (while (not (= p-min p-max)) + (setq p-min (or (text-property-any p-min p-max property value) + (point-max)) + r-end (or (text-property-not-all p-min p-max property value) + (point-max)) + ret (append ret (unless (= p-min r-end) + (list(list p-min r-end)))) + p-min r-end)) + ret)) + +(provide 'space-doc) +;;; space-doc.el ends here. diff --git a/layers/+spacemacs/spacemacs-org/packages.el b/layers/+spacemacs/spacemacs-org/packages.el new file mode 100644 index 0000000..c8310f6 --- /dev/null +++ b/layers/+spacemacs/spacemacs-org/packages.el @@ -0,0 +1,80 @@ +;;; packages.el --- spacemacs-org layer packages file for Spacemacs. +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Boris Buliga +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;;; Commentary: + +;;; Code: + +(defconst spacemacs-org-packages + '( + flyspell + ;; default-org package does not exist, we invent this package name + ;; to allow the `org' layer to own the `org' package instead of this + ;; layer. So it is easier for users to steal the ownership of the + ;; `org' package. + (default-org-config :location built-in) + (org-plus-contrib :step pre) + org-bullets + (space-doc :location local) + toc-org + )) + +(defun spacemacs-org/post-init-flyspell () + (spell-checking/add-flyspell-hook 'org-mode-hook)) + +;; dummy init function to force installation of `org-plus-contrib' +(defun spacemacs-org/init-org-plus-contrib ()) + +(defun spacemacs-org/init-default-org-config () + (use-package org + :commands (org-clock-out org-occur-in-agenda-files org-agenda-files) + :defer t + :init + (progn + ;; FIXME: This check has been disabled pending a resolution of + ;; https://github.com/syl20bnr/spacemacs/issues/3933 + ;; (when (featurep 'org) + ;; (configuration-layer//set-error) + ;; (spacemacs-buffer/append + ;; (concat + ;; "Org features were loaded before the `org' layer initialized.\n" + ;; "Try removing org code from user initialization and private layers.") t)) + (setq org-startup-with-inline-images t + org-src-fontify-natively t + ;; this is consistent with the value of + ;; `helm-org-headings-max-depth'. + org-imenu-depth 8) + :config + (progn + (font-lock-add-keywords + 'org-mode '(("\\(@@html:@@\\) \\(.*\\) \\(@@html:@@\\)" + (1 font-lock-comment-face prepend) + (2 font-lock-function-name-face) + (3 font-lock-comment-face prepend)))) + ;; Open links and files with RET in normal state + (evil-define-key 'normal org-mode-map (kbd "RET") 'org-open-at-point))))) + +(defun spacemacs-org/init-org-bullets () + (use-package org-bullets + :defer t + :init (add-hook 'org-mode-hook 'org-bullets-mode))) + +(defun spacemacs-org/init-toc-org () + (use-package toc-org + :defer t + :init + (progn + (setq toc-org-max-depth 10) + (add-hook 'org-mode-hook 'toc-org-enable)))) + +(defun spacemacs-org/init-space-doc ()) + +;;; packages.el ends here diff --git a/layers/+spacemacs/spacemacs-ui-visual/config.el b/layers/+spacemacs/spacemacs-ui-visual/config.el new file mode 100644 index 0000000..068a7ca --- /dev/null +++ b/layers/+spacemacs/spacemacs-ui-visual/config.el @@ -0,0 +1,22 @@ +;;; config.el --- Spacemacs UI Visual Layer configuration File +;; +;; Copyright (c) 2016 Sylvain Benner & Contributors +;; +;; Author: Riccardo Murri +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defcustom spacemacs-spaceline-additional-segments + '((new-version :when active)) + "Additional segments for the Spacemacs modeline. + +They are inserted in the modeline between `global' and +`buffer-position'. + +Must be a list of valid segments; see `spaceline-install' for +more information on what constitutes a valid segment." + :type '(repeat sexp) + :group 'spacemacs) diff --git a/layers/+spacemacs/spacemacs-ui-visual/funcs.el b/layers/+spacemacs/spacemacs-ui-visual/funcs.el new file mode 100644 index 0000000..7389e05 --- /dev/null +++ b/layers/+spacemacs/spacemacs-ui-visual/funcs.el @@ -0,0 +1,187 @@ +;;; funcs.el --- Spacemacs Visual UI Layer functions File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + +;; golden ratio + +(defun spacemacs/no-golden-ratio-for-buffers (bufname) + "Disable golden-ratio if BUFNAME is the name of a visible buffer." + (and (get-buffer bufname) (get-buffer-window bufname 'visible))) + +(defun spacemacs/no-golden-ratio-guide-key () + "Disable golden-ratio for guide-key popwin buffer." + (or (spacemacs/no-golden-ratio-for-buffers " *guide-key*") + (spacemacs/no-golden-ratio-for-buffers " *popwin-dummy*"))) + + +;; neotree + +(defun spacemacs/neotree-expand-or-open () + "Expand or open a neotree node." + (interactive) + (let ((node (neo-buffer--get-filename-current-line))) + (when node + (if (file-directory-p node) + (progn + (neo-buffer--set-expand node t) + (neo-buffer--refresh t) + (when neo-auto-indent-point + (next-line) + (neo-point-auto-indent))) + (call-interactively 'neotree-enter))))) + +(defun spacemacs/neotree-collapse () + "Collapse a neotree node." + (interactive) + (let ((node (neo-buffer--get-filename-current-line))) + (when node + (when (file-directory-p node) + (neo-buffer--set-expand node nil) + (neo-buffer--refresh t)) + (when neo-auto-indent-point + (neo-point-auto-indent))))) + +(defun spacemacs/neotree-collapse-or-up () + "Collapse an expanded directory node or go to the parent node." + (interactive) + (let ((node (neo-buffer--get-filename-current-line))) + (when node + (if (file-directory-p node) + (if (neo-buffer--expanded-node-p node) + (spacemacs/neotree-collapse) + (neotree-select-up-node)) + (neotree-select-up-node))))) + +(defun neotree-find-project-root () + (interactive) + (if (neo-global--window-exists-p) + (neotree-hide) + (let ((origin-buffer-file-name (buffer-file-name))) + (neotree-find (projectile-project-root)) + (neotree-find origin-buffer-file-name)))) + +(defun spacemacs//neotree-maybe-attach-window () + (when (get-buffer-window (neo-global--get-buffer)) + (neo-global--attach))) + + +;; popwin + +(defun spacemacs/remove-popwin-display-config (str) + "Removes the popwin display configurations that matches the passed STR" + (setq popwin:special-display-config + (-remove (lambda (x) (if (and (listp x) (stringp (car x))) + (string-match str (car x)))) + popwin:special-display-config))) + + +;; smooth scrolling + +(defun spacemacs/enable-smooth-scrolling () + "Enable smooth scrolling." + (interactive) + (setq scroll-conservatively 101)) + +(defun spacemacs/disable-smooth-scrolling () + "Disable smooth scrolling." + (interactive) + (setq scroll-conservatively 0)) + + +;; spaceline + +(defun spacemacs/customize-powerline-faces () + "Alter powerline face to make them work with more themes." + (when (boundp 'powerline-inactive2) + (set-face-attribute 'powerline-inactive2 nil + :inherit 'font-lock-comment-face))) + +(defun spacemacs//evil-state-face () + (let ((state (if (eq 'operator evil-state) evil-previous-state evil-state))) + (intern (format "spacemacs-%S-face" state)))) + +(defun spacemacs//restore-powerline (buffer) + "Restore the powerline in buffer" + (with-current-buffer buffer + (setq-local mode-line-format (default-value 'mode-line-format)) + (powerline-set-selected-window) + (powerline-reset))) + +(defun spacemacs//set-powerline-for-startup-buffers () + "Set the powerline for buffers created when Emacs starts." + (dolist (buffer '("*Messages*" "*spacemacs*" "*Compile-Log*")) + (when (and (get-buffer buffer) + (configuration-layer/package-usedp 'spaceline)) + (spacemacs//restore-powerline buffer)))) + +(defun spacemacs//prepare-diminish () + (when spaceline-minor-modes-p + (let ((unicodep (dotspacemacs|symbol-value + dotspacemacs-mode-line-unicode-symbols))) + (setq spaceline-minor-modes-separator + (if unicodep (if (display-graphic-p) "" " ") "|")) + (dolist (mm spacemacs--diminished-minor-modes) + (let ((mode (car mm))) + (when (and (boundp mode) (symbol-value mode)) + (let* ((unicode (cadr mm)) + (ascii (caddr mm)) + (dim (if unicodep + unicode + (if ascii ascii unicode)))) + (diminish mode dim)))))))) + + +;; zoom + +(defun spacemacs//zoom-frm-powerline-reset () + (when (fboundp 'powerline-reset) + (setq-default powerline-height (spacemacs/compute-powerline-height)) + (powerline-reset))) + +(defun spacemacs//zoom-frm-do (arg) + "Perform a zoom action depending on ARG value." + (let ((zoom-action (cond ((eq arg 0) 'zoom-frm-unzoom) + ((< arg 0) 'zoom-frm-out) + ((> arg 0) 'zoom-frm-in))) + (fm (cdr (assoc 'fullscreen (frame-parameters)))) + (fwp (* (frame-char-width) (frame-width))) + (fhp (* (frame-char-height) (frame-height)))) + (when (equal fm 'maximized) + (toggle-frame-maximized)) + (funcall zoom-action) + (set-frame-size nil fwp fhp t) + (when (equal fm 'maximized) + (toggle-frame-maximized)))) + +(defun spacemacs/zoom-frm-in () + "zoom in frame, but keep the same pixel size" + (interactive) + (spacemacs//zoom-frm-do 1) + (spacemacs//zoom-frm-powerline-reset)) + +(defun spacemacs/zoom-frm-out () + "zoom out frame, but keep the same pixel size" + (interactive) + (spacemacs//zoom-frm-do -1) + (spacemacs//zoom-frm-powerline-reset)) + +(defun spacemacs/zoom-frm-unzoom () + "Unzoom current frame, keeping the same pixel size" + (interactive) + (spacemacs//zoom-frm-do 0) + (spacemacs//zoom-frm-powerline-reset)) + + +;; ansi-colors + +(defun spacemacs-ui-visual//compilation-buffer-apply-ansi-colors () + (let ((inhibit-read-only t)) + (ansi-color-apply-on-region compilation-filter-start (point-max)))) diff --git a/layers/+spacemacs/spacemacs-ui-visual/local/zoom-frm/frame-cmds.el b/layers/+spacemacs/spacemacs-ui-visual/local/zoom-frm/frame-cmds.el new file mode 100644 index 0000000..61810c6 --- /dev/null +++ b/layers/+spacemacs/spacemacs-ui-visual/local/zoom-frm/frame-cmds.el @@ -0,0 +1,1961 @@ +;;; frame-cmds.el --- Frame and window commands (interactive functions). +;; +;; Filename: frame-cmds.el +;; Description: Frame and window commands (interactive functions). +;; Author: Drew Adams +;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com") +;; Copyright (C) 1996-2015, Drew Adams, all rights reserved. +;; Created: Tue Mar 5 16:30:45 1996 +;; Version: 0 +;; Package-Requires: ((frame-fns "0")) +;; Last-Updated: Thu Jan 1 10:44:52 2015 (-0800) +;; By: dradams +;; Update #: 3036 +;; URL: http://www.emacswiki.org/frame-cmds.el +;; Doc URL: http://emacswiki.org/FrameModes +;; Doc URL: http://www.emacswiki.org/OneOnOneEmacs +;; Doc URL: http://www.emacswiki.org/Frame_Tiling_Commands +;; Keywords: internal, extensions, mouse, frames, windows, convenience +;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x, 24.x, 25.x +;; +;; Features that might be required by this library: +;; +;; `avoid', `frame-fns', `misc-fns', `strings', `thingatpt', +;; `thingatpt+'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; Frame and window commands (interactive functions). +;; +;; +;; Summary: +;; +;; Load this library from your init file (~/.emacs or _emacs). +;; Add the suggested key bindings (below) to your init file. +;; Use `M-up|down|left|right' to move frames around incrementally. +;; Use `C-S-v', `M-S-v', `C-S-next', `C-S-prior' to move frames to screen edges. +;; Use `C-M-up|down|left|right' to resize frames incrementally. +;; Use `C-M-z' or `C-x C-z' to iconify/hide all frames. +;; Use `C-M-z' in a lone frame to restore all frames. +;; Use `C-mouse-1' in the minibuffer to restore all frames. +;; Use `C-mouse-1' in Dired to mark/unmark a file. +;; Use `C-mouse-3' on the mode line to remove window from frame. +;; Use `tile-frames-horizontally', `-vertically' to tile frames. +;; Use `C-x o' to select `other-window' or `other-frame'. +;; +;; Commands to incrementally resize frames are `enlarge-frame' and +;; `enlarge-frame-horizontally'. Sarir Khamsi +;; [sarir.khamsi@raytheon.com] originally wrote `enlarge-frame', +;; which he called `sk-grow-frame'. +;; +;; Note on saving changes made with the commands defined here: +;; +;; Some of the commands defined here change frame properties. +;; You can save any changes you have made, by using Customize. +;; To visit a Customize buffer of all unsaved changes you have +;; made, use command `customize-customized'. +;; +;; Frame parameter changes, such as background color, can be saved +;; for future use by all frames or all frames of a certain +;; kind. For that, you must change the frame parameters of the +;; correponding frame-alist variable. +;; +;; There is no single variable for saving changes to parameters of +;; the current frame. Instead, there are several different +;; frame-alist variables, which you can use to define different +;; kinds of frames. These include: `default-frame-alist', +;; `initial-frame-alist', and `special-display-frame-alist'. The +;; complete list of such frame alist variables is available using +;; function `frame-alist-var-names', defined here. +;; +;; Example: Suppose you change the background color of a frame and +;; want to make that the default background color for new frames in +;; the future. You will need to update the value of variable +;; `default-frame-alist' to use the `background-color' parameter +;; setting of the changed frame. +;; +;; You can easily copy one or all parameter values from any given +;; frame to any frame alist (such as `default-frame-alist'), by +;; using the commands `set-frame-alist-parameter-from-frame' and +;; `set-all-frame-alist-parameters-from-frame'. Those commands are +;; defined here. +;; +;; NOTE: If you also use library `fit-frame.el', and you are on MS +;; Windows, then load that library before `frame-cmds.el'. The +;; commands `maximize-frame' and `restore-frame' defined here are +;; more general and non-Windows-specific than the commands of the +;; same name defined in `fit-frame.el'. +;; +;; +;; User options defined here: +;; +;; `available-screen-pixel-bounds', `enlarge-font-tries', +;; `frame-config-register', `frame-parameters-to-exclude', +;; `move-frame-wrap-within-display-flag' +;; `rename-frame-when-iconify-flag', `show-hide-show-function', +;; `window-mgr-title-bar-pixel-height'. +;; +;; Commands defined here: +;; +;; `create-frame-tiled-horizontally', +;; `create-frame-tiled-vertically', `delete-1-window-frames-on', +;; `delete/iconify-window', `delete/iconify-windows-on', +;; `delete-other-frames', `delete-windows-for', `enlarge-font', +;; `enlarge-frame', `enlarge-frame-horizontally', +;; `hide-everything', `hide-frame', `iconify-everything', +;; `iconify/map-frame', `iconify/show-frame', +;; `jump-to-frame-config-register', `maximize-frame', +;; `maximize-frame-horizontally', `maximize-frame-vertically', +;; `mouse-iconify/map-frame', `mouse-iconify/show-frame', +;; `mouse-remove-window', `mouse-show-hide-mark-unmark', +;; `move-frame-down', `move-frame-left', `move-frame-right', +;; `move-frame-to-screen-bottom', `move-frame-to-screen-left', +;; `move-frame-to-screen-right', `move-frame-to-screen-top', +;; `move-frame-to-screen-top-left', `move-frame-up', +;; `name-all-frames-numerically', `name-frame-numerically', +;; `other-window-or-frame', `remove-window', `remove-windows-on', +;; `rename-frame', `rename-non-minibuffer-frame', `restore-frame', +;; `restore-frame-horizontally', `restore-frame-vertically', +;; `save-frame-config', +;; `set-all-frame-alist-parameters-from-frame', +;; `set-frame-alist-parameter-from-frame', `show-*Help*-buffer', +;; `show-a-frame-on', `show-buffer-menu', `show-frame', +;; `show-hide', `shrink-frame', `shrink-frame-horizontally', +;; `split-frame-horizontally', `split-frame-vertically', +;; `tell-customize-var-has-changed', `tile-frames', +;; `tile-frames-horizontally', `tile-frames-side-by-side', +;; `tile-frames-top-to-bottom', `tile-frames-vertically', +;; `toggle-max-frame', `toggle-max-frame-horizontally', +;; `toggle-max-frame-vertically'. +;; +;; Non-interactive functions defined here: +;; +;; `assq-delete-all' (Emacs 20), `butlast' (Emacs 20), +;; `frcmds-available-screen-pixel-bounds', +;; `frcmds-available-screen-pixel-height', +;; `frcmds-available-screen-pixel-width', +;; `frcmds-effective-screen-pixel-bounds', +;; `frcmds-enlarged-font-name', `frcmds-extra-pixels-width', +;; `frcmds-extra-pixels-height', `frcmds-frame-alist-var-names', +;; `frcmds-frame-parameter-names', `frcmds-frame-iconified-p', +;; `frcmds-frame-number', `frcmds-new-frame-position', +;; `frcmds-read-args-for-tiling', +;; `frcmds-read-buffer-for-delete-windows', +;; `frcmds-set-difference', `frcmds-smart-tool-bar-pixel-height', +;; `frcmds-split-frame-1', `frcmds-tile-frames', `nbutlast' (Emacs +;; 20). +;; +;; Error symbols defined here: +;; +;; `font-too-small', `font-size'. +;; +;; +;; ***** NOTE: The following EMACS PRIMITIVE has been ADVISED HERE: +;; +;; `delete-window' - If only one window in frame, `delete-frame'. +;; +;; +;; ***** NOTE: The following EMACS PRIMITIVE has been REDEFINED HERE: +;; +;; `delete-windows-on' - +;; 1) Reads buffer differently. Only buffers showing windows are candidates. +;; 2) Calls `delete-window', so this also deletes frames where +;; window showing the BUFFER is the only window. +;; (That's true also for vanilla Emacs 23+, but not before.) +;; +;; +;; Suggested key bindings: +;; +;; (global-set-key [(meta up)] 'move-frame-up) +;; (global-set-key [(meta down)] 'move-frame-down) +;; (global-set-key [(meta left)] 'move-frame-left) +;; (global-set-key [(meta right)] 'move-frame-right) +;; (global-set-key [(meta shift ?v)] 'move-frame-to-screen-top) ; like `M-v' +;; (global-set-key [(control shift ?v)] 'move-frame-to-screen-bottom) ; like `C-v' +;; (global-set-key [(control shift prior)] 'move-frame-to-screen-left) ; like `C-prior' +;; (global-set-key [(control shift next)] 'move-frame-to-screen-right) ; like `C-next' +;; (global-set-key [(control shift home)] 'move-frame-to-screen-top-left) +;; (global-set-key [(control meta down)] 'enlarge-frame) +;; (global-set-key [(control meta right)] 'enlarge-frame-horizontally) +;; (global-set-key [(control meta up)] 'shrink-frame) +;; (global-set-key [(control meta left)] 'shrink-frame-horizontally) +;; (global-set-key [(control ?x) (control ?z)] 'iconify-everything) +;; (global-set-key [vertical-line S-down-mouse-1] 'iconify-everything) +;; (global-set-key [(control ?z)] 'iconify/show-frame) +;; (global-set-key [mode-line mouse-3] 'mouse-iconify/show-frame) +;; (global-set-key [mode-line C-mouse-3] 'mouse-remove-window) +;; (global-set-key [(control meta ?z)] 'show-hide) +;; (global-set-key [vertical-line C-down-mouse-1] 'show-hide) +;; (global-set-key [C-down-mouse-1] 'mouse-show-hide-mark-unmark) +;; (substitute-key-definition 'delete-window 'remove-window global-map) +;; (define-key ctl-x-map "o" 'other-window-or-frame) +;; (define-key ctl-x-4-map "1" 'delete-other-frames) +;; (define-key ctl-x-5-map "h" 'show-*Help*-buffer) +;; (substitute-key-definition 'delete-window 'delete-windows-for global-map) +;; (define-key global-map "\C-xt." 'save-frame-config) +;; (define-key ctl-x-map "o" 'other-window-or-frame) +;; +;; (defalias 'doremi-prefix (make-sparse-keymap)) +;; (defvar doremi-map (symbol-function 'doremi-prefix) "Keymap for Do Re Mi commands.") +;; (define-key global-map "\C-xt" 'doremi-prefix) +;; (define-key doremi-map "." 'save-frame-config) +;; +;; Customize the menu. Uncomment this to try it out. +;; +;; (defvar menu-bar-frames-menu (make-sparse-keymap "Frames")) +;; (define-key global-map [menu-bar frames] +;; (cons "Frames" menu-bar-frames-menu))) +;; (define-key menu-bar-frames-menu [set-all-params-from-frame] +;; '(menu-item "Set All Frame Parameters from Frame" set-all-frame-alist-parameters-from-frame +;; :help "Set frame parameters of a frame to their current values in frame")) +;; (define-key menu-bar-frames-menu [set-params-from-frame] +;; '(menu-item "Set Frame Parameter from Frame..." set-frame-alist-parameter-from-frame +;; :help "Set parameter of a frame alist to its current value in frame")) +;; (define-key menu-bar-frames-menu [separator-frame-1] '("--")) +;; (define-key menu-bar-frames-menu [tile-frames-vertically] +;; '(menu-item "Tile Frames Vertically..." tile-frames-vertically +;; :help "Tile all visible frames vertically")) +;; (define-key menu-bar-frames-menu [tile-frames-horizontally] +;; '(menu-item "Tile Frames Horizontally..." tile-frames-horizontally +;; :help "Tile all visible frames horizontally")) +;; (define-key menu-bar-frames-menu [separator-frame-2] '("--")) +;; (define-key menu-bar-frames-menu [toggle-max-frame-vertically] +;; '(menu-item "Toggle Max Frame Vertically" toggle-max-frame-vertically +;; :help "Maximize or restore the selected frame vertically" +;; :enable (frame-parameter nil 'restore-height))) +;; (define-key menu-bar-frames-menu [toggle-max-frame-horizontally] +;; '(menu-item "Toggle Max Frame Horizontally" toggle-max-frame-horizontally +;; :help "Maximize or restore the selected frame horizontally" +;; :enable (frame-parameter nil 'restore-width))) +;; (define-key menu-bar-frames-menu [toggle-max-frame] +;; '(menu-item "Toggle Max Frame" toggle-max-frame +;; :help "Maximize or restore the selected frame (in both directions)" +;; :enable (or (frame-parameter nil 'restore-width) (frame-parameter nil 'restore-height)))) +;; (define-key menu-bar-frames-menu [maximize-frame-vertically] +;; '(menu-item "Maximize Frame Vertically" maximize-frame-vertically +;; :help "Maximize the selected frame vertically")) +;; (define-key menu-bar-frames-menu [maximize-frame-horizontally] +;; '(menu-item "Maximize Frame Horizontally" maximize-frame-horizontally +;; :help "Maximize the selected frame horizontally")) +;; (define-key menu-bar-frames-menu [maximize-frame] +;; '(menu-item "Maximize Frame" maximize-frame +;; :help "Maximize the selected frame (in both directions)")) +;; (define-key menu-bar-frames-menu [separator-frame-3] '("--")) +;; (define-key menu-bar-frames-menu [iconify-everything] +;; '(menu-item "Iconify All Frames" iconify-everything +;; :help "Iconify all frames of session at once")) +;; (define-key menu-bar-frames-menu [show-hide] +;; '(menu-item "Hide Frames / Show Buffers" show-hide +;; :help "Show, if only one frame visible; else hide."))) +;; +;; (defvar menu-bar-doremi-menu (make-sparse-keymap "Do Re Mi")) +;; (define-key global-map [menu-bar doremi] +;; (cons "Do Re Mi" menu-bar-doremi-menu)) +;; (define-key menu-bar-doremi-menu [doremi-font+] +;; '("Save Frame Configuration" . save-frame-config)) +;; +;; See also these files for other frame commands: +;; +;; `autofit-frame.el' - Automatically fit each frame to its +;; selected window. Uses `fit-frame.el'. +;; +;; `fit-frame.el' - 1) Fit a frame to its selected window. +;; 2) Incrementally resize a frame. +;; +;; `doremi-frm.el' - Incrementally adjust frame properties +;; using arrow keys and/or mouse wheel. +;; +;; `thumb-frm.el' - Shrink frames to a thumbnail size and +;; restore them again. +;; +;; `zoom-frm.el' - Zoom a frame or buffer, so that its text +;; appears larger or smaller. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change Log: +;; +;; 2014/12/09 dadams +;; Added: frcmds-frame-pixel-height. +;; frcmds-split-frame-1: Use frame-pixel-width and frcmds-frame-pixel-height, instead of working +;; with width and height frame parameters (char-based). +;; frcmds-tile-frames: +;; If Emacs 24.4+, use PIXELWISE arg with set-frame-size. +;; Otherwise: * Always subtract frcmds-extra-pixels-width. +;; * Do not subtract borders. +;; * Increment origin by one border-width. +;; 2014/12/07 dadams +;; Added: split-frame-horizontally, split-frame-vertically. +;; frcmds-tile-frames: Added optional args, so can tile within a rectangle. +;; create-frame-tiled-(horizontally|vertically): Keep same font size. +;; 2014/12/06 dadams +;; Added: create-frame-tiled-horizontally, create-frame-tiled-vertically. +;; Added aliases: tile-frames-side-by-side, tile-frames-top-to-bottom. +;; window-mgr-title-bar-pixel-height: Changed default value for ns to 50. Thx to Nate Eagleson. +;; 2014/10/15 dadams +;; window-mgr-title-bar-pixel-height: Added default value for ns (Next). Thx to Nate Eagleson. +;; 2014/10/13 dadams +;; Removed extra, empty Package-Requires. +;; 2014/07/21 dadams +;; Do not redefine delete-window - just advise it. +;; delete/iconify-window: Just use delete-window, not old-delete-window. +;; 2014/04/19 dadams +;; Added: frcmds-frame-number, name-all-frames-numerically, name-frame-numerically. +;; Renamed: available-screen-pixel-* to frcmds-available-screen-pixel-*, +;; enlarged-font-name to frcmds-enlarged-font-name, +;; extra-pixels-* to frcmds-extra-pixels-*, +;; frame-alist-var-names to frcmds-frame-alist-var-names, +;; frame-parameter-names to frcmds-frame-parameter-names, +;; frame-iconified-p to frcmds-frame-iconified-p, +;; new-frame-position to frcmds-new-frame-position, +;; read-args-for-tile-frames to frcmds-read-args-for-tiling, +;; read-buffer-for-delete-windows to frcmds-read-buffer-for-delete-windows, +;; frame-cmds-set-difference to frcmds-set-difference, +;; smart-tool-bar-pixel-height to frcmds-smart-tool-bar-pixel-height, +;; tile-frames to frcmds-tile-frames. +;; rename-non-minibuffer-frame: Pass OLD-NAME and NEW-NAME to rename-frame. +;; Group Frame-Commands: Added :prefix frcmds-. +;; +;; 2014/02/24 dadams +;; rename-frame, rename-non-minibuffer-frame: Fixed default buffer name for non-interactive. +;; 2013/09/21 dadams +;; maximize-frame: Apply frame-geom-value-numeric to new-* also. Bug report thx: Mike Fitzgerald. +;; 2013/07/21 dadams +;; Added Package-Requires to header, at least temporarily, but should not need to specify version. +;; 2013/07/12 dadams +;; set-frame-alist-parameter-from-frame: Use lax completion, so do not limit to known parameters. +;; frame-parameter-names: Updated for Emacs 24. +;; 2013/07/05 dadams +;; Added: move-frame-to-screen-top-left. +;; move-frame-to-screen-*: Read FRAME name in interactive spec. +;; 2013/07/04 dadams +;; show-hide-show-function: Use function-item instead of const for jump-to-frame-config-register. +;; 2013/05/15 dadams +;; Added error symbols font-too-small and font-size. +;; enlarged-font-name: Signal font-too-small error. +;; 2013/04/29 dadams +;; Added: deiconify-everything, (mouse-)iconify/show-frame (renamed (mouse-)iconify/map-frame). +;; iconify/show-frame: Negative prefix arg now deiconifies all. +;; 2013/03/12 dadams +;; maximize-frame: Corrected new-left, new-top. +;; Corrected arg to modify-frame-parameters - use frame-geom-value-numeric +;; Do not alias if function name is already fboundp. +;; toggle-max-frame-*: Use toggle-max-frame, not restore-frame (the alias). +;; toggle-max-frame: If no restore-* parameter then first maximize. +;; Condition last four parameters on orig-*, not restore-*. +;; 2013/02/06 dadams +;; move-frame-(up|down|left|right): Set N to 1 if nil. +;; 2013/01/17 dadams +;; Added: move-frame-to-screen-(top|bottom|left|right). +;; move-frame-(up|down|left|right): Redefined so prefix arg moves increments of char size. +;; 2012/02/29 dadams +;; Added, for Emacs 20 only: nbutlast, butlast. To avoid runtime load of cl.el. +;; Added frame-cmds-set-difference, to avoid runtime load of cl.el. +;; set-all-frame-alist-parameters-from-frame: Use frame-cmds-set-difference. +;; 2011/07/25 dadams +;; save-frame-config: Use fboundp, not featurep. +;; 2011/01/04 dadams +;; Removed autoload cookie from non-interactive function. +;; 2010/10/19 dadams +;; enlarge-font: Only do frame-update-faces if Emacs 20 (obsolete in 21). +;; 2010/06/04 dadams +;; Added: (toggle-max|restore)-frame(-horizontally|-vertically). Thx to Uday Reddy for suggestion. +;; Renamed max-frame to maximize-frame. +;; maximize-frame: Save original location & position params for later restoration. +;; 2010/05/25 dadams +;; Added: max-frame, maximize-frame-horizontally, maximize-frame-vertically. +;; 2009/10/02 dadams +;; delete-windows-on: Return nil. Make BUFFER optional: default is current buffer. +;; 2009/08/03 dadams +;; delete-window: Wrap with save-current-buffer. Thx to Larry Denenberg. +;; 2009/05/17 dadams +;; Updated to reflect thumb-frm.el name changes. +;; 2009/01/30 dadams +;; enlarge-font, enlarged-font-name, enlarge-font-tries: +;; Removed temporary workaround - Emacs 23 bug #119 was finally fixed. +;; 2009/01/01 dadams +;; Removed compile-time require of doremi-frm.el to avoid infinite recursion. +;; 2008/12/13 dadams +;; enlarge-font: Redefined for Emacs 23 - just use :height face attribute. +;; enlarge-font-tries, enlarged-font-name: Not used for Emacs 23. +;; 2008/10/31 dadams +;; Updated frame-parameter-names for Emacs 23. +;; 2008/07/29 dadams +;; Option available-screen-pixel-bounds: Use nil as default value. +;; available-screen-pixel-bounds: Redefined as the code that defined the option's default value. +;; Added: effective-screen-pixel-bounds - code taken from old available-screen-pixel-bounds, +;; but also convert frame geom value to numeric. +;; Everywhere: +;; Use effective-screen-pixel-bounds in place of available-screen-pixel-bounds function. +;; Use available-screen-pixel-bounds function instead of option. +;; available-screen-pixel-(width|height): Added optional INCLUDE-MINI-P arg. +;; new-frame-position: Call available-screen-pixel-(width|height) with arg. +;; save-frame-config: push-current-frame-config -> doremi-push-current-frame-config. +;; Soft-require doremi-frm.el when byte-compile. +;; 2008/06/02 dadams +;; Added: available-screen-pixel-bounds (option and function). +;; tile-frames, available-screen-pixel-(width|height): +;; Redefined to use available-screen-pixel-bounds. Thx to Nathaniel Cunningham for input. +;; 2008/05/29 dadams +;; Fixes for Mac by Nathaniel Cunningham and David Reitter: +;; window-mgr-title-bar-pixel-height, tile-frames, smart-tool-bar-pixel-height (added). +;; 2007/12/27 dadams +;; tile-frames: Restored border calculation, but using only external border. +;; Renamed window-mgr-*-width to window-mgr-*-height and changed default value from 32 to 27. +;; 2007/12/20 dadams +;; Added: frame-extra-pixels(width|height). Use in tile-frames. Thx to David Reitter. +;; frame-horizontal-extra-pixels: Changed default value from 30 to 32. +;; 2007/10/11 dadams +;; Added: assq-delete-all (for Emacs 20). +;; 2007/09/02 dadams +;; Added: available-screen-pixel-(width|height). Use in tile-frames, new-frame-position. +;; 2007/06/12 dadams +;; tile-frames: Corrected use of fboundp for thumbnail-frame-p. +;; 2007/05/27 dadams +;; enlarged-font-name: +;; Do nothing if null assq of ascii. Not sure what this means, but gets around Emacs 23 bug. +;; 2006/08/22 dadams +;; Added: delete-windows-for, read-buffer-for-delete-windows. +;; delete-windows-on: Use read-buffer-for-delete-windows. +;; Removed old-delete-windows-on (not used). +;; 2006/05/30 dadams +;; delete-windows-on: Return nil if buffer arg is nil. Thanks to Slawomir Nowaczyk. +;; 2006/01/07 dadams +;; Added :link for sending bug report. +;; 2006/01/06 dadams +;; Renamed group. Added :link. +;; 2006/01/04 dadams +;; Added: other-window-or-frame. +;; 2005/12/29 dadams +;; mouse-show-hide-mark-unmark: dired-mouse-mark/unmark -> diredp-mouse-mark/unmark. +;; 2005/12/13 dadams +;; Added: delete-other-frames. +;; 2005/11/18 dadams +;; enlarge-font: Try to increment or decrment further, testing for an existing font. +;; Added: enlarge-font-tries, enlarged-font-name. +;; 2005/10/03 dadams +;; Removed require of icomplete+.el (no longer redefines read-from-minibuffer). +;; 2005/07/03 dadams +;; Renamed: args-for-tile-frames to read-args-for-tile-frames. +;; 2005/06/19 dadams +;; tile-frames: Don't tile thumbnail frames. +;; 2005/05/29 dadams +;; Moved here from frame+.el and fit-frame.el: enlarge-frame*, shrink-frame*. +;; Added: move-frame-up|down|left|right, move-frame-wrap-within-display-flag, +;; new-frame-position. +;; 2005/05/28 dadams +;; show-a-frame-on: Use another-buffer as default for read-buffer, if available. +;; 2005/05/15 dadams +;; Renamed: minibuffer-frame to 1on1-minibuffer-frame. +;; 2005/05/10 dadams +;; remove-window: Removed definition; just defalias it to delete-window. +;; delete-window: (one-window-p) -> (one-window-p t). +;; set-frame-alist-parameter-from-frame: No longer use destructive fns. +;; 2005/01/19 dadams +;; set-all-frame-alist-parameters-from-frame: +;; Added really-all-p and use frame-parameters-to-exclude. +;; Added: frame-parameters-to-exclude, tell-customize-var-has-changed. +;; 2005/01/18 dadams +;; Added: set-all-frame-alist-parameters-from-frame, set-frame-alist-parameter-from-frame, +;; frame-alist-var-names, frame-parameter-names. +;; Added Note on saving changes. +;; 2005/01/08 dadams +;; Moved enlarge-font here from doremi-frm.el, where it was called doremi-grow-font. +;; 2005/01/04 dadams +;; Added rename-frame-when-iconify-flag. +;; Use it in iconify-everything, (mouse-)iconify/map-frame. +;; Added (defgroup frame-cmds). +;; 2004/12/23 dadams +;; frame-config-register, show-hide-show-function, window-mgr-title-bar-pixel-width: +;; Changed defvar to defcustom. +;; 2004/12/21 dadams +;; hide-everything, iconify-everything: bind thumbify-instead-of-iconify-flag to nil. +;; 2004/12/10 dadams +;; tile-frames: Change 15 to (frame-char-height fr) for scroll-bar-width. +;; tile-frames-*: Corrected doc strings for non-interactive case. +;; 2004/12/09 dadams +;; Changed compile-time require of strings to a soft require. +;; 2004/10/11 dadams +;; args-for-tile-frames: Fixed bug when non-existant frame in name history. +;; tile-frames: show-frame at end (for case where use prefix arg) +;; 2004/09/11 dadams +;; Moved to doremi-frm.el: frame-config-ring*, frame-config-wo-parameters, +;; push-frame-config. +;; 2004/09/07 dadams +;; Added: jump-to-frame-config-register, push-frame-config, save-frame-config. +;; 2004/09/01 dadams +;; Added: frame-config-register, show-hide-show-function, +;; jump-to-frame-config-register. +;; Rewrote to record frame config: iconify-everything, hide-everything. +;; Rewrote to use show-hide-show-function: show-hide. +;; 2004/03/22 dadams +;; Added: tile-frames, tile-frames-vertically, args-for-tile-frames. +;; Rewrote tile-frames-horizontally to use tile-frames. +;; 2004/03/19 dadams +;; Added tile-frames-horizontally. +;; 2000/11/27 dadams +;; hide-frame: fixed bug: Added get-a-frame for frame name read. +;; 2000/09/27 dadams +;; 1. Added: frame-iconified-p. +;; 2. remove-window: only make-frame-invisible if not iconified (HACK). +;; 1999/10/05 dadams +;; rename-frame: fixed bug if only 1 frame and old-name was a frame. +;; 1999/08/25 dadams +;; Added: hide-everything, show-buffer-menu, show-hide. +;; 1999/03/17 dadams +;; delete-1-window-frames-on: ensure a buffer object (not a name). +;; 1996/04/26 dadams +;; delete/iconify-windows-on, show-a-frame-on: Do nothing if null buffer. +;; 1996/03/12 dadams +;; delete/iconify-window: Unless one-window-p, do old-delete-window outside of +;; save-window-excursion. +;; 1996/03/08 dadams +;; 1. delete-windows-on: a. Fixed incorrect interactive spec (bad paren). +;; b. Second arg FRAME also provided interactively now. +;; 2. Added: delete/iconify-window, delete/iconify-windows-on. +;; 1996/02/27 dadams +;; show-frame: Call make-frame-visible. +;; 1996/02/09 dadams +;; Added show-*Help*-buffer. +;; 1996/01/30 dadams +;; 1. show-frame: Don't make-frame-visible. Done by raise-frame anyway. +;; 2. Added show-a-frame-on. +;; 1996/01/09 dadams +;; Added delete-windows-on and made it interactive. +;; 1996/01/08 dadams +;; Added rename-non-minibuffer-frame. Use in iconify-everything, +;; iconify/map-frame, mouse-iconify/map-frame. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; 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 this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile (require 'cl)) ;; case, incf (plus, for Emacs 20: dolist, dotimes) +(require 'frame-fns) ;; frame-geom-value-cons, frame-geom-value-numeric, frames-on, get-frame-name, + ;; get-a-frame, read-frame +(require 'strings nil t) ;; (no error if not found) read-buffer +(require 'misc-fns nil t) ;; (no error if not found) another-buffer + +;; Don't require even to byte-compile, because doremi-frm.el soft-requires frame-cmds.el +;; (eval-when-compile (require 'doremi-frm nil t)) ;; (no error if not found) +;; ;; doremi-push-current-frame-config + +;; Not required here, because this library requires `frame-cmds.el': `thumb-frm.el'. +;; However, `frame-cmds.el' soft-uses `thumfr-thumbnail-frame-p', which is defined +;; in `thumb-frm.el'. + +;; Quiet byte-compiler. +(defvar 1on1-minibuffer-frame) ; In `oneonone.el' +(defvar mac-tool-bar-display-mode) + +;;;;;;;;;;;;;;;;;;;;;;; + + + + +;;; USER OPTIONS (VARIABLES) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defgroup Frame-Commands nil + "Miscellaneous frame and window commands." + :group 'frames + :prefix "frcmds-" + :link `(url-link :tag "Send Bug Report" + ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\ +frame-cmds.el bug: \ +&body=Describe bug here, starting with `emacs -q'. \ +Don't forget to mention your Emacs and library versions.")) + :link '(url-link :tag "Other Libraries by Drew" + "http://www.emacswiki.org/cgi-bin/wiki/DrewsElispLibraries") + :link '(url-link :tag "Download" + "http://www.emacswiki.org/cgi-bin/wiki/frame-cmds.el") + :link '(url-link :tag "Description - `delete-window'" + "http://www.emacswiki.org/cgi-bin/wiki/FrameModes") + :link '(url-link :tag "Description - Frame Renaming" + "http://www.emacswiki.org/cgi-bin/wiki/FrameTitle") + :link '(url-link :tag "Description - Frame Resizing" + "http://www.emacswiki.org/cgi-bin/wiki/Shrink-Wrapping_Frames") + :link '(url-link :tag "Description - Frame Customization" + "http://www.emacswiki.org/cgi-bin/wiki/CustomizingAndSaving") + :link '(url-link :tag "Description - Frame Tiling" + "http://www.emacswiki.org/cgi-bin/wiki/Frame_Tiling_Commands") + :link '(url-link :tag "Description - General" + "http://www.emacswiki.org/cgi-bin/wiki/FrameModes") + :link '(emacs-commentary-link :tag "Commentary" "frame-cmds")) + +(defcustom rename-frame-when-iconify-flag t + "*Non-nil means frames are renamed when iconified. +The new name is the name of the current buffer." + :type 'boolean :group 'Frame-Commands) + +(defcustom frame-config-register ?\C-l ; Control-L is the name of the register. + "*Character naming register for saving/restoring frame configuration." + :type 'character :group 'Frame-Commands) + +(defcustom show-hide-show-function 'jump-to-frame-config-register + "*Function to show stuff that is hidden or iconified by `show-hide'. +Candidates include `jump-to-frame-config-register' and `show-buffer-menu'." + :type '(choice (function-item :tag "Restore frame configuration" jump-to-frame-config-register) + (function :tag "Another function")) + :group 'Frame-Commands) + +;; Use `cond', not `case', for Emacs 20 byte-compiler. +(defcustom window-mgr-title-bar-pixel-height (cond ((eq window-system 'mac) 22) + ;; For older versions of OS X, 40 might be better. + ((eq window-system 'ns) 50) + (t 27)) + "*Height of frame title bar provided by the window manager, in pixels. +You might alternatively call this constant the title-bar \"width\" or +\"thickness\". There is no way for Emacs to determine this, so you +must set it." + :type 'integer :group 'Frame-Commands) + +(defcustom enlarge-font-tries 100 + "*Number of times to try to change font-size, when looking for a font. +The font-size portion of a font name is incremented or decremented at +most this many times, before giving up and raising an error." + :type 'integer :group 'Frame-Commands) + +(defcustom frame-parameters-to-exclude '((window-id) (buffer-list) (name) (title) (icon-name)) + "*Parameters to exclude in `set-all-frame-alist-parameters-from-frame'. +An alist of the same form as that returned by `frame-parameters'. +The cdr of each alist element is ignored. +These frame parameters are not copied to the target alist." + :type '(repeat (cons symbol sexp)) :group 'Frame-Commands) + +(defcustom move-frame-wrap-within-display-flag t + "*Non-nil means wrap frame movements within the display. +Commands `move-frame-up', `move-frame-down', `move-frame-left', and +`move-frame-right' then move the frame back onto the display when it +moves off of it. +If nil, you can move the frame as far off the display as you like." + :type 'boolean :group 'Frame-Commands) + +(defcustom available-screen-pixel-bounds nil + "*Upper left and lower right of available screen space for tiling frames. +Integer list: (x0 y0 x1 y1), where (x0, y0) is the upper left position +and (x1, y1) is the lower right position. Coordinates are in pixels, +measured from the screen absolute origin, (0, 0), at the upper left. + +If this is nil, then the available space is calculated. That should +give good results in most cases." + :type '(list + (integer :tag "X0 (upper left) - pixels from screen left") + (integer :tag "Y0 (upper left) - pixels from screen top") + (integer :tag "X1 (lower right) - pixels from screen left" ) + (integer :tag "Y1 (lower right) - pixels from screen top")) + :group 'Frame-Commands) + + + +;;; FUNCTIONS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +;;;###autoload +(defun save-frame-config () + "Save current frame configuration. +You can restore it with \\[jump-to-frame-config-register]." + (interactive) + (frame-configuration-to-register frame-config-register) + (when (fboundp 'doremi-push-current-frame-config) ; In `doremi-frm.el'. + (doremi-push-current-frame-config)) + (message + (substitute-command-keys + (if (fboundp 'doremi-frame-configs) ; In `doremi-frm.el'. + (format "Use `\\[jump-to-frame-config-register]' (`C-x r j %c') or \ +`\\[doremi-frame-configs]' to restore frames as before (undo)." frame-config-register) + "Use `\\[jump-to-frame-config-register]' to restore frames as before (undo).")))) + +;;;###autoload +(defun jump-to-frame-config-register () + "Restore frame configuration saved in `frame-config-register'." + (interactive) + (jump-to-register frame-config-register)) + +;;;###autoload +(defun deiconify-everything () + "Deiconify any iconified frames." + (interactive) + (frame-configuration-to-register frame-config-register) + (dolist (frame (frame-list)) + (when (eq 'icon (frame-visible-p frame)) (make-frame-visible frame)))) + +;;;###autoload +(defun iconify-everything () + "Iconify all frames of session at once. +Remembers frame configuration in register `C-l' (Control-L). +To restore this frame configuration, use `\\[jump-to-register] C-l'." + (interactive) + (frame-configuration-to-register frame-config-register) + (let ((thumfr-thumbify-dont-iconify-flag nil)) ; Defined in `thumb-frm.el'. + (dolist (frame (visible-frame-list)) + (when rename-frame-when-iconify-flag (rename-non-minibuffer-frame frame)) + (iconify-frame frame)))) + +;;;###autoload +(defun hide-everything () + "Hide all frames of session at once. +Iconify minibuffer frame; make all others invisible. +Remembers frame configuration in register `C-l' (Control-L). +To restore this frame configuration, use `\\[jump-to-register] C-l'." + (interactive) + (frame-configuration-to-register frame-config-register) + (let ((minibuf-frame-name (and (boundp '1on1-minibuffer-frame) + (cdr (assq 'name (frame-parameters + 1on1-minibuffer-frame))))) + (thumfr-thumbify-dont-iconify-flag nil)) ; Defined in `thumb-frm.el'. + (dolist (frame (frame-list)) + (if (eq minibuf-frame-name (cdr (assq 'name (frame-parameters frame)))) + (iconify-frame frame) ; minibuffer frame + (make-frame-invisible frame t))))) ; other frames + +;;;###autoload +(defun show-hide () + "1 frame visible: `show-hide-show-function'; else: `hide-everything'. +This acts as a toggle between showing all frames and showing only an +iconified minibuffer frame." + (interactive) + (if (< (length (visible-frame-list)) 2) (funcall show-hide-show-function) (hide-everything))) + +;;;###autoload +(defun show-buffer-menu () + "Call `buffer-menu' after making all frames visible. +Useful after using `hide-everything' because of a Windows bug that +doesn't let you display frames that have been made visible after +being made invisible." + (interactive) + (let ((minibuf-frame-name (and (boundp '1on1-minibuffer-frame) + (cdr (assq 'name (frame-parameters 1on1-minibuffer-frame)))))) + (dolist (frame (frame-list)) + (if (eq minibuf-frame-name (cdr (assq 'name (frame-parameters frame)))) + (make-frame-visible frame) ; minibuffer frame + (iconify-frame frame))) ; other frames + (buffer-menu))) + +;;;###autoload +(defun mouse-show-hide-mark-unmark (event) + "In minibuffer: `show-hide'. In dired: mark/unmark; else: buffer menu." + (interactive "e") + (if (window-minibuffer-p (posn-window (event-start event))) + (show-hide) + (or (and (memq major-mode '(dired-mode vc-dired-mode)) + (fboundp 'diredp-mouse-mark/unmark) + (diredp-mouse-mark/unmark event)) ; Return nil if not on a file or dir. + (mouse-buffer-menu event)))) + +;;;###autoload +(defalias 'iconify/map-frame 'iconify/show-frame) ; `.../map...' is the old name. +;;;###autoload +(defun iconify/show-frame (&optional all-action) + "Iconify selected frame if now shown. Show it if now iconified. +A non-negative prefix arg iconifies all shown frames. +A negative prefix arg deiconifies all iconified frames." + (interactive "P") + (cond ((not all-action) + (when rename-frame-when-iconify-flag (rename-non-minibuffer-frame)) + (iconify-or-deiconify-frame)) + ((natnump (prefix-numeric-value all-action)) + (iconify-everything)) + (t + (deiconify-everything)))) + +;;;###autoload +(defalias 'mouse-iconify/map-frame 'mouse-iconify/show-frame) ; `.../map...' is the old name. +;;;###autoload +(defun mouse-iconify/show-frame (event) + "Iconify frame you click, if now shown. Show it if now iconified." + (interactive "e") + (select-window (posn-window (event-start event))) + (when rename-frame-when-iconify-flag (rename-non-minibuffer-frame)) + (iconify-or-deiconify-frame)) + + + +;; ADVISE ORIGINAL (built-in): +;; +;; If WINDOW is the only one in its frame, `delete-frame'. +(defadvice delete-window (around delete-frame-if-one-win activate) + "If WINDOW is the only one in its frame, then `delete-frame' too." + (save-current-buffer + (select-window (or (ad-get-arg 0) (selected-window))) + (if (one-window-p t) (delete-frame) ad-do-it))) + +;;;###autoload +(defun delete-windows-for (&optional buffer) + "`delete-window' or prompt for buffer and delete its windows. +With no prefix arg, delete the selected window. +With a prefix arg, prompt for a buffer and delete all windows, on any + frame, that show that buffer." + (interactive (list (and current-prefix-arg (frcmds-read-buffer-for-delete-windows)))) + (if buffer (delete-windows-on buffer) (delete-window))) + + + +;; REPLACES ORIGINAL (built-in): +;; +;; 1) Use `read-buffer' in interactive spec. +;; 2) Do not raise an error if BUFFER is a string that does not name a buffer. +;; 3) Call `delete-window', so if you use the advised `delete-window' here then this also deletes +;; frames where window showing the BUFFER is the only window. +;; +;;;###autoload +(defun delete-windows-on (&optional buffer frame) + "Delete windows showing BUFFER. +Optional arg BUFFER defaults to the current buffer. + +Optional second arg FRAME controls which frames are considered. + If nil or omitted, delete all windows showing BUFFER in any frame. + If t, delete only windows showing BUFFER in the selected frame. + If `visible', delete all windows showing BUFFER in any visible frame. + If a frame, delete only windows showing BUFFER in that frame. + +Interactively, FRAME depends on the prefix arg, as follows: + Without a prefix arg (prefix = nil), FRAME is nil (all frames). + With prefix arg >= 0, FRAME is t (this frame only). + With prefix arg < 0, FRAME is `visible' (all visible frames)." + (interactive + (list (frcmds-read-buffer-for-delete-windows) + (and current-prefix-arg + (or (natnump (prefix-numeric-value current-prefix-arg)) 'visible)))) + (unless buffer (setq buffer (current-buffer))) ; Like Emacs 23+ - unlike Emacs 21-22. + + ;; `get-buffer-window' interprets FRAME oppositely for t and nil, so switch. + (setq frame (if (eq t frame) nil (if (eq nil frame) t frame))) + (let (win) + ;; Vanilla Emacs version raises an error if BUFFER is a string that does not name a buffer. + ;; We do not raise an error - we do nothing. + (and (get-buffer buffer) + (while (setq win (get-buffer-window buffer frame)) (delete-window win)) + nil))) ; Return nil always, like vanilla Emacs. + +(defun frcmds-read-buffer-for-delete-windows () + "Read buffer name for delete-windows commands. +Only displayed buffers are completion candidates." + (completing-read "Delete windows on buffer: " + (let ((all-bufs (buffer-list)) + (cand-bufs ())) + (dolist (buf all-bufs) + (when (get-buffer-window buf t) + (push (list (buffer-name buf)) cand-bufs))) + cand-bufs) + nil t nil 'minibuffer-history (buffer-name (current-buffer)) t)) + +(defsubst frcmds-frame-iconified-p (frame) + "Return non-nil if FRAME is `frame-live-p' and `frame-visible-p'." + (and (frame-live-p frame) (eq (frame-visible-p frame) 'icon))) + +;; (defun remove-window (&optional window) +;; "Remove WINDOW from the display. Default is `selected-window'. +;; If WINDOW is the only one in its frame, then: +;; If WINDOW is dedicated to its buffer, then make its frame invisible. +;; Otherwise, delete its frame (as well as the window)." +;; (interactive) +;; (setq window (or window (selected-window))) +;; (select-window window) +;; (if (and (window-dedicated-p (selected-window)) +;; (one-window-p t)) +;; (let ((fr (selected-frame))) +;; ;; HACK because of Emacs bug: `raise-frame' won't raise a frame +;; ;; that was first iconified and then made invisible. +;; ;; So, here we don't make an iconified frame invisible. +;; (unless (frcmds-frame-iconified-p fr) +;; (make-frame-invisible fr))) +;; (delete-window))) + +;; REMOVED old definition, above, because of problems with invisible +;; *Completions* frame when use completion window with subsequent args +;; to a command. Just use `delete-window' now, which deletes frame if +;; `one-window-p'. Use a `defalias' because its easier than replacing +;; all my calls to `remove-window' with `delete-window'. +;; +;;;###autoload +(defalias 'remove-window 'delete-window) + +;;;###autoload +(defun remove-windows-on (buffer) + "Remove all windows showing BUFFER. This calls `remove-window' +on each window showing BUFFER." + (interactive + (list (read-buffer "Remove all windows showing buffer: " (current-buffer) 'existing))) + (setq buffer (get-buffer buffer)) ; Convert to buffer. + (when buffer ; Do nothing if null BUFFER. + (dolist (fr (frames-on buffer t)) + (remove-window (get-buffer-window buffer t))))) + +;;;###autoload +(defun mouse-remove-window (event) + "Remove the window you click on. (This calls `remove-window'.) +This command must be bound to a mouse click." + (interactive "e") + (mouse-minibuffer-check event) + (remove-window (posn-window (event-start event)))) + +;;;###autoload +(defun delete/iconify-window (&optional window frame-p) + "Delete or iconify WINDOW (default: `selected-window'). +If WINDOW is the only one in its frame (`one-window-p'), then optional +arg FRAME-P determines the behavior regarding the frame, as follows: + If FRAME-P is nil, then the frame is deleted (with the window). + If FRAME-P is t, then the frame is iconified. + If FRAME-P is a symbol naming a function, the function is applied + to WINDOW as its only arg. + If the result is nil, then the frame is deleted. + If the result is non-nil, then the frame is iconified. + If FRAME-P is anything else, then behavior is as if FRAME-P were the + symbol `window-dedicated-p': the frame is iconified if + WINDOW is dedicated, otherwise the frame is deleted. + +Interactively, FRAME-P depends on the prefix arg, as follows: + Without a prefix arg (prefix = nil), FRAME-P is `window-dedicated-p'. + With prefix arg < 0, FRAME-P is t. The frame is iconified. + With prefix arg >= 0, FRAME-P is nil. The frame is deleted." + (interactive + (list nil (if current-prefix-arg + (not (natnump (prefix-numeric-value current-prefix-arg))) + 'window-dedicated-p))) + (setq window (or window (selected-window))) + (let ((one-win-p t)) + (save-window-excursion + (select-window window) + (if (one-window-p) + (if frame-p + (if (eq t frame-p) + (iconify-frame) + (unless (and (symbolp frame-p) (fboundp frame-p)) + (setq frame-p 'window-dedicated-p)) + (if (funcall frame-p window) (iconify-frame) (delete-frame))) + (delete-frame)) ; Default. + (setq one-win-p nil))) + ;; Do this outside `save-window-excursion'. + (unless one-win-p (delete-window window)))) + +;;;###autoload +(defun delete/iconify-windows-on (buffer &optional frame frame-p) + "For each window showing BUFFER: delete it or iconify its frame. +\(This calls `delete/iconify-window' on each window showing BUFFER.) + +Optional second arg FRAME controls which frames are considered. + If nil or omitted, treat all windows showing BUFFER in any frame. + If t, treat only windows showing BUFFER in the selected frame. + If `visible', treat all windows showing BUFFER in any visible frame. + If a frame, treat only windows showing BUFFER in that frame. + +Optional third arg FRAME-P controls what to do with one-window frames. + If FRAME-P is nil, then one-window frames showing BUFFER are deleted. + If FRAME-P is t, then one-window frames are iconified. + If FRAME-P is a symbol naming a function, the function is applied + to each window showing buffer in a frame by itself. + If the result is nil, then the frame is deleted. + If the result is non-nil, then the frame is iconified. + If FRAME-P is anything else, then behavior is as if FRAME-P were the + symbol `window-dedicated-p': One-window frames are + iconified if window is dedicated, else they are deleted. + +Interactively, FRAME is nil, and FRAME-P depends on the prefix arg: + Without a prefix arg (prefix = nil), FRAME-P is `window-dedicated-p'. + With prefix arg < 0, FRAME-P is t. The frame is iconified. + With prefix arg >= 0, FRAME-P is nil. The frame is deleted." + (interactive + (list (read-buffer "Delete windows on buffer: " (current-buffer) 'existing) + nil + (if current-prefix-arg + (not (natnump (prefix-numeric-value current-prefix-arg))) + 'window-dedicated-p))) + (setq buffer (get-buffer buffer)) ; Convert to buffer. + (when buffer ; Do nothing if null BUFFER. + ;; `get-buffer-window' interprets FRAME oppositely for t and nil, + ;; so switch. + (setq frame (if (eq t frame) nil (if (eq nil frame) t frame))) + (dolist (fr (frames-on buffer frame)) + (delete/iconify-window (get-buffer-window buffer frame) frame-p)))) + +;;;###autoload +(defun rename-frame (&optional old-name new-name all-named) + "Rename a frame named OLD-NAME to NEW-NAME. +Prefix arg non-nil means rename all frames named OLD-NAME to NEWNAME. +OLD-NAME may be a frame, its name, or nil. Default is `selected-frame'. +NEW-NAME is a string or nil. Default NEW-NAME is current `buffer-name'." + (interactive + (list (read-frame (concat "Rename " (and current-prefix-arg "all ") + "frame" (and current-prefix-arg "s named") ": ") + nil t) ; Default = selected. Must exist. + (read-from-minibuffer "Rename to (new name): " (cons (buffer-name) 1)) + current-prefix-arg)) + (setq old-name (or old-name (get-frame-name)) ; Batch defaults from current. + new-name (or new-name (buffer-name (window-buffer (frame-selected-window))))) + ;; Convert to frame if string. + (let ((fr (get-a-frame old-name))) + (if all-named + (while fr + (modify-frame-parameters fr (list (cons 'name new-name))) + (setq fr (get-a-frame old-name))) ; Get another. + (when (string= (get-frame-name fr) (get-frame-name)) + (setq fr (selected-frame))) + (modify-frame-parameters fr (list (cons 'name new-name)))))) + +;;;###autoload +(defun rename-non-minibuffer-frame (&optional old-name new-name all-named) + "Unless OLD-NAME names the minibuffer frame, use `rename-frame' +to rename a frame named OLD-NAME to NEW-NAME. +Prefix arg non-nil means rename all frames named OLD-NAME to NEW-NAME. +OLD-NAME may be a frame, its name, or nil. Default is `selected-frame'. +NEW-NAME is a string or nil. Default NEW-NAME is current `buffer-name'." + (interactive + (list (read-frame (concat "Rename " (and current-prefix-arg "all ") + "frame" (and current-prefix-arg "s named") ": ") + nil t) ; Default = selected. Must exist. + (read-from-minibuffer "Rename to (new name): " (cons (buffer-name) 1)) + current-prefix-arg)) + (setq old-name (or old-name (get-frame-name)) ; Batch defaults from current. + new-name (or new-name (buffer-name (window-buffer (frame-selected-window))))) + (let ((fr (get-a-frame old-name))) ; Convert to frame if string. + (if (and (boundp '1on1-minibuffer-frame) + (eq (cdr (assq 'name (frame-parameters 1on1-minibuffer-frame))) + (cdr (assq 'name (frame-parameters fr))))) + (and (interactive-p) + (error "Use `rename-frame' if you really want to rename minibuffer frame")) + (rename-frame old-name new-name)))) + +;;;###autoload +(defun name-all-frames-numerically (&optional startover) + "Rename all frames to numerals in 1,2,3... +With optional arg STARTOVER (prefix arg, interactively), rename all +starting over from 1. Otherwise, numbering continues from the highest +existing frame number." + (interactive "P") + (when startover + (dolist (fr (frame-list)) + (rename-non-minibuffer-frame fr (format "a%s" (frame-parameter fr 'name))))) + (mapc #'name-frame-numerically (frame-list))) + +;;;###autoload +(defun name-frame-numerically (&optional frame frames) + "Name FRAME (default, selected frame) to a numeral in 1,2,3... +If FRAME's name is already such a numeral, do nothing. +Else: + Rename it to a numeral one greater than the max numeric frame name. + Rename any other frames to numerals also. + +To automatically name new frames numerically, you can do this in your +init file: + + (add-hook 'after-make-frame-functions 'name-frame-numerically)" + (interactive) + (setq frame (or frame (selected-frame)) + frames (or frames (list frame))) + (let ((onum (frcmds-frame-number frame)) + onums max) + (unless onum + (dolist (fr (frcmds-set-difference (frame-list) frames)) + (unless (eq fr frame) + (name-frame-numerically fr (cons fr frames)))) + (setq onums (delq nil (mapcar #'frcmds-frame-number (frame-list))) + max (if onums (apply #'max onums) 0)) + (rename-non-minibuffer-frame frame (number-to-string (1+ max)))))) + +(defun frcmds-frame-number (frame) + "Return FRAME's number, or nil if its name is not a numeral 1,2,3..." + (let ((num (string-to-number (frame-parameter frame 'name)))) + (and (wholenump num) (not (zerop num)) num))) + +;;;###autoload +(defun show-frame (frame) + "Make FRAME visible and raise it, without selecting it. +FRAME may be a frame or its name." + (interactive (list (read-frame "Frame to make visible: "))) + (setq frame (get-a-frame frame)) + (make-frame-visible frame) + (raise-frame frame)) + +;;;###autoload +(defun hide-frame (frame &optional prefix) + "Make FRAME invisible. Like `make-frame-invisible', but reads frame name. +Non-nil PREFIX makes it invisible even if all other frames are invisible." + (interactive (list (read-frame "Frame to make invisible: "))) + (make-frame-invisible (get-a-frame frame) prefix)) + +;;;###autoload +(defun show-a-frame-on (buffer) + "Make visible and raise a frame showing BUFFER, if there is one. +Neither the frame nor the BUFFER are selected. +BUFFER may be a buffer or its name (a string)." + (interactive + (list (read-buffer "Show a frame showing buffer: " + (if (fboundp 'another-buffer) ; Defined in `misc-fns.el'. + (another-buffer nil t) + (other-buffer (current-buffer))) + 'existing))) + (when buffer ; Do nothing if null BUFFER. + (let ((fr (car (frames-on buffer)))) (when fr (show-frame fr))))) + +;;;###autoload +(defun show-*Help*-buffer () + "Raise a frame showing buffer *Help*, without selecting it." + (interactive) (show-a-frame-on "*Help*")) + +;;;###autoload +(defun delete-1-window-frames-on (buffer) + "Delete all visible 1-window frames showing BUFFER." + (interactive + (list (read-buffer "Delete all visible 1-window frames showing buffer: " + (current-buffer) 'existing))) + (setq buffer (get-buffer buffer)) + (save-excursion + (when (buffer-live-p buffer) ; Do nothing if dead buffer. + (dolist (fr (frames-on buffer)) ; Is it better to search through + (save-window-excursion ; `frames-on' or `get-buffer-window-list'? + (select-frame fr) + (when (one-window-p t fr) (delete-frame))))))) + +;;;###autoload +(defun delete-other-frames (&optional frame) + "Delete all frames except FRAME (default: selected frame). +Interactively, use a prefix arg (`\\[universal-argument]') to be prompted for FRAME." + (interactive (list (if current-prefix-arg + (get-a-frame (read-frame "Frame to make invisible: ")) + (selected-frame)))) + (when frame + (dolist (fr (frame-list)) + (unless (eq fr frame) (condition-case nil (delete-frame fr) (error nil)))))) + +;;;###autoload +(defun maximize-frame-horizontally (&optional frame) + "Maximize selected frame horizontally." + (interactive (list (selected-frame))) + (maximize-frame 'horizontal frame)) + +;;;###autoload +(defun maximize-frame-vertically (&optional frame) + "Maximize selected frame vertically." + (interactive (list (selected-frame))) + (maximize-frame 'vertical frame)) + +;;;###autoload +(defun maximize-frame (&optional direction frame) + "Maximize selected frame horizontally, vertically, or both. +With no prefix arg, maximize both directions. +With a non-negative prefix arg, maximize vertically. +With a negative prefix arg, maximize horizontally. + +In Lisp code: + DIRECTION is the direction: `horizontal', `vertical', or `both'. + FRAME is the frame to maximize." + (interactive (list (if current-prefix-arg + (if (natnump (prefix-numeric-value current-prefix-arg)) + 'vertical + 'horizontal) + 'both))) + (unless frame (setq frame (selected-frame))) + (unless direction (setq direction 'both)) + (let (;; Size of a frame that uses all of the available screen area, + ;; but leaving room for a minibuffer frame at bottom of display. + (fr-pixel-width (frcmds-available-screen-pixel-width)) + (fr-pixel-height (frcmds-available-screen-pixel-height)) + (fr-origin (if (eq direction 'horizontal) + (car (frcmds-effective-screen-pixel-bounds)) + (cadr (frcmds-effective-screen-pixel-bounds)))) + (orig-left (frame-parameter frame 'left)) + (orig-top (frame-parameter frame 'top)) + (orig-width (frame-parameter frame 'width)) + (orig-height (frame-parameter frame 'height))) + (let* ((borders (* 2 (cdr (assq 'border-width (frame-parameters frame))))) + (new-left (if (memq direction '(horizontal both)) 0 orig-left)) + (new-top (if (memq direction '(vertical both)) 0 orig-top)) + ;; Subtract borders, scroll bars, & title bar, then convert pixel sizes to char sizes. + (new-width (if (memq direction '(horizontal both)) + (/ (- fr-pixel-width borders (frcmds-extra-pixels-width frame)) + (frame-char-width frame)) + orig-width)) + (new-height (if (memq direction '(vertical both)) + (- (/ (- fr-pixel-height borders + (frcmds-extra-pixels-height frame) + window-mgr-title-bar-pixel-height + (frcmds-smart-tool-bar-pixel-height)) + (frame-char-height frame)) + ;; Subtract menu bar unless on Carbon Emacs (menu bar not in the frame). + (if (eq window-system 'mac) + 0 + (cdr (assq 'menu-bar-lines (frame-parameters frame))))) + orig-height))) + (modify-frame-parameters + frame + `((left . ,new-left) + (width . ,new-width) + (top . ,new-top) + (height . ,new-height) + ;; If we actually changed a parameter, record the old one for restoration. + ,(and new-left (/= (frame-geom-value-numeric 'left orig-left) + (frame-geom-value-numeric 'left new-left)) + (cons 'restore-left orig-left)) + ,(and new-top (/= (frame-geom-value-numeric 'top orig-top) + (frame-geom-value-numeric 'top new-top)) + (cons 'restore-top orig-top)) + ,(and new-width (/= (frame-geom-value-numeric 'width orig-width) + (frame-geom-value-numeric 'width new-width)) + (cons 'restore-width orig-width)) + ,(and new-height (/= (frame-geom-value-numeric 'height orig-height) + (frame-geom-value-numeric 'height new-height)) + (cons 'restore-height orig-height))))) + (show-frame frame) + (incf fr-origin (if (eq direction 'horizontal) fr-pixel-width fr-pixel-height)))) + +;;;###autoload +(unless (fboundp 'restore-frame-horizontally) + (defalias 'restore-frame-horizontally 'toggle-max-frame-horizontally)) +;;;###autoload +(defun toggle-max-frame-horizontally (&optional frame) + "Toggle maximization of FRAME horizontally. +If used once, this restores the frame. If repeated, it maximizes. +This affects the `left' and `width' frame parameters. + +FRAME defaults to the selected frame." + (interactive (list (selected-frame))) + (toggle-max-frame 'horizontal frame)) + +;;;###autoload +(unless (fboundp 'restore-frame-vertically) + (defalias 'restore-frame-vertically 'toggle-max-frame-vertically)) +;;;###autoload +(defun toggle-max-frame-vertically (&optional frame) + "Toggle maximization of FRAME vertically. +If used once, this restores the frame. If repeated, it maximizes. +This affects the `top' and `height' frame parameters. + +FRAME defaults to the selected frame." + (interactive (list (selected-frame))) + (toggle-max-frame 'vertical frame)) + +;;;###autoload +(unless (fboundp 'restore-frame) (defalias 'restore-frame 'toggle-max-frame)) +;;;###autoload +(defun toggle-max-frame (&optional direction frame) + "Toggle maximization of FRAME horizontally, vertically, or both. +Reverses or (if restored) repeats the effect of the Emacs maximize +commands. Does not restore from maximization effected outside Emacs. + +With no prefix arg, toggle both directions. +With a non-negative prefix arg, toggle only vertically. +With a negative prefix arg, toggle horizontally. + +When toggling both directions, each is toggled from its last maximize +or restore state. This means that using this after +`maximize-frame-horizontally', `maximize-frame-vertically', +`toggle-max-frame-horizontally', or `toggle-max-frame-vertically' does +not necessarily just reverse the effect of that command. + +In Lisp code: + DIRECTION is the direction: `horizontal', `vertical', or `both'. + FRAME is the frame to change. It defaults to the selected frame." + (interactive (list (if current-prefix-arg + (if (natnump (prefix-numeric-value current-prefix-arg)) + 'vertical + 'horizontal) + 'both))) + (unless frame (setq frame (selected-frame))) + (unless direction (setq direction 'both)) + (let ((restore-left (frame-parameter frame 'restore-left)) + (restore-top (frame-parameter frame 'restore-top)) + (restore-width (frame-parameter frame 'restore-width)) + (restore-height (frame-parameter frame 'restore-height)) + (orig-left (frame-parameter frame 'left)) + (orig-top (frame-parameter frame 'top)) + (orig-width (frame-parameter frame 'width)) + (orig-height (frame-parameter frame 'height)) + (horiz (memq direction '(horizontal both))) + (vert (memq direction '(vertical both)))) + (case direction + (both (unless (and restore-left restore-width restore-top restore-height) + (maximize-frame 'both frame))) + (vertical (unless (and restore-top restore-height) (maximize-frame-vertically frame))) + (horizontal (unless (and restore-left restore-width) (maximize-frame-horizontally frame)))) + (modify-frame-parameters + frame `(,(and horiz restore-left (cons 'left restore-left)) + ,(and horiz restore-width (cons 'width restore-width)) + ,(and vert restore-top (cons 'top restore-top)) + ,(and vert restore-height (cons 'height restore-height)) + ,(and horiz orig-left (cons 'restore-left orig-left)) + ,(and horiz orig-width (cons 'restore-width orig-width)) + ,(and vert orig-top (cons 'restore-top orig-top)) + ,(and vert orig-height (cons 'restore-height orig-height))))) + (show-frame frame)) + +;;;###autoload +(defalias 'tile-frames-side-by-side 'tile-frames-horizontally) +;;;###autoload +(defun tile-frames-horizontally (&optional frames) + "Tile frames horizontally (side by side). +Interactively: + With prefix arg, you are prompted for names of two frames to tile. + With no prefix arg, all visible frames are tiled, except a + standalone minibuffer frame, if any. +If called from a program, all frames in list FRAMES are tiled." + (interactive (and current-prefix-arg (frcmds-read-args-for-tiling))) + (frcmds-tile-frames 'horizontal frames)) + +;;;###autoload +(defalias 'tile-frames-top-to-bottom 'tile-frames-vertically) +;;;###autoload +(defun tile-frames-vertically (&optional frames) + "Tile frames vertically (stacking from the top of the screen downward). +Interactively: + With prefix arg, you are prompted for names of two frames to tile. + With no prefix arg, all visible frames are tiled, except a + standalone minibuffer frame, if any. +If called from a program, all frames in list FRAMES are tiled." + (interactive (and current-prefix-arg (frcmds-read-args-for-tiling))) + (frcmds-tile-frames 'vertical frames)) + +;;;###autoload +(defun create-frame-tiled-horizontally () + "Horizontally tile screen with selected frame and a copy. +The same character size is used for the new frame." + (interactive) + (let* ((fr1 (selected-frame)) + (font1 (frame-parameter fr1 'font)) + (fr2 (make-frame-command))) + (save-selected-window (select-frame fr2) (set-frame-font font1)) + (frcmds-tile-frames 'horizontal (list fr1 fr2)))) + +;;;###autoload +(defun create-frame-tiled-vertically () + "Vertically tile screen with selected frame and a copy. +The same character size is used for the new frame." + (interactive) + (let* ((fr1 (selected-frame)) + (font1 (frame-parameter fr1 'font)) + (fr2 (make-frame-command))) + (frcmds-tile-frames 'vertical (list fr1 fr2)))) + +;;;###autoload +(defun split-frame-horizontally (num) + "Horizontally split the selected frame. +With a prefix arg, create that many new frames. +The same character size is used for the new frames." + (interactive "p") + (frcmds-split-frame-1 'horizontal num)) + +;;;###autoload +(defun split-frame-vertically (num) + "Vertically split the selected frame. +With a prefix arg, create that many new frames. +The same character size is used for the new frames." + (interactive "p") + (frcmds-split-frame-1 'vertical num)) + +(defun frcmds-split-frame-1 (direction num) + "Helper for `split-frame-horizontally' and `split-frame-vertically'. +DIRECTION is `horizontal' or `vertical'. +NUM is the desired number of new frames to create." + (let* ((fr1 (selected-frame)) + (font1 (frame-parameter fr1 'font)) + (x-min (frame-geom-value-numeric 'left (frame-parameter fr1 'left))) + (y-min (frame-geom-value-numeric 'top (frame-parameter fr1 'top))) + (wid (frame-pixel-width fr1)) + (hght (frcmds-frame-pixel-height fr1)) + (frames (list fr1)) + fr) + (dotimes (ii num) + (setq fr (make-frame-command)) + (save-selected-window (select-frame fr) (set-frame-font font1)) + (push fr frames)) + (frcmds-tile-frames direction frames x-min y-min wid hght))) + +(defun frcmds-frame-pixel-height (frame) + "Pixel height of FRAME, including the window-manager title bar and menu-bar. +For the title bar, `window-mgr-title-bar-pixel-height' is used. +For the menu-bar, the frame char size is multiplied by frame parameter +`menu-bar-lines'. But that parameter does not take into account +menu-bar wrapping." + (+ window-mgr-title-bar-pixel-height + (frame-pixel-height frame) + (if (not (eq window-system 'x)) + 0 + (+ (* (frame-char-height frame) + (cdr (assq 'menu-bar-lines (frame-parameters frame)))))))) + +(defun frcmds-tile-frames (direction frames &optional x-min-pix y-min-pix pix-width pix-height) + "Tile visible frames horizontally or vertically, depending on DIRECTION. +Arg DIRECTION is `horizontal' or `vertical' (meaning side by side or +above and below, respectively). + +Arg FRAMES is the list of frames to tile. If nil, then tile all visible +frames (except a standalone minibuffer frame, if any). + +The optional args cause tiling to be limited to the bounding rectangle +they specify. X-MIN-PIX and Y-MIN-PIX are the `left' and `top' screen +pixel positions of the rectangle. X-PIX-WIDTH and Y-PIX-HEIGHT are +the pixel width and height of the rectangle." + (let ((visible-frames (or frames + (filtered-frame-list ; Get visible frames, except minibuffer. + #'(lambda (fr) + (and (eq t (frame-visible-p fr)) + (or (not (fboundp 'thumfr-thumbnail-frame-p)) + (not (thumfr-thumbnail-frame-p fr))) + (or (not (boundp '1on1-minibuffer-frame)) + (not (eq (cdr (assq 'name (frame-parameters + 1on1-minibuffer-frame))) + (cdr (assq 'name (frame-parameters fr))))))))))) + ;; Size of a frame that uses all of the available screen area, + ;; but leaving room for a minibuffer frame at bottom of display. + (fr-pixel-width (or pix-width (frcmds-available-screen-pixel-width))) + (fr-pixel-height (or pix-height (frcmds-available-screen-pixel-height))) + (fr-origin (if (eq direction 'horizontal) + (or x-min-pix (car (frcmds-effective-screen-pixel-bounds))) + (or y-min-pix (cadr (frcmds-effective-screen-pixel-bounds)))))) + (case direction ; Size of frame in pixels. + (horizontal (setq fr-pixel-width (/ fr-pixel-width (length visible-frames)))) + (vertical (setq fr-pixel-height (/ fr-pixel-height (length visible-frames)))) + (otherwise (error "`frcmds-tile-frames': DIRECTION must be `horizontal' or `vertical'"))) + (dolist (fr visible-frames) + (if (or (> emacs-major-version 24) + (and (= emacs-major-version 24) (> emacs-minor-version 3))) + (let ((frame-resize-pixelwise t)) + (set-frame-size + fr + ;; Subtract scroll bars, & title bar. + (- fr-pixel-width (frcmds-extra-pixels-width fr)) + (- fr-pixel-height + window-mgr-title-bar-pixel-height + (if pix-height 0 (frcmds-smart-tool-bar-pixel-height fr)) + (if (not (eq window-system 'x)) ; Menu bar for X is not in the frame. + 0 + (* (frame-char-height fr) (cdr (assq 'menu-bar-lines (frame-parameters fr)))))) + 'PIXELWISE)) + (set-frame-size + fr + ;; Subtract scroll bars, & title bar, then convert pixel sizes to char sizes. + (/ (- fr-pixel-width + (frcmds-extra-pixels-width fr)) + (frame-char-width fr)) + (/ (- fr-pixel-height + (frcmds-extra-pixels-height fr) + window-mgr-title-bar-pixel-height + (if pix-height 0 (frcmds-smart-tool-bar-pixel-height fr)) + (if (not (eq window-system 'x)) ; Menu bar for X is not in the frame. + 0 + (* (frame-char-height fr) (cdr (assq 'menu-bar-lines (frame-parameters fr)))))) + (frame-char-height fr)))) + (set-frame-position fr + (if (eq direction 'horizontal) fr-origin (or x-min-pix 0)) + (if (eq direction 'horizontal) (or y-min-pix 0) fr-origin)) + (show-frame fr) + ;; Move over the width or height of one frame, and add one border width. + (incf fr-origin (+ (or (cdr (assq 'border-width (frame-parameters fr))) 0) + (if (eq direction 'horizontal) fr-pixel-width fr-pixel-height)))))) + +(defun frcmds-extra-pixels-width (frame) + "Pixel difference between FRAME total width and its text area width." + (- (frame-pixel-width frame) (* (frame-char-width frame) (frame-width frame)))) + +(defun frcmds-extra-pixels-height (frame) + "Pixel difference between FRAME total height and its text area height." + (- (frame-pixel-height frame) (* (frame-char-height frame) (frame-height frame)))) + +(defun frcmds-smart-tool-bar-pixel-height (&optional frame) + "Pixel height of Mac smart tool bar." + (if (and (boundp 'mac-tool-bar-display-mode) (> (frame-parameter frame 'tool-bar-lines) 0)) + (if (eq mac-tool-bar-display-mode 'icons) 40 56) + 0)) + +(defun frcmds-read-args-for-tiling () + "Read arguments for `frcmds-tile-frames'." + (list + (list + ;; Note: `read-frame' puts selected-frame name at front of `frame-name-history'. + (get-a-frame (read-frame "Tile two frames - First frame: " nil t)) + ;; Get next visible frame. For default (prompt) value: + ;; If there is another visible frame in `frame-name-history', use next such. + ;; Else if there is another visible frame in internal frame list, use next such. + ;; Else use selected frame. (`frame-name-history' is defined in `frame.el'.) + (get-a-frame + (read-frame + "Second frame: " + (let ((fr-names (cdr frame-name-history)) + (visible-p nil) + (fr nil)) + (while (and (not fr) fr-names) ; While no visible frame found and still fr-names to check. + (setq fr (car fr-names) ; Name + fr (get-a-frame fr) ; Frame + fr (and fr (eq t (frame-visible-p fr)) fr) ; Visible frame + fr-names (cdr fr-names))) + + ;; If no visible frames in history, besides selected-frame, + ;; then get next visible frame (not its name) from internal frame list. + (unless fr + (setq fr (selected-frame)) + (while (and (not visible-p) + (setq fr (next-frame fr)) + (not (equal fr (selected-frame)))) ; equal => no other found. + (setq visible-p (eq t (frame-visible-p fr))))) + fr) + t))))) + +(defun frcmds-available-screen-pixel-bounds () + "Returns a value of the same form as option `available-screen-pixel-bounds'. +This represents the currently available screen area." + (or available-screen-pixel-bounds ; Use the option value, if available. + (if (fboundp 'mac-display-available-pixel-bounds) ; Mac-OS-specific. + (mac-display-available-pixel-bounds) + (list 0 0 (x-display-pixel-width) (x-display-pixel-height))))) + +; Emacs 20 doesn't have `butlast'. Define it to avoid requiring `cl.el' at runtime. From `subr.el'. +(unless (fboundp 'butlast) + (defun nbutlast (list &optional n) + "Modifies LIST to remove the last N elements." + (let ((m (length list))) + (or n (setq n 1)) + (and (< n m) (progn (when (> n 0) (setcdr (nthcdr (- (1- m) n) list) ())) + list)))) + + (defun butlast (list &optional n) + "Return a copy of LIST with the last N elements removed." + (if (and n (<= n 0)) list (nbutlast (copy-sequence list) n)))) + +(defun frcmds-effective-screen-pixel-bounds () + "Upper left and lower right of available screen space for tiling frames. +This is `frcmds-available-screen-pixel-bounds', possibly adjusted to +allow for the standalone minibuffer frame provided by `oneonone.el'." + (if (boundp '1on1-minibuffer-frame) + (append (butlast (frcmds-available-screen-pixel-bounds)) + (list (frame-geom-value-numeric 'top (cdr (assq 'top (frame-parameters + 1on1-minibuffer-frame)))))) + (frcmds-available-screen-pixel-bounds))) + +(defun frcmds-available-screen-pixel-width (&optional include-mini-p) + "Width of the usable screen, in pixels. +Non-nil optional argument `include-mini-p' means include the space +occupied by a standalone minibuffer, if any." + (let ((bounds (if include-mini-p + (frcmds-available-screen-pixel-bounds) + (frcmds-effective-screen-pixel-bounds)))) + (- (caddr bounds) (car bounds)))) ; X1 - X0 + +(defun frcmds-available-screen-pixel-height (&optional include-mini-p) + "Height of the usable screen, in pixels. +Non-nil optional argument `include-mini-p' means include the +space occupied by a standalone minibuffer, if any." + (let ((bounds (if include-mini-p + (frcmds-available-screen-pixel-bounds) + (frcmds-effective-screen-pixel-bounds)))) + (- (cadddr bounds) (cadr bounds)))) ; Y1 - Y0 + +;; Inspired by `sk-grow-frame' from Sarir Khamsi [sarir.khamsi@raytheon.com] +;;;###autoload +(defun enlarge-frame (&optional increment frame) ; Suggested binding: `C-M-down'. + "Increase the height of FRAME (default: selected-frame) by INCREMENT. +INCREMENT is in lines (characters). +Interactively, it is given by the prefix argument." + (interactive "p") + (set-frame-height frame (+ (frame-height frame) increment))) + +;;;###autoload +(defun enlarge-frame-horizontally (&optional increment frame) ; Suggested binding: `C-M-right'. + "Increase the width of FRAME (default: selected-frame) by INCREMENT. +INCREMENT is in columns (characters). +Interactively, it is given by the prefix argument." + (interactive "p") + (set-frame-width frame (+ (frame-width frame) increment))) + +;;;###autoload +(defun shrink-frame (&optional increment frame) ; Suggested binding: `C-M-up'. + "Decrease the height of FRAME (default: selected-frame) by INCREMENT. +INCREMENT is in lines (characters). +Interactively, it is given by the prefix argument." + (interactive "p") + (set-frame-height frame (- (frame-height frame) increment))) + +;;;###autoload +(defun shrink-frame-horizontally (&optional increment frame) ; Suggested binding: `C-M-left'. + "Decrease the width of FRAME (default: selected-frame) by INCREMENT. +INCREMENT is in columns (characters). +Interactively, it is given by the prefix argument." + (interactive "p") + (set-frame-width frame (- (frame-width frame) increment))) + +;;;###autoload +(defun move-frame-down (&optional n frame) ; Suggested binding: `M-down'. + "Move selected frame down. +Move it N times `frame-char-height', where N is the prefix arg. +In Lisp code, FRAME is the frame to move." + (interactive "p") + (unless n (setq n 1)) + (setq n (* n (frame-char-height frame))) + (modify-frame-parameters frame (list (list 'top '+ (frcmds-new-frame-position frame 'top n))))) + +;;;###autoload +(defun move-frame-up (&optional n frame) ; Suggested binding: `M-up'. + "Move selected frame up. +Same as `move-frame-down', except movement is up." + (interactive "p") + (unless n (setq n 1)) + (move-frame-down (- n))) + +;;;###autoload +(defun move-frame-right (&optional n frame) ; Suggested binding: `M-right'. + "Move frame to the right. +Move it N times `frame-char-width', where N is the prefix arg. +In Lisp code, FRAME is the frame to move." + (interactive "p") + (unless n (setq n 1)) + (setq n (* n (frame-char-width frame))) + (modify-frame-parameters frame (list (list 'left '+ (frcmds-new-frame-position frame 'left n))))) + +;;;###autoload +(defun move-frame-left (&optional n frame) ; Suggested binding: `M-left'. + "Move frame to the left. +Same as `move-frame-right', except movement is to the left." + (interactive "p") + (unless n (setq n 1)) + (move-frame-right (- n))) + +;; Helper function. +(defun frcmds-new-frame-position (frame type incr) + "Return the new TYPE position of FRAME, incremented by INCR. +TYPE is `left' or `top'. +INCR is the increment to use when changing the position." + (let ((new-pos (+ incr (cadr (frame-geom-value-cons + type (cdr (assq type (frame-parameters frame))))))) + (display-dimension (if (eq 'left type) + (frcmds-available-screen-pixel-width t) + (frcmds-available-screen-pixel-height t))) + (frame-dimension (if (eq 'left type) (frame-pixel-width frame) (frame-pixel-height frame)))) + (if (not move-frame-wrap-within-display-flag) + new-pos + (when (< new-pos (- frame-dimension)) (setq new-pos display-dimension)) + (when (> new-pos display-dimension) (setq new-pos (- frame-dimension))) + new-pos))) + +;;;###autoload +(defun move-frame-to-screen-top (arg &optional frame) ; Suggested binding: `M-S-v'. + "Move FRAME (default: selected-frame) to the top of the screen. +With a prefix arg, offset it that many char heights from the top." + (interactive (list (if current-prefix-arg + (* (frame-char-height) (prefix-numeric-value current-prefix-arg)) + 0) + (get-a-frame (read-frame "Frame: " nil 'EXISTING)))) + (modify-frame-parameters frame `((top . ,arg)))) + +;;;###autoload +(defun move-frame-to-screen-bottom (arg &optional frame) ; Suggested binding: `C-S-v'. + "Move FRAME (default: selected-frame) to the bottom of the screen. +With a prefix arg, offset it that many char heights from the bottom." + (interactive (list (if current-prefix-arg + (* (frame-char-height) (prefix-numeric-value current-prefix-arg)) + 0) + (get-a-frame (read-frame "Frame: " nil 'EXISTING)))) + (let* ((borders (* 2 (cdr (assq 'border-width (frame-parameters frame))))) + (avail-height (- (/ (- (frcmds-available-screen-pixel-height) borders + (frcmds-extra-pixels-height frame) + window-mgr-title-bar-pixel-height + (frcmds-smart-tool-bar-pixel-height)) + (frame-char-height frame)) + ;; Subtract menu bar unless on Carbon Emacs (menu bar not in the frame). + (if (eq window-system 'mac) + 0 + (cdr (assq 'menu-bar-lines (frame-parameters frame))))))) + (modify-frame-parameters frame `((top . ,(- (+ avail-height arg))))))) + +;;;###autoload +(defun move-frame-to-screen-left (arg &optional frame) ; Suggested binding: `C-S-prior'. + "Move FRAME (default: selected-frame) to the left side of the screen. +With a prefix arg, offset it that many char widths from the left." + (interactive (list (if current-prefix-arg + (* (frame-char-width) (prefix-numeric-value current-prefix-arg)) + 0) + (get-a-frame (read-frame "Frame: " nil 'EXISTING)))) + (modify-frame-parameters frame `((left . ,arg)))) + +;;;###autoload +(defun move-frame-to-screen-right (arg &optional frame) ; Suggested binding: `C-S-next'. + "Move FRAME (default: selected-frame) to the right side of the screen. +With a prefix arg, offset it that many char widths from the right." + (interactive (list (if current-prefix-arg + (* (frame-char-width) (prefix-numeric-value current-prefix-arg)) + 0) + (get-a-frame (read-frame "Frame: " nil 'EXISTING)))) + (modify-frame-parameters + frame ; Hard-code 7 here - what does it depend on? + `((left . ,(- (x-display-pixel-width) (+ (frame-pixel-width) 7 arg)))))) + +;;;###autoload +(defun move-frame-to-screen-top-left (arg &optional frame) ; Suggested binding: `C-S-home'. + "Move FRAME (default: selected-frame) to the top and left of the screen. +With a prefix arg, offset it that many char widths from the edges. + +Note: You can use this command to move an off-screen (thus not +visible) frame back onto the screen." + (interactive (list (if current-prefix-arg + (* (frame-char-width) (prefix-numeric-value current-prefix-arg)) + 0) + (get-a-frame (read-frame "Frame: " nil 'EXISTING)))) + (modify-frame-parameters frame '((top . ,arg) (left . ,arg)))) + + +;; This does not work 100% well. For instance, set frame font to +;; "-raster-Terminal-normal-r-normal-normal-12-90-96-96-c-50-ms-oemlatin", then decrease font size. +;; The next smaller existing font on my machine is +;; "-raster-Terminal-normal-r-normal-normal-11-*-96-96-c-*-ms-oemlatin". Decrease size again. +;; Next smaller font is "-raster-Terminal-bold-r-normal-normal-5-37-96-96-c-60-ms-oemlatin". Notice +;; the switch to bold from regular. Cannot decrease any more. Increase size. Next larger font is +;; "-raster-Terminal-bold-r-normal-normal-8-*-96-96-c-*-ms-oemlatin". Can no longer increase size. +;; +;;;###autoload +(defun enlarge-font (&optional increment frame) + "Increase size of font in FRAME by INCREMENT. +Interactively, INCREMENT is given by the prefix argument. +Optional FRAME parameter defaults to current frame." + (interactive "p") + (setq frame (or frame (selected-frame))) + (let ((fontname (cdr (assq 'font (frame-parameters frame)))) + (count enlarge-font-tries)) + (setq fontname (frcmds-enlarged-font-name fontname frame increment)) + (while (and (not (x-list-fonts fontname)) (wholenump (setq count (1- count)))) + (setq fontname (frcmds-enlarged-font-name fontname frame increment))) + (unless (x-list-fonts fontname) (error "Cannot change font size")) + (modify-frame-parameters frame (list (cons 'font fontname))) + ;; Update faces that want a bold or italic version of the default font. + (when (< emacs-major-version 21) (frame-update-faces frame)))) + +;;; This was a workaround hack for an Emacs 23 bug (#119, aka #1562). +;;; This works OK, but it is not as refined as the version I use, and it does not work for +;;; older Emacs versions. +;;; +;;; (when (> emacs-major-version 22) +;;; (defun enlarge-font (&optional increment frame) +;;; "Increase size of font in FRAME by INCREMENT. +;;; Interactively, INCREMENT is given by the prefix argument. +;;; Optional FRAME parameter defaults to current frame." +;;; (interactive "p") +;;; (setq frame (or frame (selected-frame))) +;;; (set-face-attribute +;;; 'default frame :height (+ (* 10 increment) +;;; (face-attribute 'default :height frame 'default))))) + + + + + +;;; Define error symbols `font-too-small' and `font-size', and their error conditions and messages. +;;; +;;; You can use these to handle an error of trying to make the font too small. +;;; See library `thumb-frm.el', command `thumfr-thumbify-frame'. +;;; +(put 'font-too-small 'error-conditions '(error font-size font-too-small)) +(put 'font-too-small 'error-message "Font size is too small") + +(put 'font-size 'error-conditions '(error font-size)) +(put 'font-size 'error-message "Bad font size") + +(defun frcmds-enlarged-font-name (fontname frame increment) + "FONTNAME, after enlarging font size of FRAME by INCREMENT. +FONTNAME is the font of FRAME." + (when (query-fontset fontname) + (let ((ascii (assq 'ascii (aref (fontset-info fontname frame) 2)))) + (when ascii (setq fontname (nth 2 ascii))))) + (let ((xlfd-fields (x-decompose-font-name fontname))) + (unless xlfd-fields (error "Cannot decompose font name")) + (let ((new-size (+ (string-to-number (aref xlfd-fields xlfd-regexp-pixelsize-subnum)) + increment))) + (unless (> new-size 0) (signal 'font-too-small (list new-size))) + (aset xlfd-fields xlfd-regexp-pixelsize-subnum (number-to-string new-size))) + ;; Set point size & width to "*", so frame width will adjust to new font size + (aset xlfd-fields xlfd-regexp-pointsize-subnum "*") + (aset xlfd-fields xlfd-regexp-avgwidth-subnum "*") + (x-compose-font-name xlfd-fields))) + +;;;###autoload +(defun set-frame-alist-parameter-from-frame (alist parameter &optional frame) + "Set PARAMETER of frame alist ALIST to its current value in FRAME. +FRAME defaults to the selected frame. ALIST is a variable (symbol) +whose value is an alist of frame parameters." + (interactive + (let ((symb (or (and (fboundp 'symbol-nearest-point) + (symbol-nearest-point)) + (symbolp (variable-at-point)))) + (enable-recursive-minibuffers t)) + (list (intern (completing-read + "Frame alist to change (variable): " + (frcmds-frame-alist-var-names) nil t nil nil 'default-frame-alist t)) + (intern (completing-read "Parameter to set:" ; Lax completion - not just known parameters. + (frcmds-frame-parameter-names) nil nil nil nil 'left t)) + (get-a-frame (read-frame "Frame to copy parameter value from: " nil t))))) + (unless (boundp alist) + (error "Not a defined Emacs variable: `%s'" alist)) + (set alist (assq-delete-all parameter (copy-alist (eval alist)))) + (set alist (cons (assq parameter (frame-parameters frame)) (eval alist))) + (tell-customize-var-has-changed alist)) + +;;; Standard Emacs 21+ function, defined here for Emacs 20. +(unless (fboundp 'assq-delete-all) + (defun assq-delete-all (key alist) + "Delete from ALIST all elements whose car is `eq' to KEY. +Return the modified alist. +Elements of ALIST that are not conses are ignored." + (while (and (consp (car alist)) (eq (car (car alist)) key)) (setq alist (cdr alist))) + (let ((tail alist) + tail-cdr) + (while (setq tail-cdr (cdr tail)) + (if (and (consp (car tail-cdr)) (eq (car (car tail-cdr)) key)) + (setcdr tail (cdr tail-cdr)) + (setq tail tail-cdr)))) + alist)) + +;; Define this to avoid requiring `cl.el' at runtime. Same as `icicle-set-difference'. +(defun frcmds-set-difference (list1 list2 &optional key) + "Combine LIST1 and LIST2 using a set-difference operation. +Optional arg KEY is a function used to extract the part of each list +item to compare. + +The result list contains all items that appear in LIST1 but not LIST2. +This is non-destructive; it makes a copy of the data if necessary, to +avoid corrupting the original LIST1 and LIST2." + (if (or (null list1) (null list2)) + list1 + (let ((keyed-list2 (and key (mapcar key list2))) + (result ())) + (while list1 + (unless (if key + (member (funcall key (car list1)) keyed-list2) + (member (car list1) list2)) + (setq result (cons (car list1) result))) + (setq list1 (cdr list1))) + result))) + +;;;###autoload +(defun set-all-frame-alist-parameters-from-frame (alist &optional frame really-all-p) + "Set frame parameters of ALIST to their current values in FRAME. +Unless optional argument REALLY-ALL-P (prefix arg) is non-nil, the +frame parameters in list `frame-parameters-to-exclude' are +excluded: they are not copied from FRAME to ALIST. +ALIST is a variable (symbol) whose value is an alist of frame parameters. +FRAME defaults to the selected frame." + (interactive + (let ((symb (or (and (fboundp 'symbol-nearest-point) + (symbol-nearest-point)) + (symbolp (variable-at-point)))) + (enable-recursive-minibuffers t)) + (list (intern (completing-read + "Frame alist to change (variable): " + (frcmds-frame-alist-var-names) nil t nil nil 'default-frame-alist t)) + (get-a-frame (read-frame "Frame to copy parameter values from: " nil t)) + current-prefix-arg))) + (unless (boundp alist) + (error "Not a defined Emacs variable: `%s'" alist)) + (set alist (frcmds-set-difference (frame-parameters frame) + (and (not really-all-p) frame-parameters-to-exclude) + #'car)) + (tell-customize-var-has-changed alist)) + +(defun frcmds-frame-alist-var-names () + "Return an alist of all variable names that end in \"frame-alist\". +The CAR of each list item is a string variable name. +The CDR is nil." + (let ((vars ())) + (mapatoms (lambda (sym) (and (boundp sym) + (setq sym (symbol-name sym)) + (string-match "frame-alist$" sym) + (push (list sym) vars)))) + vars)) + +(defun frcmds-frame-parameter-names () + "Return an alist of all available frame-parameter names. +These are the documented, out-of-the-box (predefined) parameters. +The CAR of each list item is a string parameter name. +The CDR is nil." + (let ((params '(("auto-lower") + ("auto-raise") + ("background-color") + ("background-mode") + ("border-color") + ("border-width") + ("buffer-list") + ("buffer-predicate") + ("cursor-color") + ("cursor-type") + ("display") + ("display-type") + ("font") + ("foreground-color") + ("height") + ("horizontal-scroll-bars") + ("icon-left") + ("icon-name") + ("icon-top") + ("icon-type") + ("internal-border-width") + ("left") + ("menu-bar-lines") + ("minibuffer") + ("mouse-color") + ("name") + ("scroll-bar-width") + ("title") + ("top") + ("unsplittable") + ("user-position") + ("vertical-scroll-bars") + ("visibility") + ("width") + ("window-id")))) + (when (> emacs-major-version 20) + (setq params (nconc params '(("fullscreen") + ("left-fringe") + ("line-spacing") + ("outer-window-id") + ("right-fringe") + ("screen-gamma") + ("scroll-bar-background") + ("scroll-bar-foreground") + ("tool-bar-lines") + ("tty-color-mode") + ("wait-for-wm"))))) + (when (> emacs-major-version 21) + (setq params (nconc params '(("user-size"))))) + (when (> emacs-major-version 22) + (setq params (nconc params '(("alpha") + ("display-environment-variable") + ("font-backend") + ("sticky") + ("term-environment-variable"))))) + (when (> emacs-major-version 23) + (setq params (nconc params '(("explicit-name") + ("tool-bar-position"))))) + params)) + +;;;###autoload +(defun tell-customize-var-has-changed (variable) + "Tell Customize to recognize that VARIABLE has been set (changed). +VARIABLE is a symbol that names a user option." + (interactive "vVariable: ") + (put variable 'customized-value (list (custom-quote (eval variable))))) + +;;;###autoload +(defun other-window-or-frame (arg) + "`other-frame', if `one-window-p'; otherwise, `other-window'." + (interactive "p") + (if (one-window-p) (other-frame arg) (other-window arg))) + +;;;;;;;;;;;;;;;;;;;;;;; + +(provide 'frame-cmds) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; frame-cmds.el ends here diff --git a/layers/+spacemacs/spacemacs-ui-visual/local/zoom-frm/frame-fns.el b/layers/+spacemacs/spacemacs-ui-visual/local/zoom-frm/frame-fns.el new file mode 100644 index 0000000..68b6b20 --- /dev/null +++ b/layers/+spacemacs/spacemacs-ui-visual/local/zoom-frm/frame-fns.el @@ -0,0 +1,313 @@ +;;; frame-fns.el --- Non-interactive frame and window functions. +;; +;; Filename: frame-fns.el +;; Description: Non-interactive frame and window functions. +;; Author: Drew Adams +;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com") +;; Copyright (C) 1996-2015, Drew Adams, all rights reserved. +;; Created: Tue Mar 5 16:15:50 1996 +;; Version: 0 +;; Package-Requires: () +;; Last-Updated: Thu Jan 1 10:45:03 2015 (-0800) +;; By: dradams +;; Update #: 227 +;; URL: http://www.emacswiki.org/frame-fns.el +;; Doc URL: http://emacswiki.org/FrameModes +;; Keywords: internal, extensions, local, frames +;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x, 24.x, 25.x +;; +;; Features that might be required by this library: +;; +;; `avoid'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; Non-interactive frame and window functions. +;; +;; Main new functions defined here: +;; +;; `1-window-frames-on', `distance', `flash-ding', +;; `frame-geom-spec-cons', `frame-geom-value-cons', +;; `frame-geom-spec-numeric', `frame-geom-value-numeric', +;; `frames-on', `get-a-frame', `get-frame-name', +;; `multi-window-frames-on', `read-frame', `window-coords'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change Log: +;; +;; 2011/01/04 dadams +;; Removed autoload cookies from non-interactive functions. +;; 2010/01/12 dadams +;; 1-window-frames-on, multi-window-frames-on: +;; save-excursion + set-buffer -> with-current-buffer. +;; 2008/04/05 dadams +;; get-a-frame: Define without using member-if. +;; 2005/10/31 dadams +;; read-frame: Swapped default and init values in call to completing-read. +;; 2004/11/26 dadams +;; Added frame-geom-spec-numeric and frame-geom-value-numeric. +;; 2004/03/19 dadams +;; read-frame: 1) if default is a frame, use its name, +;; 2) use frame-name-history, not minibuffer-history, +;; and use make-frame-names-alist, not frame-alist, +;; in completing-read +;; 1996/02/14 dadams +;; Added: window-coords, distance. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; 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 this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(eval-when-compile (when (< emacs-major-version 21) (require 'cl))) + ;; dolist, push +(require 'avoid nil t) ;; mouse-avoidance-point-position + +;;;;;;;;;;;;;;;;;;;;;;; + +(defun window-coords (&optional position) + "Return window coordinates of buffer POSITION (default: point). +If POSITION is nil, (point) is used." + (unless (fboundp 'mouse-avoidance-point-position) (require 'avoid)) + (cdr (mouse-avoidance-point-position))) + +(defun distance (pt1 pt2) + "Distance as the crow flies between PT1 and PT2. +PT1 and PT2 are each a cons of the form (X . Y)." + (let ((xdiff (abs (- (car pt1) (car pt2)))) + (ydiff (abs (- (cdr pt1) (cdr pt2))))) + (sqrt (+ (* xdiff xdiff) (* ydiff ydiff))))) + +(defun frame-geom-value-numeric (type value &optional frame) + "Return equivalent geometry value for FRAME in numeric terms. +A geometry value equivalent to VALUE for FRAME is returned, +where the value is numeric, not a consp. +TYPE is the car of the original geometry spec (TYPE . VALUE). + It is `top' or `left', depending on which edge VALUE is related to. +VALUE is the cdr of a frame geometry spec: (left/top . VALUE). +If VALUE is a consp, then it is converted to a numeric value, perhaps + relative to the opposite frame edge from that in the original spec. +FRAME defaults to the selected frame. + +Examples (measures in pixels) - + Assuming display height/width=1024, frame height/width=600: + 300 inside display edge: 300 => 300 + (+ 300) => 300 + 300 inside opposite display edge: (- 300) => -300 + -300 => -300 + 300 beyond display edge + (= 724 inside opposite display edge): (+ -300) => -724 + 300 beyond display edge + (= 724 inside opposite display edge): (- -300) => 724 + +In the last two examples, the returned value is relative to the +opposite frame edge from the edge indicated in the input spec." + (if (consp value) + (if (natnump (cadr value)) + ;; e.g. (+ 300) or (- 300) => 300 or -300 + (funcall (car value) (cadr value)) + ;; e.g. (+ -300) or (- -300) + (let ((oppval (- (if (eq 'left type) + (x-display-pixel-width) + (x-display-pixel-height)) + (cadr value) + (if (eq 'left type) + (frame-pixel-width frame) + (frame-pixel-height frame))))) + (if (eq '+ (car value)) + (- oppval) ; e.g. (+ -300) => -724 + oppval))) ; e.g. (- -300) => 724 + ;; e.g. 300 or -300 + value)) + +(defun frame-geom-spec-numeric (spec &optional frame) + "Return equivalent geometry specification for FRAME in numeric terms. +A geometry specification equivalent to SPEC for FRAME is returned, +where the value is numeric, not a consp. +SPEC is a frame geometry spec: (left . VALUE) or (top . VALUE). +If VALUE is a consp, then it is converted to a numeric value, perhaps + relative to the opposite frame edge from that in the original SPEC. +FRAME defaults to the selected frame. + +Examples (measures in pixels) - + Assuming display height=1024, frame height=600: + top 300 below display top: (top . 300) => (top . 300) + (top + 300) => (top . 300) + bottom 300 above display bottom: (top - 300) => (top . -300) + (top . -300) => (top . -300) + top 300 above display top + (= bottom 724 above display bottom): (top + -300) => (top . -724) + bottom 300 below display bottom + (= top 724 below display top): (top - -300) => (top . 724) + +In the last two examples, the returned value is relative to the +opposite frame edge from the edge indicated in the input SPEC." + (cons (car spec) (frame-geom-value-numeric (car spec) (cdr spec)))) + +(defun frame-geom-value-cons (type value &optional frame) + "Return equivalent geometry value for FRAME as a cons with car `+'. +A geometry value equivalent to VALUE for FRAME is returned, +where the value is a cons with car `+', not numeric. +TYPE is the car of the original geometry spec (TYPE . VALUE). + It is `top' or `left', depending on which edge VALUE is related to. +VALUE is the cdr of a frame geometry spec: (left/top . VALUE). +If VALUE is a number, then it is converted to a cons value, perhaps + relative to the opposite frame edge from that in the original spec. +FRAME defaults to the selected frame. + +Examples (measures in pixels) - + Assuming display height/width=1024, frame height/width=600: + 300 inside display edge: 300 => (+ 300) + (+ 300) => (+ 300) + 300 inside opposite display edge: (- 300) => (+ 124) + -300 => (+ 124) + 300 beyond display edge + (= 724 inside opposite display edge): (+ -300) => (+ -300) + 300 beyond display edge + (= 724 inside opposite display edge): (- -300) => (+ 724) + +In the 3rd, 4th, and 6th examples, the returned value is relative to +the opposite frame edge from the edge indicated in the input spec." + (cond ((and (consp value) (eq '+ (car value))) ; e.g. (+ 300), (+ -300) + value) + ((natnump value) (list '+ value)) ; e.g. 300 => (+ 300) + (t ; e.g. -300, (- 300), (- -300) + (list '+ (- (if (eq 'left type) ; => (+ 124), (+ 124), (+ 724) + (x-display-pixel-width) + (x-display-pixel-height)) + (if (integerp value) (- value) (cadr value)) + (if (eq 'left type) + (frame-pixel-width frame) + (frame-pixel-height frame))))))) + +(defun frame-geom-spec-cons (spec &optional frame) + "Return equivalent geometry spec for FRAME as a cons with car `+'. +A geometry specification equivalent to SPEC for FRAME is returned, +where the value is a cons with car `+', not numeric. +SPEC is a frame geometry spec: (left . VALUE) or (top . VALUE). +If VALUE is a number, then it is converted to a cons value, perhaps + relative to the opposite frame edge from that in the original spec. +FRAME defaults to the selected frame. + +Examples (measures in pixels) - + Assuming display height=1024, frame height=600: + top 300 below display top: (top . 300) => (top + 300) + (top + 300) => (top + 300) + bottom 300 above display bottom: (top - 300) => (top + 124) + (top . -300) => (top + 124) + top 300 above display top + (= bottom 724 above display bottom): (top + -300) => (top + -300) + bottom 300 below display bottom + (= top 724 below display top): (top - -300) => (top + 724) + +In the 3rd, 4th, and 6th examples, the returned value is relative to +the opposite frame edge from the edge indicated in the input spec." + (cons (car spec) (frame-geom-value-cons (car spec) (cdr spec)))) + +(defun get-frame-name (&optional frame) + "Return the string that names FRAME (a frame). Default is selected frame." + (unless frame (setq frame (selected-frame))) + (if (framep frame) + (cdr (assq 'name (frame-parameters frame))) + (error "Function `get-frame-name': Argument not a frame: `%s'" frame))) + +(defun get-a-frame (frame) + "Return a frame, if any, named FRAME (a frame or a string). +If none, return nil. +If FRAME is a frame, it is returned." + (cond ((framep frame) frame) + ((stringp frame) + (catch 'get-a-frame-found + (dolist (fr (frame-list)) + (when (string= frame (get-frame-name fr)) + (throw 'get-a-frame-found fr))) + nil)) + (t (error + "Function `get-frame-name': Arg neither a string nor a frame: `%s'" + frame)))) + +(defun read-frame (prompt &optional default existing) + "Read the name of a frame, and return it as a string. +Prompts with 1st arg, PROMPT (a string). + +The default frame is named by the optional 2nd arg, DEFAULT, if a +string or a frame, or by the `selected-frame', if nil. + +Non-nil optional 3rd arg, EXISTING, means to allow only names of +existing frames." + (setq default (if (framep default) + (get-frame-name default) + (or default (get-frame-name)))) + (unless (stringp default) + (error "Function `read-frame': DEFAULT arg is neither a frame nor a string")) + (completing-read prompt (make-frame-names-alist) + ;; To limit to live frames: + ;; (function (lambda (fn+f)(frame-live-p (cdr fn+f)))) + ;; `frame-name-history' is defined in `frame.el'. + nil existing nil '(frame-name-history . 2) default)) + +(defun frames-on (buffer &optional frame) + "List of all live frames showing BUFFER (a buffer or its name). +The optional FRAME argument is as for function `get-buffer-window'." + (filtered-frame-list (function (lambda (fr) (get-buffer-window buffer fr))))) + +(defun 1-window-frames-on (buffer) + "List of all visible 1-window frames showing BUFFER." + (setq buffer (get-buffer buffer)) + (when buffer ; Do nothing if BUFFER is not a buffer. + (let ((frs ())) + (with-current-buffer buffer + (when (buffer-live-p buffer) ; Do nothing if dead buffer. + ;; $$$$$$ Is it better to search through frames-on or windows-on? + (dolist (fr (frames-on buffer)) + (save-window-excursion (select-frame fr) + (when (one-window-p t fr) (push fr frs)))))) + frs))) + +(defun multi-window-frames-on (buffer) + "List of all visible multi-window frames showing BUFFER." + (setq buffer (get-buffer buffer)) + (when buffer ; Do nothing if BUFFER is not a buffer. + (let ((frs ())) + (with-current-buffer buffer + (when (buffer-live-p buffer) ; Do nothing if dead buffer. + ;; $$$$$$ Is it better to search through frames-on or windows-on? + (dolist (fr (frames-on buffer)) + (save-window-excursion (select-frame fr) + (unless (one-window-p t fr) + (push fr frs)))))) + frs))) + +(defun flash-ding (&optional do-not-terminate frame) + "Ring bell (`ding'), after flashing FRAME (default: current), if relevant. +Terminates any keyboard macro executing, unless arg DO-NOT-TERMINATE non-nil." + (save-window-excursion + (when frame (select-frame frame)) + (let ((visible-bell t)) (ding 'DO-NOT-TERMINATE))) ; Flash. + (let ((visible-bell nil)) (ding 'DO-NOT-TERMINATE))) ; Bell. + +;;;;;;;;;;;;;;;;;;;;;;; + +(provide 'frame-fns) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; frame-fns.el ends here diff --git a/layers/+spacemacs/spacemacs-ui-visual/local/zoom-frm/zoom-frm.el b/layers/+spacemacs/spacemacs-ui-visual/local/zoom-frm/zoom-frm.el new file mode 100644 index 0000000..91eac33 --- /dev/null +++ b/layers/+spacemacs/spacemacs-ui-visual/local/zoom-frm/zoom-frm.el @@ -0,0 +1,439 @@ +;;; zoom-frm.el --- Commands to zoom frame font size. +;; +;; Filename: zoom-frm.el +;; Description: Commands to zoom frame font size. +;; Author: Drew Adams +;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com") +;; Copyright (C) 2005-2015, Drew Adams, all rights reserved. +;; Created: Fri Jan 07 10:24:35 2005 +;; Version: 0 +;; Package-Requires: ((frame-fns "0") (frame-cmds "0")) +;; Last-Updated: Thu Jan 1 11:24:13 2015 (-0800) +;; By: dradams +;; Update #: 322 +;; URL: http://www.emacswiki.org/zoom-frm.el +;; Doc URL: http://emacswiki.org/SetFonts +;; Keywords: frames, extensions, convenience +;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x, 24.x, 25.x +;; +;; Features that might be required by this library: +;; +;; `avoid', `frame-cmds', `frame-fns', `misc-fns', `strings', +;; `thingatpt', `thingatpt+'. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Commentary: +;; +;; Commands to zoom into and out of text. They zoom a frame or a +;; buffer, so that the text appears larger or smaller. +;; +;; Commands `zoom-in', `zoom-out', and `zoom-in/out' do both kinds of +;; zooming. They can behave like command `text-scale-adjust', +;; zooming a buffer wherever it is displayed, or they can zoom an +;; entire single frame (all of its windows). Hit `C-u' at any time +;; while using these commands to toggle between buffer and frame +;; zooming. +;; +;; Because it is a more general replacement for `text-scale-adjust', +;; I suggest you bind `zoom-in/out' to the keys bound by default to +;; `text-scale-adjust': `C-x C-+', `C-x C-=', `C-x C--', and `C-x +;; C-0'. +;; +;; It is also handy to use a mouse button or wheel for zooming, hence +;; the mouse binding suggestions. For example, binding `zoom-in' and +;; `zoom-out' to mouse wheel events gives you the zooming effect you +;; are perhaps used to in a Web browser. +;; +;; User option `zoom-frame/buffer' determines which kind of zooming +;; (frame or buffer) is used by default. You can customize this +;; option, but (in Emacs 23 or later) you can also toggle it just by +;; providing a prefix arg (`C-u') to `zoom-in/out', `zoom-in', or +;; `zoom-out'. +;; +;; Note about saving changes made dynamically using the commands +;; defined here: +;; +;; Some of the commands defined here change frame properties. You +;; can save any changes you have made, by using Customize. To +;; visit a Customize buffer of all unsaved changes you have made, +;; use command `customize-customized'. +;; +;; Frame parameter changes, such as font size, can be saved for +;; future use by all frames or all frames of a certain kind. For +;; that, you must change the frame parameters of the correponding +;; frame-alist variable. +;; +;; There is no single variable for saving changes to parameters of +;; the current frame. Instead, there are several different +;; frame-alist variables, which you can use to define different +;; kinds of frames. These include: `default-frame-alist', +;; `initial-frame-alist', and `special-display-frame-alist'. The +;; complete list of such frame alist variables is available using +;; function `frame-alist-var-names', defined in library +;; `frame-cmds.el'. +;; +;; Example: Suppose you change the font size of a frame and want to +;; make that the default font size for new frames in the future. +;; You will need to update the value of variable +;; `default-frame-alist' to use the `font' parameter setting of the +;; changed frame. +;; +;; You can easily copy one or all parameter values from any given +;; frame to any frame alist (such as `default-frame-alist'), by +;; using the commands `set-frame-alist-parameter-from-frame' and +;; `set-all-frame-alist-parameters-from-frame'. Those commands are +;; defined in library `frame-cmds.el'. +;; +;; +;; Commands defined here: +;; +;; `toggle-zoom-frame', `zoom-all-frames-in', +;; `zoom-all-frames-out', `zoom-frm-in', `zoom-frm-out', +;; `zoom-frm-unzoom', `zoom-in', `zoom-in/out' (Emacs 23+), +;; `zoom-out'. +;; +;; +;; User options (variables) defined here: +;; +;; `frame-zoom-font-difference', `zoom-frame/buffer' (Emacs 23+). +;; +;; +;; Put this in your init file (`~/.emacs'): (require 'zoom-frm) +;; +;; Suggested key bindings: +;; +;; Emacs 23 and later: +;; +;; (define-key ctl-x-map [(control ?+)] 'zoom-in/out) +;; (define-key ctl-x-map [(control ?-)] 'zoom-in/out) +;; (define-key ctl-x-map [(control ?=)] 'zoom-in/out) +;; (define-key ctl-x-map [(control ?0)] 'zoom-in/out) +;; +;; Any Emacs version: +;; +;; (global-set-key (if (boundp 'mouse-wheel-down-event) ; Emacs 22+ +;; (vector (list 'control +;; mouse-wheel-down-event)) +;; [C-mouse-wheel]) ; Emacs 20, 21 +;; 'zoom-in) +;; (when (boundp 'mouse-wheel-up-event) ; Emacs 22+ +;; (global-set-key (vector (list 'control mouse-wheel-up-event)) +;; 'zoom-out)) +;; +;; (global-set-key [S-mouse-1] 'zoom-in) +;; (global-set-key [C-S-mouse-1] 'zoom-out) +;; ;; Get rid of `mouse-set-font' or `mouse-appearance-menu': +;; (global-set-key [S-down-mouse-1] nil) +;; +;; The first two of the mouse bindings mean that in Emacs 22 or later +;; you can hold the Control key and rotate the mouse wheel to zoom in +;; and out, just as you might do in a Web browser. +;; +;; (In Emacs 20 and 21, Control plus mouse wheeling zooms in, but to +;; zoom out you need to use `C--' before wheeling with Control. This +;; is because Emacs 20 and 21 do not have separate events for the +;; mouse wheel directions, and it is the prefix arg, not the wheel +;; direction, that determines the effect.) +;; +;; +;; See also these files for other frame commands: +;; +;; `autofit-frame.el' - Automatically fit each frame to its +;; selected window. Uses `fit-frame.el'. +;; +;; `fit-frame.el' - 1) Fit a frame to its selected window. +;; 2) Incrementally resize a frame. +;; +;; `doremi-frm.el' - Incrementally adjust frame properties +;; using arrow keys and/or mouse wheel. +;; +;; `frame-cmds.el' - Miscellaneous frame and window commands. +;; +;; `thumb-frm.el' - Shrink frames to a thumbnail size and +;; restore them again. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Change Log: +;; +;; 2013/12/31 dadams +;; zoom-in/out: Use set-transient-map, if defined. +;; 2013/09//29 dadams +;; zoom-in/out: Only for Emacs 24.3+ (needs set-temporary-overlay-map). +;; 2013/09/13 dadams +;; Added: zoom-all-frames-in, zoom-all-frames-out. +;; 2013/04/21 dadams +;; Added: zoom-in/out. +;; 2011/01/04 dadams +;; Added autoload cookies for defgroup and defcustom. +;; 2010/07/06 dadams +;; zoom-(in|out): Put doc strings before interactive spec. Thx to Yidong Chong. +;; 2009/06/11 dadams +;; Added buffer zooming, for Emacs 23. +;; Added zoom-(in|out), group zoom, zoom-frame/buffer. +;; 2006/01/07 dadams +;; Added :link for sending bug report. +;; 2006/01/06 dadams +;; frame-zoom-font-difference: Changed :group to Frame-Commands. Added :link. +;; 2005/01/18 dadams +;; Changed default value of frame-zoom-font-difference. +;; Added Note on saving changes. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; 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 this program; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: + +(require 'frame-cmds) ;; enlarge-font + + +(defvar zoom-frame/buffer) ;; Defined here for Emacs 22+. + +;;;;;;;;;;;;;;;;;;;;;;;; + + +;;; USER OPTIONS (VARIABLES) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;;###autoload +(defgroup zoom nil + "Zoom a frame or buffer." + :group 'frames :group 'Frame-Commands ; Defined in `frame-cmds.el'. + :link `(url-link :tag "Send Bug Report" + ,(concat "mailto:" "drew.adams" "@" "oracle" ".com?subject=\ +zoom-frm.el bug: \ +&body=Describe bug here, starting with `emacs -q'. \ +Don't forget to mention your Emacs and library versions.")) + :link '(url-link :tag "Other Libraries by Drew" + "http://www.emacswiki.org/DrewsElispLibraries") + :link '(url-link :tag "Download" + "http://www.emacswiki.org/emacs-en/download/zoom-frm.el") + :link '(url-link :tag "Description" + "http://www.emacswiki.org/SetFonts#ChangingFontSize") + :link '(emacs-commentary-link :tag "Commentary" "zoom-frm")) + +;;;###autoload +(defcustom frame-zoom-font-difference 1 + "*Number of points to change the frame font size when zooming. +This applies to commands `zoom-in/out', `zoom-in', `zoom-out', +`zoom-frm-in', and `zoom-frm-out' when zooming a frame. + +The absolute value of the value must be less than the current font +size for the frame, because the new font size cannot be less than one +point." + :type 'integer :group 'zoom) + +(when (> emacs-major-version 22) + (defcustom zoom-frame/buffer 'frame + "*What to zoom: current frame or current buffer. +See command `zoom-in/out', `zoom-in', or `zoom-out'." + :type '(choice (const :tag "Zoom frame" frame) (const :tag "Zoom buffer" buffer)) + :group 'zoom)) + + +;;; FUNCTIONS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(unless (> emacs-major-version 22) (defalias 'zoom-in 'zoom-frm-in)) +;;;###autoload +(defun zoom-frm-in (&optional frame flip) + "Zoom FRAME in by `frame-zoom-font-difference', making text larger. +If `frame-zoom-font-difference' is negative, make text smaller. +With prefix argument FLIP, reverse the direction: +if `frame-zoom-font-difference' is positive, then make text smaller. +This is equal but opposite to `zoom-frm-out'." + (interactive (list (selected-frame) current-prefix-arg)) + (setq frame (or frame (selected-frame))) + (let ((zoom-factor (frame-parameter frame 'zoomed)) + (increment (if flip (- frame-zoom-font-difference) frame-zoom-font-difference))) + (unless zoom-factor (setq zoom-factor 0)) + (setq zoom-factor (+ zoom-factor increment)) + (enlarge-font increment frame) + (modify-frame-parameters frame (list (cons 'zoomed zoom-factor))))) + +(unless (> emacs-major-version 22) (defalias 'zoom-out 'zoom-frm-out)) +;;;###autoload +(defun zoom-frm-out (&optional frame flip) + "Zoom FRAME out by `frame-zoom-font-difference', making text smaller. +If `frame-zoom-font-difference' is negative, make text larger. +With prefix argument FLIP, reverse the direction: +if `frame-zoom-font-difference' is positive, then make text larger. +This is equal but opposite to `zoom-frm-in'." + (interactive (list (selected-frame) current-prefix-arg)) + (setq frame (or frame (selected-frame))) + (let ((frame-zoom-font-difference (- frame-zoom-font-difference))) + (zoom-frm-in frame flip))) + +;;;###autoload +(defun zoom-frm-unzoom (&optional frame) + "Cancel zoom of FRAME." + (interactive) + (setq frame (or frame (selected-frame))) + (let ((zoom-factor (frame-parameter frame 'zoomed))) + (if (not zoom-factor) + (error "Frame is not zoomed") + (enlarge-font (- zoom-factor) frame) + (modify-frame-parameters frame '((zoomed)))))) + +;;;###autoload +(defun toggle-zoom-frame (&optional frame) + "Alternately zoom/unzoom FRAME by `frame-zoom-font-difference'." + (interactive) + (setq frame (or frame (selected-frame))) + (if (frame-parameter frame 'zoomed) + (zoom-frm-unzoom frame) + (zoom-frm-in frame))) + +(when (> emacs-major-version 22) + (defun zoom-in (arg) + "Zoom current frame or buffer in. +With a prefix arg, toggle between zooming frame and zooming buffer. +Frame zooming uses command `zoom-frm-in'. +Buffer zooming uses command `text-scale-increase'." + (interactive "P") + (when arg + (setq zoom-frame/buffer (if (eq zoom-frame/buffer 'frame) 'buffer 'frame))) + (if (eq zoom-frame/buffer 'frame) + (zoom-frm-in) + (with-current-buffer + (if (string-match "mouse" (format "%S" (event-basic-type + last-command-event))) + (window-buffer (posn-window (event-start last-command-event))) + (current-buffer)) + (text-scale-increase 1)))) + + (defun zoom-out (arg) + "Zoom current frame or buffer out. +With a prefix arg, toggle between zooming frame and zooming buffer. +Frame zooming uses command `zoom-frm-out'. +Buffer zooming uses command `text-scale-decrease'." + (interactive "P") + (when arg + (setq zoom-frame/buffer (if (eq zoom-frame/buffer 'frame) 'buffer 'frame))) + (if (eq zoom-frame/buffer 'frame) + (zoom-frm-out) + (with-current-buffer + (if (string-match "mouse" (format "%S" (event-basic-type + last-command-event))) + (window-buffer (posn-window (event-start last-command-event))) + (current-buffer)) + (text-scale-decrease 1)))) + + (when (or (fboundp 'set-transient-map) ; Emacs 24.4+ + (fboundp 'set-temporary-overlay-map)) ; Emacs 24.3 + + (defun zoom-in/out (arg) + "Zoom current frame or buffer in or out. +A prefix arg determines the behavior, as follows: + none : Use 1 as the zoom amount. + plain `C-u': Toggle between zooming frame and zooming buffer. + 0 : Unzoom: reset size to the default. + other : Use the numeric value as the zoom amount. + +Similar to the behavior of command `text-scale-adjust', you can +continue to use any of the keys `+', `-', `0', and `C-u' repeatedly. +The zoom amount from the initial key sequence is used each time. + +Example: `C-3 C-x C-- C-- C-- C--' zooms out 4 times with a zoom +amount of 3 each time. + +The zoom amount for frame zooming is a point-size increment/decrement. +The zoom amount for buffer zooming is a number of text-scaling steps. + +Frame zooming uses command `zoom-frm-in'. +Buffer zooming uses command `text-scale-increase'. + +User option `zoom-frame/buffer' determines the default zoom type: +frame or buffer. If the option value is `buffer' and you never use +plain `C-u' with this command then it acts like `text-scale-adjust'." + (interactive "P") + (when (or (equal arg '(4)) (eq ?\025 last-command-event)) ; `C-u' + (setq zoom-frame/buffer (if (eq zoom-frame/buffer 'frame) 'buffer 'frame) + arg 1) + (message "Zooming %sS from now on" (upcase (symbol-name zoom-frame/buffer))) + (sit-for 1)) + (let* ((ev last-command-event) + (echo-keystrokes nil) + (base (event-basic-type ev)) + (step (if (or (equal arg '(4)) (eq ?\025 last-command-event)) ; C-u + 'C-U-WAS-USED + (setq arg (prefix-numeric-value arg)) + (case base + ((?+ ?=) arg) + (?- (- arg)) + (?0 0) + (t arg))))) + (message (if (eq step 0) + "Reset to default size. Use +/- to zoom in/out" + "Use +/- to zoom in/out, 0 to reset (unzoom)")) + (unless (eq step 'C-U-WAS-USED) + (if (eq zoom-frame/buffer 'frame) + (if (eq step 0) + (zoom-frm-unzoom) + (let ((frame-zoom-font-difference step)) (zoom-frm-in))) + (with-current-buffer + (if (string-match "mouse" (format "%S" (event-basic-type last-command-event))) + (window-buffer (posn-window (event-start last-command-event))) + (current-buffer)) + (text-scale-increase step)))) + (let ((fun (if (fboundp 'set-transient-map) + #'set-transient-map + #'set-temporary-overlay-map))) + (funcall fun + (let ((map (make-sparse-keymap))) + (dolist (mods '(() (control))) + (dolist (key '(?- ?+ ?= ?0)) ; The `=' key is often unshifted `+' key. + (define-key map (vector (append mods (list key))) + `(lambda () (interactive) (zoom-in/out ',arg))))) + (define-key map "\C-u" `(lambda () (interactive) (zoom-in/out ',arg))) + map))))))) + +;; These are not so useful, but some people might like them. +(when (fboundp 'set-face-attribute) ; Emacs 22+ + (defun zoom-all-frames-in (&optional flip) + "Zoom all frames in by `frame-zoom-font-difference', making text larger. +If `frame-zoom-font-difference' is negative, make text smaller. +With prefix argument FLIP, reverse the direction: +if `frame-zoom-font-difference' is positive, then make text smaller. +This is equal but opposite to `zoom-all-frames-out'. +Note: This zooming is unaffected by `zoom-frm-unzoom'." + (interactive "P") + (let ((increment (if flip (- frame-zoom-font-difference) frame-zoom-font-difference))) + (set-face-attribute 'default nil + :height (+ (* 10 increment) + (face-attribute 'default :height nil 'default))))) + + (defun zoom-all-frames-out (&optional flip) + "Zoom all frames out by `frame-zoom-font-difference', making text smaller. +If `frame-zoom-font-difference' is negative, make text larger. +With prefix argument FLIP, reverse the direction: +if `frame-zoom-font-difference' is positive, then make text larger. +This is equal but opposite to `zoom-frm-in'. +Note: This zooming is unaffected by `zoom-frm-unzoom'." + (interactive "P") + (let ((increment (if flip frame-zoom-font-difference (- frame-zoom-font-difference)))) + (set-face-attribute 'default nil + :height (+ (* 10 increment) + (face-attribute 'default :height nil 'default)))))) + +;;;;;;;;;;;;;;;;;;;;;;;;; + +(provide 'zoom-frm) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; zoom-frm.el ends here diff --git a/layers/+spacemacs/spacemacs-ui-visual/packages.el b/layers/+spacemacs/spacemacs-ui-visual/packages.el new file mode 100644 index 0000000..4695bf1 --- /dev/null +++ b/layers/+spacemacs/spacemacs-ui-visual/packages.el @@ -0,0 +1,386 @@ +;;; packages.el --- Spacemacs UI Visual Layer packages File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq spacemacs-ui-visual-packages + '( + (ansi-colors :location built-in) + fancy-battery + fill-column-indicator + golden-ratio + hl-todo + neotree + popup + popwin + (smooth-scrolling :location built-in) + spaceline + (zoom-frm :location local))) + +(defun spacemacs-ui-visual/init-ansi-colors () + (add-hook 'compilation-filter-hook + 'spacemacs-ui-visual//compilation-buffer-apply-ansi-colors)) + +(defun spacemacs-ui-visual/init-fancy-battery () + (use-package fancy-battery + :defer t + :init + (progn + (spacemacs|add-toggle mode-line-battery + :mode fancy-battery-mode + :documentation "Display battery info in mode-line." + :evil-leader "tmb") + (setq-default fancy-battery-show-percentage t)))) + +(defun spacemacs-ui-visual/init-fill-column-indicator () + (use-package fill-column-indicator + :defer t + :init + (progn + (setq fci-rule-width 1) + (setq fci-rule-color "#D0BF8F") + ;; manually register the minor mode since it does not define any + ;; lighter + (push '(fci-mode "") minor-mode-alist) + (spacemacs|add-toggle fill-column-indicator + :status fci-mode + :on (turn-on-fci-mode) + :off (turn-off-fci-mode) + :documentation "Display the fill column indicator." + :evil-leader "tf")) + :config + (spacemacs|diminish fci-mode " ⓕ" " f"))) + +(defun spacemacs-ui-visual/init-golden-ratio () + (use-package golden-ratio + :defer t + :init + (progn + (setq spacemacs-window-manipulation-transient-state-add-bindings + '(("g" spacemacs/toggle-golden-ratio))) + (spacemacs|add-toggle golden-ratio + :status golden-ratio-mode + :on (golden-ratio-mode) (golden-ratio) + :off (golden-ratio-mode -1) (balance-windows) + :documentation "Resize the focused window using the golden ratio." + :evil-leader "tg")) + :config + (progn + ;; golden-ratio-exclude-modes + (dolist (m '("bs-mode" + "calc-mode" + "ediff-mode" + "dired-mode" + "gud-mode" + "gdb-locals-mode" + "gdb-registers-mode" + "gdb-breakpoints-mode" + "gdb-threads-mode" + "gdb-frames-mode" + "gdb-inferior-io-mode" + "gdb-disassembly-mode" + "gdb-memory-mode" + "speedbar-mode" + )) + (add-to-list 'golden-ratio-exclude-modes m)) + + (add-to-list 'golden-ratio-exclude-buffer-regexp "^\\*[hH]elm.*") + + ;; golden-ratio-extra-commands + (dolist (f '(ace-window + ace-delete-window + ace-select-window + ace-swap-window + ace-maximize-window + avy-pop-mark + buf-move-left + buf-move-right + buf-move-up + buf-move-down + evil-avy-goto-word-or-subword-1 + evil-avy-goto-line + evil-window-delete + evil-window-split + evil-window-vsplit + evil-window-left + evil-window-right + evil-window-up + evil-window-down + evil-window-bottom-right + evil-window-top-left + evil-window-mru + evil-window-next + evil-window-prev + evil-window-new + evil-window-vnew + evil-window-rotate-upwards + evil-window-rotate-downwards + evil-window-move-very-top + evil-window-move-far-left + evil-window-move-far-right + evil-window-move-very-bottom + quit-window + select-window-0 + select-window-1 + select-window-2 + select-window-3 + select-window-4 + select-window-5 + select-window-6 + select-window-7 + select-window-8 + select-window-9 + windmove-left + windmove-right + windmove-up + windmove-down)) + (add-to-list 'golden-ratio-extra-commands f)) + + ;; golden-ratio-exclude-buffer-names + (dolist (n '(" *NeoTree*" + "*LV*" + " *which-key*")) + (add-to-list 'golden-ratio-exclude-buffer-names n)) + + (add-to-list 'golden-ratio-inhibit-functions + 'spacemacs/no-golden-ratio-guide-key) + + (spacemacs|diminish golden-ratio-mode " ⓖ" " g")))) + +(defun spacemacs-ui-visual/init-hl-todo () + (use-package hl-todo + :defer t + :init (spacemacs/add-to-hooks 'hl-todo-mode '(text-mode-hook + prog-mode-hook)))) + +(defun spacemacs-ui-visual/init-neotree () + (use-package neotree + :defer t + :commands neo-global--window-exists-p + :init + (progn + (setq neo-window-width 32 + neo-create-file-auto-open t + neo-banner-message "Press ? for neotree help" + neo-show-updir-line nil + neo-mode-line-type 'neotree + neo-smart-open t + neo-dont-be-alone t + neo-persist-show nil + neo-show-hidden-files t + neo-auto-indent-point t + neo-modern-sidebar t + neo-vc-integration nil) + + (spacemacs|define-transient-state neotree + :title "NeoTree Key Hints" + :doc " +Navigation^^^^ Actions^^ Visual actions/config^^^ +───────^^^^─────────────── ───────^^──────── ───────^^^──────────────── +[_L_] next sibling^^ [_c_] create [_TAB_] shrink/enlarge +[_H_] previous sibling^^ [_d_] delete [_|_] vertical split +[_J_] goto child^^ [_r_] rename [_-_] horizonatal split +[_K_] goto parent^^ [_R_] change root [_gr_] refresh^ +[_l_] open/expand^^ ^^ [_s_] hidden:^^^ %s(if neo-buffer--show-hidden-file-p \"on\" \"off\") +[_h_] up/collapse^^ ^^ ^^^ +[_j_] line down^^ ^^ ^^^ +[_k_] line up^^ ^^ ^^ +[_RET_] open ^^^^ [_?_] close hints +" + :bindings + ("RET" neotree-enter) + ("TAB" neotree-stretch-toggle) + ("|" neotree-enter-vertical-split) + ("-" neotree-enter-horizontal-split) + ("?" nil :exit t) + ("c" neotree-create-node) + ("d" neotree-delete-node) + ("gr" neotree-refresh) + ("h" spacemacs/neotree-collapse-or-up) + ("H" neotree-select-previous-sibling-node) + ("j" neotree-next-line) + ("J" neotree-select-down-node) + ("k" neotree-previous-line) + ("K" neotree-select-up-node) + ("l" spacemacs/neotree-expand-or-open) + ("L" neotree-select-next-sibling-node) + ("r" neotree-rename-node) + ("R" neotree-change-root) + ("s" neotree-hidden-file-toggle)) + + (defun spacemacs//neotree-key-bindings () + "Set the key bindings for a neotree buffer." + (evilified-state-evilify-map neotree-mode-map + :mode neotree-mode + :bindings + (kbd "TAB") 'neotree-stretch-toggle + (kbd "RET") 'neotree-enter + (kbd "|") 'neotree-enter-vertical-split + (kbd "-") 'neotree-enter-horizontal-split + (kbd "c") 'neotree-create-node + (kbd "d") 'neotree-delete-node + (kbd "gr") 'neotree-refresh + (kbd "h") 'spacemacs/neotree-collapse-or-up + (kbd "H") 'neotree-select-previous-sibling-node + (kbd "j") 'neotree-next-line + (kbd "J") 'neotree-select-down-node + (kbd "k") 'neotree-previous-line + (kbd "K") 'neotree-select-up-node + (kbd "l") 'spacemacs/neotree-expand-or-open + (kbd "L") 'neotree-select-next-sibling-node + (kbd "q") 'neotree-hide + (kbd "r") 'neotree-rename-node + (kbd "R") 'neotree-change-root + (kbd "?") 'spacemacs/neotree-transient-state/body + (kbd "s") 'neotree-hidden-file-toggle)) + + (spacemacs/set-leader-keys + "ft" 'neotree-toggle + "pt" 'neotree-find-project-root)) + :config + (spacemacs//neotree-key-bindings))) + +(defun spacemacs-ui-visual/init-popup ()) + +(defun spacemacs-ui-visual/init-popwin () + (use-package popwin + :config + (progn + (popwin-mode 1) + (spacemacs/set-leader-keys "wpm" 'popwin:messages) + (spacemacs/set-leader-keys "wpp" 'popwin:close-popup-window) + + ;; don't use default value but manage it ourselves + (setq popwin:special-display-config nil) + + ;; buffers that we manage + (push '("*Help*" :dedicated t :position bottom :stick t :noselect t :height 0.4) popwin:special-display-config) + (push '("*compilation*" :dedicated t :position bottom :stick t :noselect t :height 0.4) popwin:special-display-config) + (push '("*Shell Command Output*" :dedicated t :position bottom :stick t :noselect nil ) popwin:special-display-config) + (push '("*Async Shell Command*" :dedicated t :position bottom :stick t :noselect nil ) popwin:special-display-config) + (push '(" *undo-tree*" :dedicated t :position bottom :stick t :noselect nil :height 0.4) popwin:special-display-config) + (push '("*ert*" :dedicated t :position bottom :stick t :noselect nil ) popwin:special-display-config) + (push '("*grep*" :dedicated t :position bottom :stick t :noselect nil ) popwin:special-display-config) + (push '("*nosetests*" :dedicated t :position bottom :stick t :noselect nil ) popwin:special-display-config) + (push '("^\*WoMan.+\*$" :regexp t :position bottom ) popwin:special-display-config)))) + +(defun spacemacs-ui-visual/init-smooth-scrolling () + (setq scroll-preserve-screen-position t + scroll-margin 0 + scroll-conservatively (if dotspacemacs-smooth-scrolling 101 0)) + (spacemacs|add-toggle smooth-scrolling + :status (= 101 scroll-conservatively) + :on (spacemacs/enable-smooth-scrolling) + :off (spacemacs/disable-smooth-scrolling) + :documentation "Smooth scrolling." + :evil-leader "tv")) + +(defun spacemacs-ui-visual/init-spaceline () + (use-package spaceline-config + :init + (progn + (add-hook 'spacemacs-post-user-config-hook 'spaceline-compile) + (add-hook 'spacemacs-post-theme-change-hook + 'spacemacs/customize-powerline-faces) + (add-hook 'spacemacs-post-theme-change-hook 'powerline-reset) + (setq-default powerline-default-separator 'utf-8) + (spacemacs|do-after-display-system-init + (when (and (eq 'utf-8 powerline-default-separator)) + (setq-default powerline-default-separator 'wave)) + ;; seems to be needed to avoid weird graphical artefacts with the + ;; first graphical client + (require 'spaceline) + (spaceline-compile))) + :config + (progn + (spacemacs/customize-powerline-faces) + (setq spaceline-org-clock-p nil + spaceline-highlight-face-func 'spacemacs//evil-state-face) + ;; Segment toggles + (dolist (spec '((minor-modes "tmm") + (major-mode "tmM") + (version-control "tmv") + (new-version "tmV") + (point-position "tmp") + (org-clock "tmc"))) + (let* ((segment (car spec)) + (status-var (intern (format "spaceline-%S-p" segment)))) + (eval `(spacemacs|add-toggle ,(intern (format "mode-line-%S" segment)) + :status ,status-var + :on (setq ,status-var t) + :off (setq ,status-var nil) + :documentation ,(format "Show %s in the mode-line." + (replace-regexp-in-string + "-" " " (format "%S" segment))) + :evil-leader ,(cadr spec))))) + ;; unicode + (let ((unicodep (dotspacemacs|symbol-value + dotspacemacs-mode-line-unicode-symbols))) + (setq spaceline-window-numbers-unicode unicodep + spaceline-workspace-numbers-unicode unicodep)) + (add-hook 'spaceline-pre-hook 'spacemacs//prepare-diminish) + ;; New spacemacs version segment + (defpowerline spacemacs-powerline-new-version + (propertize + spacemacs-version-check-lighter + 'mouse-face 'mode-line-highlight + 'help-echo (format "New version %s | Click with mouse-1 to update" + spacemacs-new-version) + 'local-map (let ((map (make-sparse-keymap))) + (define-key map + [mode-line down-mouse-1] + (lambda (event) + (interactive "@e") + (if (yes-or-no-p + (format + (concat "Do you want to update to the newest " + "version %s ?") spacemacs-new-version)) + (progn + (spacemacs/switch-to-version + spacemacs-new-version)) + (message "Update aborted.")))) + map))) + (spaceline-define-segment new-version + (when spacemacs-new-version + (spacemacs-powerline-new-version + (spacemacs/get-new-version-lighter-face + spacemacs-version spacemacs-new-version)))) + (apply #'spaceline-spacemacs-theme + spacemacs-spaceline-additional-segments) + ;; Additional spacelines + (when (package-installed-p 'helm) + (spaceline-helm-mode t)) + (when (configuration-layer/package-usedp 'info+) + (spaceline-info-mode t)) + ;; Enable spaceline for buffers created before the configuration of + ;; spaceline + (spacemacs//set-powerline-for-startup-buffers)))) + +(defun spacemacs-ui-visual/init-zoom-frm () + (use-package zoom-frm + :commands (zoom-frm-unzoom + zoom-frm-out + zoom-frm-in) + :init + (progn + (spacemacs|define-transient-state zoom-frm + :title "Zoom Frame Transient State" + :doc " +[_+_/_=_] zoom frame in [_-_] zoom frame out [_0_] reset zoom [_q_] quit" + :bindings + ("+" spacemacs/zoom-frm-in) + ("=" spacemacs/zoom-frm-in) + ("-" spacemacs/zoom-frm-out) + ("0" spacemacs/zoom-frm-unzoom) + ("q" nil :exit t)) + (spacemacs/set-leader-keys "zf" 'spacemacs/zoom-frm-transient-state/body) + + ;; Font size, either with ctrl + mouse wheel + (global-set-key (kbd "") 'spacemacs/zoom-frm-in) + (global-set-key (kbd "") 'spacemacs/zoom-frm-out)))) diff --git a/layers/+spacemacs/spacemacs-ui/local/centered-cursor/centered-cursor-mode.el b/layers/+spacemacs/spacemacs-ui/local/centered-cursor/centered-cursor-mode.el new file mode 100644 index 0000000..1b69985 --- /dev/null +++ b/layers/+spacemacs/spacemacs-ui/local/centered-cursor/centered-cursor-mode.el @@ -0,0 +1,421 @@ +;;; centered-cursor-mode.el --- cursor stays vertically centered + +;; Copyright (C) 2007 André Riemann + +;; Author: André Riemann +;; Maintainer: André Riemann +;; Created: 2007-09-14 +;; Keywords: convenience + +;; URL: http://www.emacswiki.org/cgi-bin/wiki/centered-cursor-mode.el +;; Compatibility: only tested with GNU Emacs 23.0 +;; Version: 0.5.2 +;; Last-Updated: 2009-08-31 + +;; This file 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 file 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., 51 Franklin Street, Fifth Floor, Boston, +;; MA 02110-1301, USA. + +;;; Commentary: + +;; Makes the cursor stay vertically in a defined position (usually +;; centered). The vertical position can be altered, see key definition +;; below. + +;; To load put that in .emacs: +;; (require 'centered-cursor-mode) +;; To activate do: +;; M-x centered-cursor-mode +;; for buffer local or +;; M-x global-centered-cursor-mode +;; for global minor mode. +;; Also possible: put that in .emacs +;; (and +;; (require 'centered-cursor-mode) +;; (global-centered-cursor-mode +1)) +;; to always have centered-cursor-mode on in all buffers. + +;;; TODO: +;; - the code is a mess +;; - ccm-vpos-inverted doesn't work with ccm-vpos == 0, because first +;; position from top is 0 and from bottom -1 +;; - interactive first start isn't animated when calling global-... +;; because it starts the modes for each buffer and interactive-p fails +;; for that +;; - more bugs? + +;;; Change Log: +;; 2009-08-31 andre-r +;; * replaced window-body-height with window-text-height +;; (partially visible lines are not counted in window-text-height) +;; * bug fixed in ccm-vpos-recenter +;; (some parentheses where wrong after the last update) +;; 2009-02-23 andre-r +;; * some simplifications +;; 2009-02-22 andre-r +;; * some tips from Drew Adams: +;; - new local variable coding:utf-8 +;; - made recenter-sequence a defvar +;; - added groups scrolling and convenience +;; - replaced mouse-4 and mouse-5 with +;; mouse-wheel-up-event and mouse-wheel-down-event +;; - added scroll-bar-toolkit-scroll to ccm-ignored-commands +;; - made ccm-ignored-commands customisable +;; * removed a bug where it didn't work with more than one window +;; displaying the same buffer +;; * added function for page up and down scrolling +;; (standard ones didn't work well with this mode) +;; * made the animation delay customisable +;; * made the initial vertical position customisable +;; * made the behaviour at the end of the file customisable +;; 2008-02-02 andre-r +;; * fixed bug that led to wrong-type-argument +;; when opening a new buffer +;; * some other minor stuff +;; 2007-09-24 andre-r +;; * added global minor mode +;; 2007-09-21 andre-r +;; * not recentering at end of buffer +;; * defvar animate-first-start-p +;; 2007-09-14 andre-r +;; * inital release + +;; This file is *NOT* part of GNU Emacs. + +;;; Code: + +(defgroup centered-cursor nil + "Makes the cursor stay vertically in a defined position (usually centered). +Instead the cursor the text moves around the cursor." + :group 'scrolling + :group 'convenience + :link '(emacs-library-link :tag "Source Lisp File" "centered-cursor-mode.el") + :link '(url-link "http://www.emacswiki.org/cgi-bin/wiki/centered-cursor-mode.el")) + +(defcustom ccm-step-size 2 + "Step size when animated recentering." + :group 'centered-cursor + :tag "Animation step size" + :type 'integer) + +(defcustom ccm-step-delay 0.02 + "Delay between animation steps. +If you want a different animation speed." + :group 'centered-cursor + :tag "Animation step delay" + :type 'number) + +(defcustom ccm-ignored-commands '(mouse-drag-region + mouse-set-point + widget-button-click + scroll-bar-toolkit-scroll) + "After these commands recentering is ignored. +This is to prevent unintentional jumping (especially when mouse +clicking). Following commands (except the ignored ones) will +cause an animated recentering to give a feedback and not just +jumping to the center." + :group 'centered-cursor + :tag "Ignored commands" + :type '(repeat (symbol :tag "Command"))) + +(defcustom ccm-vpos-init '(round (window-text-height) 2) + "This is the screen line position where the cursor initially stays." + :group 'centered-cursor + :tag "Vertical cursor position" + :type '(choice (const :tag "Center" (round (window-text-height) 2)) + (const :tag "Golden ratio" (round (* 21 (window-text-height)) 34)) + (integer :tag "Lines from top" :value 10))) +(make-variable-buffer-local 'ccm-vpos-init) + +(defcustom ccm-vpos-inverted 1 + "Inverted vertical cursor position. +Defines if the initial vertical position `ccm-vpos-init' is +measured from the bottom instead from the top." + :group 'centered-cursor + :tag "Inverted cursor position" + :type '(choice (const :tag "Inverted" -1) + (const :tag "Not inverted" 1))) +(make-variable-buffer-local 'ccm-vpos-inverted) + +(defcustom ccm-recenter-at-end-of-file nil + "Recenter at the end of the file. +If non-nil the end of the file is recentered. If nil the end of +the file stays at the end of the window." + :group 'centered-cursor + :tag "Recenter at EOF" + :type '(choice (const :tag "Don't recenter at the end of the file" nil) + (const :tag "Recenter at the end of the file" t))) +(make-variable-buffer-local 'ccm-recenter-end-of-file) + +(defvar ccm-vpos nil + "This is the screen line position where the cursor stays.") +(make-variable-buffer-local 'ccm-vpos) + +(defvar animate-first-start-p nil + "Whether or not to animate at first start. It is set to nil, if +centered-cursor-mode is called non-interactively.") +(make-variable-buffer-local 'animate-first-start-p) + +(defvar recenter-sequence nil + "Before animated recentering a list is generated first with positions +to successively recenter to") +(make-variable-buffer-local 'recenter-sequence) + +(defvar ccm-map + (let ((ccm-map (make-sparse-keymap))) + (define-key ccm-map [(control meta -)] 'ccm-vpos-up) + (define-key ccm-map [(control meta +)] 'ccm-vpos-down) + (define-key ccm-map [(control meta =)] 'ccm-vpos-down) + (define-key ccm-map [(control meta ?0)] 'ccm-vpos-recenter) + (when (bound-and-true-p mouse-wheel-mode) + (mapc (lambda (key) + (define-key ccm-map key 'ccm-mwheel-scroll)) + (list (vector mouse-wheel-up-event) + (vector mouse-wheel-down-event) + (vector (list 'control mouse-wheel-up-event)) + (vector (list 'control mouse-wheel-down-event)) + (vector (list 'shift mouse-wheel-up-event)) + (vector (list 'shift mouse-wheel-down-event))))) + (define-key ccm-map [(meta v)] 'ccm-scroll-down) + (define-key ccm-map [(control v)] 'ccm-scroll-up) + (define-key ccm-map [prior] 'ccm-scroll-down) + (define-key ccm-map [next] 'ccm-scroll-up) + ccm-map) + "Keymap used in centered-cursor-mode.") + + +(defun ccm-mwheel-scroll (event) + "Very similar to `mwheel-scroll', but does not use `scroll-down' +and `scroll-up' but `previous-line' and `next-line', that is, the +cursor is moved and thus the text in the window is scrolled +due to `recenter'. + +The customizable variable `mouse-wheel-scroll-amount' is used to +determine how much to scroll, where nil instead of a number means +the same as in mwheel-scroll, scroll by a near full screen. + +This command exists, because mwheel-scroll caused strange +behaviour with automatic recentering." +;; (interactive (list last-input-event)) + (interactive "e") + (let* ((mods (delq 'click (delq 'double (delq 'triple (event-modifiers event))))) + (amt (assoc mods mouse-wheel-scroll-amount))) + ;;(message "%S" mods) + (if amt + (setq amt (or (cdr amt) + (- (window-text-height) + next-screen-context-lines))) + (let ((list-elt mouse-wheel-scroll-amount)) + (while (consp (setq amt (pop list-elt)))))) + (if mouse-wheel-follow-mouse + (select-window (posn-window (event-start event)))) + (let ((button (mwheel-event-button event))) + (cond + ((eq button mouse-wheel-down-event) + (forward-line (- amt))) + ;;(princ amt)) + ((eq button mouse-wheel-up-event) + (forward-line amt)) + ;;(princ amt)) + (t (error "Bad binding in ccm-mwheel-scroll")))))) + +(defun ccm-scroll-down (&optional arg) + "Replaces `scroll-down' because with scroll-down +`centered-cursor-mode' sometimes doesn't reach the top of the +buffer. This version actually moves the cursor with +`previous-line'. Since with centered-cursor-mode the cursor is in +a fixed position the movement appears as page up." + (interactive "P") + (let ((amt (or arg (- (window-text-height) + next-screen-context-lines)))) + (forward-line (- amt)))) + +(defun ccm-scroll-up (&optional arg) + "Replaces `scroll-up' to be consistent with `ccm-scroll-down'. +This version actually moves the cursor with `previous-line'. +Since with centered-cursor-mode the cursor is in a fixed position +the movement appears as page up." + (interactive "P") + (let ((amt (or arg (- (window-text-height) + next-screen-context-lines)))) + (forward-line amt))) + + +(defun ccm-vpos-down (arg) + "Adjust the value of the screen line (where the cursor stays) by arg. +Negative values for arg are possible. Just the variable ccm-vpos +is set." + (interactive "p") + (or arg (setq arg 1)) + (let ((new-pos (if (< ccm-vpos 0) + (- ccm-vpos arg) + (+ ccm-vpos arg))) + ;; see pos-visible-in-window-p + (vpos-max (if (< ccm-vpos 0) + -1 + (- (window-text-height) 1))) + (vpos-min (if (< ccm-vpos 0) + (- (window-text-height)) + 0))) + (setq ccm-vpos + (cond + ((< new-pos vpos-min) + vpos-min) + ((> new-pos vpos-max) + vpos-max) + (t + new-pos))))) + +(defun ccm-vpos-up (arg) + "See `ccm-vpos-down'." + (interactive "p") + (or arg (setq arg 1)) + (ccm-vpos-down (- arg))) + +(defun ccm-vpos-recenter () + "Set the value of the screen line (where the cursor stays) in +the center. Just the variable ccm-vpos is set." + (interactive) + (if (equal (current-buffer) + (window-buffer (selected-window))) + (setq ccm-vpos (* (eval ccm-vpos-init) + ccm-vpos-inverted)))) + +(defun ccm-position-cursor () + "Do the actual recentering at the position `ccm-vpos'." + (unless (member this-command ccm-ignored-commands) + (unless ccm-vpos + (ccm-vpos-recenter)) + (unless (minibufferp (current-buffer)) + (if (equal (current-buffer) + (window-buffer (selected-window))) + (let* ((current-line + (if (< ccm-vpos 0) + ;; one-based, from bottom, negative + (- (count-lines (point) + ;; window-end is sometimes < 0 + ;; when opening a help buffer + (if (> (window-end) 0) + (window-end) + 1))) + ;; zero-based, from top, positive + (+ (count-lines (window-start) (point)) + ;; count-lines returns different value in column 0 + (if (= (current-column) 0) 0 -1)))) + (diff (- ccm-vpos current-line)) + (step-size ccm-step-size) + (step-delay ccm-step-delay) + (vpos-inverted ccm-vpos-inverted) + (recenter-at-end-of-file ccm-recenter-at-end-of-file)) + + (let* ((bottom-vpos (if (< ccm-vpos 0) + (- ccm-vpos) + (- (window-text-height) ccm-vpos))) + (correction (save-excursion + (if (or (= (point) (point-max)) + (progn + (goto-char (point-max)) + (zerop (current-column)))) + 1 0))) + ;; lines from point to end of buffer + (bottom-lines (+ (count-lines (point) (point-max)) + correction))) + + ;; only animate if point was moved rather far away + ;; before by a mouseclick (see ccm-ignored-commands) + ;; or if minor mode is just entered interactively + (if (not (and (> (abs diff) 4) + (or (member last-command ccm-ignored-commands) + animate-first-start-p))) + + (recenter (if (and (< bottom-lines bottom-vpos) + (not recenter-at-end-of-file)) + ;; if near the bottom, recenter in the + ;; negative screen line that equals the + ;; bottom buffer line, i.e. if we are in + ;; the second last line (-2) of the + ;; buffer, the cursor will be recentered + ;; in -2 + (- bottom-lines) + ccm-vpos)) + + (setq animate-first-start-p nil) + ;; first build a list with positions to successively recenter to + (setq recenter-sequence + ;; reverse: because we build the list not FROM -> TO but + ;; TO -> FROM because if step size in number-sequence is + ;; bigger than one, TO might not included, that means the + ;; ccm-vpos would not be reached + ;; cdr: don't recenter the current-line + (if (and (< bottom-lines bottom-vpos) + (not recenter-at-end-of-file)) + ;; this one is for animation near the bottom + (cdr (reverse (number-sequence + (- bottom-lines) + (if (< ccm-vpos 0) + current-line + (- (- (window-text-height) current-line))) + (* (/ diff (abs diff)) (- step-size))))) + (cdr (reverse (number-sequence + ccm-vpos + current-line + (* (/ diff (abs diff)) (- step-size))))))) + ;; (message "%d %d %d (%d): %S" current-line ccm-vpos bottom-lines diff recenter-sequence) + (while recenter-sequence + ;; actual animation + (recenter (pop recenter-sequence)) + (if (car recenter-sequence) (sit-for step-delay t)))))))))) + +(defun ccm-first-start (animate) + "Called from centered-cursor-mode. Animate at first start, if +centered-cursor-mode is called interactively." + (let ((animate-first-start-p animate)) + (ccm-vpos-recenter) + (ccm-position-cursor))) + +;;(defalias 'ccm 'centered-cursor-mode) +(define-minor-mode centered-cursor-mode + "Makes the cursor stay vertically in a defined +position (usually centered)." + :init-value nil +;; :lighter nil + :lighter " ¢" + :keymap ccm-map + (cond + (centered-cursor-mode + (ccm-first-start (interactive-p)) + (add-hook 'post-command-hook 'ccm-position-cursor t t) + (add-hook 'window-configuration-change-hook 'ccm-vpos-recenter t t)) + (t + (remove-hook 'post-command-hook 'ccm-position-cursor t) + (remove-hook 'window-configuration-change-hook 'ccm-vpos-recenter t)))) + + +(define-global-minor-mode global-centered-cursor-mode centered-cursor-mode + centered-cursor-mode) + +(provide 'centered-cursor-mode) + +;;; Help: +;; (info "(elisp)Defining Minor Modes") +;; (info "(elisp)Screen Lines") +;; (info "(elisp)Hooks") +;; (info "(elisp)Customization") +;; (find-function 'mwheel-scroll) + +;; Local Variables: +;; coding: utf-8 +;; End: + +;;; centered-cursor-mode.el ends here diff --git a/layers/+spacemacs/spacemacs-ui/packages.el b/layers/+spacemacs/spacemacs-ui/packages.el new file mode 100644 index 0000000..f08937e --- /dev/null +++ b/layers/+spacemacs/spacemacs-ui/packages.el @@ -0,0 +1,308 @@ +;;; packages.el --- Spacemacs UI Layer packages File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq spacemacs-ui-packages + '(ace-link + (centered-cursor :location local) + desktop + (doc-view :location built-in) + flx-ido + info+ + open-junk-file + paradox + restart-emacs + window-numbering)) + +;; Initialization of packages + +(defun spacemacs-ui/init-ace-link () + (use-package ace-link + :commands spacemacs/ace-buffer-links + :init + (progn + (define-key spacemacs-buffer-mode-map "o" 'spacemacs/ace-buffer-links) + (with-eval-after-load 'info + (define-key Info-mode-map "o" 'ace-link-info)) + (with-eval-after-load 'help-mode + (define-key help-mode-map "o" 'ace-link-help)) + (with-eval-after-load 'eww + (define-key eww-link-keymap "o" 'ace-link-eww) + (define-key eww-mode-map "o" 'ace-link-eww))) + :config + (progn + (defvar spacemacs--link-pattern "~?/.+\\|\s\\[") + (defun spacemacs//collect-spacemacs-buffer-links () + (let ((end (window-end)) + points) + (save-excursion + (goto-char (window-start)) + (while (re-search-forward spacemacs--link-pattern end t) + (push (+ (match-beginning 0) 1) points)) + (nreverse points)))) + (defun spacemacs/ace-buffer-links () + "Ace jump to links in `spacemacs' buffer." + (interactive) + (let ((res (avy-with spacemacs/ace-buffer-links + (avy--process + (spacemacs//collect-spacemacs-buffer-links) + #'avy--overlay-pre)))) + (when res + (goto-char (1+ res)) + (widget-button-press (point)))))))) + +(defun spacemacs-ui/init-centered-cursor () + (use-package centered-cursor-mode + :commands (centered-cursor-mode + global-centered-cursor-mode) + :init + (progn + (spacemacs|add-toggle centered-point + :mode centered-cursor-mode + :documentation + "Keep point at the center of the window." + :evil-leader "t-") + (spacemacs|add-toggle centered-point-globally + :mode global-centered-cursor-mode + :documentation + "Keep point at the center of the window globally." + :evil-leader "t C--")) + :config + (progn + (setq ccm-recenter-at-end-of-file t + ccm-ignored-commands '(mouse-drag-region + mouse-set-point + widget-button-click + scroll-bar-toolkit-scroll + evil-mouse-drag-region)) + (spacemacs|diminish centered-cursor-mode " ⊝" " -")))) + +(defun spacemacs-ui/init-desktop () + (use-package desktop + :defer t + :init + (setq desktop-dirname spacemacs-cache-directory) + :config + (push spacemacs-cache-directory desktop-path))) + +(defun spacemacs-ui/init-doc-view () + (use-package doc-view + :defer t + :init + (evilified-state-evilify doc-view-mode doc-view-mode-map + "/" 'spacemacs/doc-view-search-new-query + "?" 'spacemacs/doc-view-search-new-query-backward + "gg" 'doc-view-first-page + "G" 'spacemacs/doc-view-goto-page + "gt" 'doc-view-goto-page + "h" 'doc-view-previous-page + "j" 'doc-view-next-line-or-next-page + "k" 'doc-view-previous-line-or-previous-page + "K" 'doc-view-kill-proc-and-buffer + "l" 'doc-view-next-page + "n" 'doc-view-search + "N" 'doc-view-search-backward + (kbd "C-d") 'doc-view-scroll-up-or-next-page + (kbd "C-k") 'doc-view-kill-proc + (kbd "C-u") 'doc-view-scroll-down-or-previous-page) + :config + (progn + (defun spacemacs/doc-view-search-new-query () + "Initiate a new query." + (interactive) + (doc-view-search 'newquery)) + + (defun spacemacs/doc-view-search-new-query-backward () + "Initiate a new query." + (interactive) + (doc-view-search 'newquery t)) + + (defun spacemacs/doc-view-goto-page (&optional count) + (interactive (list + (when current-prefix-arg + (prefix-numeric-value current-prefix-arg)))) + (if (null count) + (doc-view-last-page) + (doc-view-goto-page count))) + + ;; fixed a weird issue where toggling display does not + ;; swtich to text mode + (defadvice doc-view-toggle-display + (around spacemacs/doc-view-toggle-display activate) + (if (eq major-mode 'doc-view-mode) + (progn + ad-do-it + (text-mode) + (doc-view-minor-mode)) + ad-do-it))))) + +(defun spacemacs-ui/init-flx-ido () + (use-package flx-ido + :init (flx-ido-mode 1))) + +(defun spacemacs-ui/init-info+ () + (use-package info+ + :defer t + :init + (progn + (with-eval-after-load 'info + (require 'info+)) + (setq Info-fontify-angle-bracketed-flag nil)))) + +(defun spacemacs-ui/init-open-junk-file () + (use-package open-junk-file + :defer t + :commands (open-junk-file) + :init + (setq open-junk-file-format (concat spacemacs-cache-directory "junk/%Y/%m/%d-%H%M%S.")) + (defun spacemacs/open-junk-file (&optional arg) + "Open junk file using helm or ivy. + +Interface choice depends on whether the `ivy' layer is used or +not. + +When ARG is non-nil search in junk files." + (interactive "P") + (let* ((fname (format-time-string open-junk-file-format (current-time))) + (rel-fname (file-name-nondirectory fname)) + (junk-dir (file-name-directory fname)) + (default-directory junk-dir)) + (cond ((and arg (configuration-layer/layer-usedp 'ivy)) + (spacemacs/counsel-search dotspacemacs-search-tools nil junk-dir)) + ((configuration-layer/layer-usedp 'ivy) + (require 'counsel) + (counsel-find-file rel-fname)) + (arg + (require 'helm) + (let (helm-ff-newfile-prompt-p) + (spacemacs/helm-files-smart-do-search))) + (t + (require 'helm) + (let (helm-ff-newfile-prompt-p) + (helm-find-files-1 fname)))))) + (spacemacs/set-leader-keys "fJ" 'spacemacs/open-junk-file))) + +(defun spacemacs-ui/init-paradox () + (use-package paradox + :commands paradox-list-packages + :init + (progn + (setq paradox-execute-asynchronously nil) + (defun spacemacs/paradox-list-packages () + "Load depdendencies for auth and open the package list." + (interactive) + (require 'epa-file) + (require 'auth-source) + (when (and (not (boundp 'paradox-github-token)) + (file-exists-p "~/.authinfo.gpg")) + (let ((authinfo-result (car (auth-source-search + :max 1 + :host "github.com" + :port "paradox" + :user "paradox" + :require '(:secret))))) + (let ((paradox-token (plist-get authinfo-result :secret))) + (setq paradox-github-token (if (functionp paradox-token) + (funcall paradox-token) + paradox-token))))) + (paradox-list-packages nil)) + + (evilified-state-evilify paradox-menu-mode paradox-menu-mode-map + "H" 'paradox-menu-quick-help + "J" 'paradox-next-describe + "K" 'paradox-previous-describe + "L" 'paradox-menu-view-commit-list + "o" 'paradox-menu-visit-homepage) + (spacemacs/set-leader-keys + "ak" 'spacemacs/paradox-list-packages)))) + +(defun spacemacs-ui/init-restart-emacs() + (use-package restart-emacs + :defer t + :init + (defun spacemacs/restart-emacs (&optional args) + "Restart emacs." + (interactive) + (setq spacemacs-really-kill-emacs t) + (restart-emacs args)) + (defun spacemacs/restart-emacs-resume-layouts (&optional args) + "Restart emacs and resume layouts." + (interactive) + (spacemacs/restart-emacs (cons "--resume-layouts" args))) + (defun spacemacs/restart-emacs-debug-init (&optional args) + "Restart emacs and enable debug-init." + (interactive) + (spacemacs/restart-emacs (cons "--debug-init" args))) + (defun spacemacs/restart-stock-emacs-with-packages (packages &optional args) + "Restart emacs without the spacemacs configuration, enable +debug-init and load the given list of packages." + (interactive + (progn + (unless package--initialized + (package-initialize t)) + (let ((packages (append (mapcar 'car package-alist) + (mapcar 'car package-archive-contents) + (mapcar 'car package--builtins)))) + (setq packages (mapcar 'symbol-name packages)) + (let ((val (completing-read-multiple "Packages to load (comma separated): " + packages nil t))) + `(,val))))) + (let ((load-packages-string (mapconcat (lambda (pkg) (format "(use-package %s)" pkg)) + packages " "))) + (spacemacs/restart-emacs-debug-init + (append (list "-q" "--execute" + (concat "(progn (package-initialize) " + "(require 'use-package)" + load-packages-string ")")) + args)))) + (spacemacs/set-leader-keys + "qd" 'spacemacs/restart-emacs-debug-init + "qD" 'spacemacs/restart-stock-emacs-with-packages + "qr" 'spacemacs/restart-emacs-resume-layouts + "qR" 'spacemacs/restart-emacs))) + +(defun spacemacs-ui/init-window-numbering () + (use-package window-numbering + :config + (progn + (when (configuration-layer/package-usedp 'spaceline) + (defun window-numbering-install-mode-line (&optional position) + "Do nothing, the display is handled by the powerline.")) + (setq window-numbering-auto-assign-0-to-minibuffer nil) + (spacemacs/set-leader-keys + "0" 'select-window-0 + "1" 'select-window-1 + "2" 'select-window-2 + "3" 'select-window-3 + "4" 'select-window-4 + "5" 'select-window-5 + "6" 'select-window-6 + "7" 'select-window-7 + "8" 'select-window-8 + "9" 'select-window-9) + (window-numbering-mode 1)) + + ;; make sure neotree is always 0 + (defun spacemacs//window-numbering-assign () + "Custom number assignment for neotree." + (when (and (boundp 'neo-buffer-name) + (string= (buffer-name) neo-buffer-name) + ;; in case there are two neotree windows. Example: when + ;; invoking a transient state from neotree window, the new + ;; window will show neotree briefly before displaying the TS, + ;; causing an error message. the error is eliminated by + ;; assigning 0 only to the top-left window + (eq (selected-window) (window-at 0 0))) + 0)) + + ;; using lambda to work-around a bug in window-numbering, see + ;; https://github.com/nschum/window-numbering.el/issues/10 + (setq window-numbering-assign-func + (lambda () (spacemacs//window-numbering-assign))))) diff --git a/layers/+tags/cscope/README.org b/layers/+tags/cscope/README.org new file mode 100644 index 0000000..5c10a5b --- /dev/null +++ b/layers/+tags/cscope/README.org @@ -0,0 +1,71 @@ +#+TITLE: Cscope layer + +[[file:img/cscope.jpg]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#cscope][Cscope]] + - [[#pycscope][PyCscope]] + - [[#usage][Usage]] + - [[#key-bindings][Key bindings]] + +* Description +This layer provides bindings for using [[http://cscope.sourceforge.net][Cscope]] and [[https://github.com/portante/pycscope][PyCscope]] in Spacemacs. + +=Cscope= provides indexing and searching capabilities for C and C++ code. +=PyCscope= extends these capabilities for Python code as well. See +[[https://github.com/OpenGrok/OpenGrok/wiki/Comparison-with-Similar-Tools][here]] for a comparison between =Cscope= and other similar tools (such as gtags). + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =cscope= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Cscope +Install =Cscope= through your package manager, or download it from the +[[http://cscope.sourceforge.net/#downloads][website]] and build it from source. + +From package manager (for example, Ubuntu): + +#+BEGIN_SRC sh +sudo apt-get install cscope +#+END_SRC + +From source: + +#+BEGIN_SRC sh +tar xvf cscope-15.8b +cd cscope-15.8b +./configure +make +sudo make install +#+END_SRC + +** PyCscope +Install PyCscope through pip: + +#+BEGIN_SRC sh +pip install pycscope +#+END_SRC + +* Usage +Before using any helm-cscope commands, remember to create a Cscope index file. +Do it by running the command =cscope-index-files= for C and C++ projects, or the +command =cscope/run-pycscope= for Python projects, bound to ~SPC m g i~. + +* Key bindings + +| Key Binding | Description | +|-------------+-----------------------------------------------| +| ~SPC m g c~ | find which functions are called by a function | +| ~SPC m g C~ | find where a function is called | +| ~SPC m g d~ | find global definition of a symbol | +| ~SPC m g e~ | search regular expression | +| ~SPC m g f~ | find a file | +| ~SPC m g F~ | find which files include a file | +| ~SPC m g i~ | create Cscope index | +| ~SPC m g r~ | find references of a symbol | +| ~SPC m g x~ | search text | diff --git a/layers/+tags/cscope/img/cscope.jpg b/layers/+tags/cscope/img/cscope.jpg new file mode 100644 index 0000000..90dcb2e Binary files /dev/null and b/layers/+tags/cscope/img/cscope.jpg differ diff --git a/layers/+tags/cscope/packages.el b/layers/+tags/cscope/packages.el new file mode 100644 index 0000000..a73ed9d --- /dev/null +++ b/layers/+tags/cscope/packages.el @@ -0,0 +1,60 @@ +;;; packages.el --- cscope Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq cscope-packages + '( + (helm-cscope :toggle (configuration-layer/package-usedp 'helm)) + xcscope + )) + +(defun cscope/init-xcscope () + (use-package xcscope + :commands (cscope-index-files cscope/run-pycscope) + :init + (progn + ;; for python projects, we don't want xcscope to rebuild the databse, + ;; because it uses cscope instead of pycscope + (setq cscope-option-do-not-update-database t + cscope-display-cscope-buffer nil) + + (defun cscope//safe-project-root () + "Return project's root, or nil if not in a project." + (and (fboundp 'projectile-project-root) + (projectile-project-p) + (projectile-project-root))) + + (defun cscope/run-pycscope (directory) + (interactive (list (file-name-as-directory + (read-directory-name "Run pycscope in directory: " + (cscope//safe-project-root))))) + (let ((default-directory directory)) + (shell-command + (format "pycscope -R -f '%s'" + (expand-file-name "cscope.out" directory)))))))) + +(defun cscope/init-helm-cscope () + (use-package helm-cscope + :defer t + :init + (defun spacemacs/setup-helm-cscope (mode) + "Setup `helm-cscope' for MODE" + (spacemacs/set-leader-keys-for-major-mode mode + "gc" 'helm-cscope-find-called-function + "gC" 'helm-cscope-find-calling-this-funtcion + "gd" 'helm-cscope-find-global-definition + "ge" 'helm-cscope-find-egrep-pattern + "gf" 'helm-cscope-find-this-file + "gF" 'helm-cscope-find-files-including-file + "gr" 'helm-cscope-find-this-symbol + "gx" 'helm-cscope-find-this-text-string)) + :config + (defadvice helm-cscope-find-this-symbol (before cscope/goto activate) + (evil--jumps-push)))) diff --git a/layers/+tags/gtags/README.org b/layers/+tags/gtags/README.org new file mode 100644 index 0000000..bc0d378 --- /dev/null +++ b/layers/+tags/gtags/README.org @@ -0,0 +1,252 @@ +#+TITLE: Helm Gtags layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#install][Install]] + - [[#gnu-global-gtags][GNU Global (gtags)]] + - [[#install-on-osx-using-homebrew][Install on OSX using Homebrew]] + - [[#install-on-nix-from-source][Install on *nix from source]] + - [[#install-recommended-dependencies][Install recommended dependencies]] + - [[#install-with-recommended-features][Install with recommended features]] + - [[#configure-your-environment-to-use-pygments-and-ctags][Configure your environment to use pygments and ctags]] + - [[#emacs-configuration][Emacs Configuration]] + - [[#disabling-by-default][Disabling by default]] + - [[#usage][Usage]] + - [[#language-support][Language Support]] + - [[#built-in-languages][Built-in languages]] + - [[#exuberant-ctags-languages][Exuberant ctags languages]] + - [[#universal-ctags-languages][Universal ctags languages]] + - [[#pygments-languages-plus-symbol-and-reference-tags][Pygments languages (plus symbol and reference tags)]] + - [[#eldoc-integration][Eldoc integration]] + - [[#key-bindings][Key bindings]] + +* Description +=helm-gtags= and =ggtags= are clients for GNU Global. GNU Global is a source +code tagging system that allows querying symbol locations in source code, such +as definitions or references. Adding the =gtags= layer enables both of these +modes. + +* Features + +- Select any tag in a project retrieved by gtags +- Resume previous helm-gtags session +- Jump to a location based on context +- Find definitions +- Find references +- Present tags in current function only +- Create a tag database +- Jump to definitions in file +- Show stack of visited locations +- Manually update tag database +- Jump to next location in context stack +- Jump to previous location in context stack +- Jump to a file in tag database +- Enables =eldoc= in modes that otherwise might not support it. +- Enables =company complete= in modes that otherwise might not support it. + +* Install + +** GNU Global (gtags) +To use gtags, you first have to install [[https://www.gnu.org/software/global/download.html][GNU Global]]. + +You can install =global= from the software repository of your OS; however, many +OS distributions are out of date, and you will probably be missing support for +=pygments= and =exuberant ctags=, and thus support for many languages. We +recommend installing from source. If not for example to install on Ubuntu: + +#+begin_src sh + sudo apt-get install global +#+end_src + +*** Install on OSX using Homebrew + +#+begin_src sh options + brew install global --with-pygments --with-ctags +#+end_src + +*** Install on *nix from source +**** Install recommended dependencies +To take full advantage of global you should install 2 extra packages in +addition to global: pygments and ctags (exuberant). You can do this using +your normal OS package manager, e.g., on Ubuntu + +#+BEGIN_SRC sh + sudo apt-get install exuberant-ctags python-pygments +#+END_SRC + +or e.g., Archlinux: + +#+BEGIN_SRC sh + sudo pacman -S ctags python-pygments +#+END_SRC + +**** Install with recommended features +Download the latest tar.gz archive, then run these commands: + +#+BEGIN_SRC sh + tar xvf global-6.5.3.tar.gz + cd global-6.5.3 + ./configure --with-exuberant-ctags=/usr/bin/ctags + make + sudo make install +#+END_SRC + +**** Configure your environment to use pygments and ctags +To be able to use =pygments= and =ctags=, you need to copy the sample +=gtags.conf= either to =/etc/gtags.conf= or =$HOME/.globalrc=. For example: + +#+begin_src sh + cp gtags.conf ~/.globalrc +#+end_src + +Additionally you should define GTAGSLABEL in your shell startup file e.g. +with sh/ksh: + +#+begin_src sh + echo export GTAGSLABEL=pygments >> .profile +#+end_src + +** Emacs Configuration +To use this configuration layer, add it to your =~/.spacemacs=. You +will need to add =gtags= to the existing =dotspacemacs-configuration-layers=. + +#+begin_src emacs-lisp + (setq dotspacemacs-configuration-layers + '( ;; ... + gtags + ;; ... + )) +#+end_src + +*** Disabling by default +If =ggtags-mode= is too intrusive you can disable it by default, by setting the +layer variable =gtags-enable-by-default= to =nil=. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers + '((gtags :variables gtags-enable-by-default t))) +#+END_SRC + +This variable can also be set as a file-local or directory-local variable for +additional control per project. + +* Usage + +Before using the =gtags=, remember to create a GTAGS database by the following +methods: + +- From within Emacs, runs the command =helm-gtags-create-tags=, which is bound + to ~SPC m g c~. If the language is not directly supported by GNU Global, you + can choose =ctags= or =pygments= as a backend to generate tag database. + +- From inside terminal, runs gtags at your project root in terminal: + +#+BEGIN_SRC sh + cd /path/to/project/root + gtags +#+END_SRC + +If the language is not directly supported by =gtags=, and you have not set the +GTAGSLABEL environment variable, use this command instead: + +#+BEGIN_SRC sh + gtags --gtagslabel=pygments +#+END_SRC + +*** Language Support +**** Built-in languages +If you do not have =ctags= or =pygments= enabled gtags will only produce +tags for the following languages: + +- asm +- c/c++ +- java +- php +- yacc + +**** Exuberant ctags languages +If you have enabled =exuberant ctags= and use that as the backend (i.e., +GTAGSLABEL=ctags or --gtagslabel=ctags) the following additional languages +will have tags created for them: + +- c# +- erlang +- javascript +- common-lisp +- emacs-lisp +- lua +- ocaml +- python +- ruby +- scheme +- vimscript +- windows-scripts (.bat .cmd files) + +**** Universal ctags languages +If instead you installed you the newer/beta =universal ctags= and use that +as the backend (i.e., GTAGSLABEL=ctags or --gtagslabel=ctags) the following +additional languages will have tags created for them: + +- clojure +- d +- go +- rust + +**** Pygments languages (plus symbol and reference tags) +In order to look up symbol references for any language not in the built in +parser you must use the pygments backend. When this backend is used global +actually uses both ctags and pygments to find the definitions and uses of +functions and variables as well as "other symbols". + +If you enabled pygments (the best choice) and use that as the backend (i.e., +GTAGSLABEL=pygments or --gtagslabel=pygments) the following additional +languages will have tags created for them: + +- elixir +- fsharp +- haskell +- octave +- racket +- scala +- shell-scripts +- tex + +** Eldoc integration +This layer also integrates =ggtags= for its Eldoc feature. That means, when +writing code, you can look at the minibuffer (at the bottom) and see variable +and function definition of the symbol the cursor is on. However, this feature is +only activated for programming modes that are not one of these languages: + +- C +- C++ +- Common Lisp +- Emacs Lisp +- Python +- Ruby + +Since these modes have better Eldoc integration already. + +In addition, if output from =compile= (bound to ~SPC c C~), =shell-command= +(bound to ~SPC !~ and ~M-!~) or =async-shell-command= (bound to ~M-&~) commands +contains symbol in your project, you move cursor on such symbol and use any of +the gtags commands. + +* Key bindings + +| Key Binding | Description | +|-------------+-----------------------------------------------------------| +| ~SPC m g c~ | create a tag database | +| ~SPC m g f~ | jump to a file in tag database | +| ~SPC m g g~ | jump to a location based on context | +| ~SPC m g G~ | jump to a location based on context (open another window) | +| ~SPC m g d~ | find definitions | +| ~SPC m g i~ | present tags in current function only | +| ~SPC m g l~ | jump to definitions in file | +| ~SPC m g n~ | jump to next location in context stack | +| ~SPC m g p~ | jump to previous location in context stack | +| ~SPC m g r~ | find references | +| ~SPC m g R~ | resume previous helm-gtags session | +| ~SPC m g s~ | select any tag in a project retrieved by gtags | +| ~SPC m g S~ | show stack of visited locations | +| ~SPC m g u~ | manually update tag database | diff --git a/layers/+tags/gtags/config.el b/layers/+tags/gtags/config.el new file mode 100644 index 0000000..1829136 --- /dev/null +++ b/layers/+tags/gtags/config.el @@ -0,0 +1,20 @@ +;;; config.el --- gtags configuration File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar gtags-enable-by-default t + "Whether or not to enable ggtags-mode.") + +(spacemacs|define-jump-handlers tcl-mode) +(spacemacs|define-jump-handlers vhdl-mode) +(spacemacs|define-jump-handlers awk-mode) +(spacemacs|define-jump-handlers dired-mode) +(spacemacs|define-jump-handlers compilation-mode) +(spacemacs|define-jump-handlers shell-mode) diff --git a/layers/+tags/gtags/funcs.el b/layers/+tags/gtags/funcs.el new file mode 100644 index 0000000..de37953 --- /dev/null +++ b/layers/+tags/gtags/funcs.el @@ -0,0 +1,65 @@ +;;; funcs.el --- gtags functions File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun helm-gtags-dwim-other-window () + "helm-gtags-dwim in the other window" + (interactive) + (let ((helm-gtags--use-otherwin t) + (split-height-threshold nil) + (split-width-threshold 140)) + (helm-gtags-dwim))) + +(defun spacemacs/helm-gtags-maybe-dwim () + "Runs `helm-gtags-dwim' if `gtags-enable-by-default' is on. +Otherwise does nothing." + (interactive) + (when gtags-enable-by-default + (call-interactively 'helm-gtags-dwim))) + +(defun spacemacs/helm-gtags-define-keys-for-mode (mode) + "Define key bindings for the specific MODE." + (when (fboundp mode) + ;; The functionality of `helm-gtags-mode' is pretty much entirely superseded + ;; by `ggtags-mode', so we don't add this hook + ;; (let ((hook (intern (format "%S-hook" mode)))) + ;; (add-hook hook 'helm-gtags-mode)) + + ;; `helm-gtags-dwim' is added to the end of the mode-specific jump handlers + ;; Some modes have more sophisticated jump handlers that go to the beginning + ;; It might be possible to add `helm-gtags-dwim' instead to the default + ;; handlers, if it does a reasonable job in ALL modes. + (let ((jumpl (intern (format "spacemacs-jump-handlers-%S" mode)))) + (add-to-list jumpl 'spacemacs/helm-gtags-maybe-dwim 'append)) + + (spacemacs/set-leader-keys-for-major-mode mode + "gc" 'helm-gtags-create-tags + "gd" 'helm-gtags-find-tag + "gD" 'helm-gtags-find-tag-other-window + "gf" 'helm-gtags-select-path + "gG" 'helm-gtags-dwim-other-window + "gi" 'helm-gtags-tags-in-this-function + "gl" 'helm-gtags-parse-file + "gn" 'helm-gtags-next-history + "gp" 'helm-gtags-previous-history + "gr" 'helm-gtags-find-rtag + "gR" 'helm-gtags-resume + "gs" 'helm-gtags-select + "gS" 'helm-gtags-show-stack + "gu" 'helm-gtags-update-tags))) + +(defun spacemacs/ggtags-mode-enable () + "Enable ggtags and eldoc mode. + +For eldoc, ggtags advises the eldoc function at the lowest priority +so that if the major mode has better support it will use it first." + (when gtags-enable-by-default + (ggtags-mode 1) + (eldoc-mode 1))) diff --git a/layers/+tags/gtags/packages.el b/layers/+tags/gtags/packages.el new file mode 100644 index 0000000..2a35884 --- /dev/null +++ b/layers/+tags/gtags/packages.el @@ -0,0 +1,56 @@ +;;; packages.el --- gtags Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; and: Christian E. Hopps +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defconst gtags-packages + '( + ggtags + (helm-gtags :toggle (configuration-layer/package-usedp 'helm)) + )) + +(defun gtags/init-ggtags () + (use-package ggtags + :defer t + :init + (progn + ;; modes that do not have a layer, add here. + (add-hook 'awk-mode-local-vars-hook #'spacemacs/ggtags-mode-enable) + (add-hook 'shell-mode-local-vars-hook #'spacemacs/ggtags-mode-enable) + (add-hook 'tcl-mode-local-vars-hook #'spacemacs/ggtags-mode-enable) + (add-hook 'vhdl-mode-local-vars-hook #'spacemacs/ggtags-mode-enable)) + :config + (when (configuration-layer/package-usedp 'helm-gtags) + ;; If anyone uses helm-gtags, they would want to use these key bindings. + ;; These are bound in `ggtags-mode-map', since the functionality of + ;; `helm-gtags-mode' is basically entirely contained within + ;; `ggtags-mode-map' --- this way we don't have to enable both. + ;; Note: all of these functions are autoloadable. + (define-key ggtags-mode-map (kbd "M-.") 'helm-gtags-dwim) + (define-key ggtags-mode-map (kbd "C-x 4 .") 'helm-gtags-find-tag-other-window) + (define-key ggtags-mode-map (kbd "M-,") 'helm-gtags-pop-stack) + (define-key ggtags-mode-map (kbd "M-*") 'helm-gtags-pop-stack)))) + +(defun gtags/init-helm-gtags () + (use-package helm-gtags + :defer t + :init + (progn + (setq helm-gtags-ignore-case t + helm-gtags-auto-update t + helm-gtags-use-input-at-cursor t + helm-gtags-pulse-at-cursor t) + ;; modes that do not have a layer, define here + (spacemacs/helm-gtags-define-keys-for-mode 'tcl-mode) + (spacemacs/helm-gtags-define-keys-for-mode 'vhdl-mode) + (spacemacs/helm-gtags-define-keys-for-mode 'awk-mode) + (spacemacs/helm-gtags-define-keys-for-mode 'dired-mode) + (spacemacs/helm-gtags-define-keys-for-mode 'compilation-mode) + (spacemacs/helm-gtags-define-keys-for-mode 'shell-mode)))) diff --git a/layers/+themes/colors/README.org b/layers/+themes/colors/README.org new file mode 100644 index 0000000..420168f --- /dev/null +++ b/layers/+themes/colors/README.org @@ -0,0 +1,110 @@ +#+TITLE: Colors layer + +[[file:img/rainbow_dash.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#configuration][Configuration]] + - [[#colorize-identifiers][Colorize identifiers]] + - [[#enable-nyan-cat][Enable Nyan cat]] + - [[#key-bindings][Key bindings]] + - [[#colorize-identifiers-1][Colorize Identifiers]] + - [[#rainbow-mode][Rainbow Mode]] + - [[#nyan-mode][Nyan Mode]] + +* Description +This layer colors your life with: +- [[https://github.com/Fanael/rainbow-identifiers][rainbow identifiers]] mode will colorize all identifiers (christmas tree mode :-)) + with an almost unique color. +- [[https://github.com/ankurdave/color-identifiers-mode][color-identifiers]] mode will colorize only identifiers recognized as variables. +- [[https://julien.danjou.info/projects/emacs-packages][rainbow mode]] displays strings representing colors with the color they + represent as background. +- [[https://github.com/syl20bnr/nyan-mode][nyan mode]] display a Nyan cat progress bar in the mode-line. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =colors= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Configuration +** Colorize identifiers +To colorize some identifiers by default in programming language buffers, set +the layer variables =colors-colorize-identifiers= to either =variables= or +=all=. =variables= will colorize only words recognized as variables, =all= +will colorize all the words. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '( + (colors :variables colors-colorize-identifiers 'all))) +#+END_SRC + +When using the value =all= the Saturation and lightness of can be set per theme +by adding an entry in the variable =colors-theme-identifiers-sat&light=. This is +an alist where the key is a theme symbol and the value is a pair =(saturation +lightness)=. + +For now saturation and lightness are not supported with the =variables= value. + +Example: + +#+BEGIN_SRC emacs-lisp + (push '(mytheme . (50 50)) colors-theme-identifiers-sat&light) +#+END_SRC + +** Enable Nyan cat +To enable the package =nyan-mode= set the variable +=colors-enable-nyan-cat-progress-bar= to =t=: + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers '( + (colors :variables colors-enable-nyan-cat-progress-bar t))) +#+END_SRC + +It may be handy to enable it only in a GUI, you can do it by using +a quasi-quoted list: + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers + =((colors :variables + colors-enable-nyan-cat-progress-bar ,(display-graphic-p)))) +#+END_SRC + +* Key bindings +The prefix associated with colors is ~C~. + +** Colorize Identifiers + +| Key Binding | Description | +|-------------+-----------------------------------------------------------------| +| ~SPC C a~ | colorize all idendifiers in current buffer | +| ~SPC C C-a~ | globally colorize all idendifiers and all subsequent buffers | +| ~SPC C v~ | colorize all variables only in current buffer | +| ~SPC C C-v~ | globally colorize all variables only and all subsequent buffers | + +The =saturation= and =lightness= of identifier colors can be adjusted live +when colorizing all the identifiers with the transient-state: + +| Key Binding | Description | +|-----------------+------------------------------------------| +| ~SPC C i s~ | initiate change =saturation= mini-mode | +| ~SPC C i l~ | initiate change =lightness= mini-mode | +| ~+~ | increase the =saturation= or =lightness= | +| ~-~ | decrease the =saturation= or =lightness= | +| ~=~ | reset the =saturation= or =lightness= | +| ~Any other key~ | leave the change mini-mode | + +** Rainbow Mode + +[[file:img/rainbow-mode.png]] + +=rainbow-mode= mode can be toggled on and off with: + + ~SPC t C c~ + +** Nyan Mode +=nyan-mode= mode can be toggled on and off with: + + ~SPC t m n~ + +Note that the toggle is local to the current buffer. diff --git a/layers/+themes/colors/config.el b/layers/+themes/colors/config.el new file mode 100644 index 0000000..c165af0 --- /dev/null +++ b/layers/+themes/colors/config.el @@ -0,0 +1,32 @@ +;;; config.el --- Colors Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(defvar colors-colorize-identifiers nil + "If `variables' colorize variables, if `all' colorize all identifiers in +programming language buffers.") + +(defvar colors-enable-nyan-cat-progress-bar nil + "If non nil all nyan cat packages are enabled (for now only `nyan-mode').") + +(defvar colors-theme-identifiers-sat&light + '((jazz . (50 55)) + (gotham . (45 60)) + (leuven . (100 40)) + (material . (95 105)) + (monokai . (55 60)) + (solarized-dark . (65 55)) + (solarized-light . (60 55)) + (spacemacs-light . (65 45)) + (spacemacs-dark . (125 100)) + (zenburn . (40 65))) + "alist of theme symbols and pair of saturation and lightness values.") diff --git a/layers/+themes/colors/funcs.el b/layers/+themes/colors/funcs.el new file mode 100644 index 0000000..99f52d4 --- /dev/null +++ b/layers/+themes/colors/funcs.el @@ -0,0 +1,119 @@ +;;; funcs.el --- Colors Layer functions File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + +;; rainbow-identifiers + +(defun colors//rainbow-identifiers-mode-maybe () + "Enable rainbow identifiers if the major mode is a prog mode." + (when (derived-mode-p 'prog-mode) + (rainbow-identifiers-mode))) + +(defun colors//tweak-theme-colors (theme) + "Tweak color themes by adjusting rainbow-identifiers." + (interactive) + ;; tweak the saturation and lightness of identifier colors + (when (not (assq theme (get 'rainbow-identifiers-cie-l*a*b*-saturation + 'theme-value))) + (let ((sat&light (assq theme colors-theme-identifiers-sat&light))) + (if sat&light + (setq rainbow-identifiers-cie-l*a*b*-saturation (cadr sat&light) + rainbow-identifiers-cie-l*a*b*-lightness (caddr sat&light)) + ;; default + (setq rainbow-identifiers-cie-l*a*b*-saturation 80 + rainbow-identifiers-cie-l*a*b*-lightness 45))))) + +(defun colors//change-color-mini-mode-doc (component) + "Display a short documentation in the mini buffer." + (let ((var (intern (format + "rainbow-identifiers-cie-l*a*b*-%s" component)))) + (spacemacs/echo "Change color %s mini-mode (value: %s) + + to increase %s + - to decrease %s + = to reset +Press any other key to exit." component (eval var) component component))) + +(defun colors/change-color-component-overlay-map (component) + "Set a temporary overlay map to easily change a color COMPONENT from + rainbow-identifier mode. The color COMPONENT can be 'saturation' or + 'lightness'." + (set-temporary-overlay-map + (let ((map (make-sparse-keymap)) + (up-func (intern (format "colors/change-color-%s-up" component))) + (down-func (intern (format "colors/change-color-%s-down" component))) + (reset-func (intern (format "colors/change-color-%s-reset" component)))) + (define-key map (kbd "+") up-func) + (define-key map (kbd "-") down-func) + (define-key map (kbd "=") reset-func) + map) t) + (colors//change-color-mini-mode-doc component)) + +(defun colors/init-rainbow-mode () + (use-package rainbow-mode + :commands rainbow-mode + :init (spacemacs/set-leader-keys "tCc" 'rainbow-mode) + :config (spacemacs|hide-lighter rainbow-mode))) + +(defun colors/start-change-color-saturation () + "Initiate the overlay map to change the saturation." + (interactive) + (colors/change-color-component-overlay-map "saturation")) + +(defun colors/change-color-saturation-up () + "Increase the saturation by 5 units." + (interactive) + (colors//change-color-component-func "saturation" 5)) + +(defun colors/change-color-saturation-down () + "Decrease the saturation by 5 units." + (interactive) + (colors//change-color-component-func "saturation" -5)) + +(defun colors/change-color-saturation-reset () + "Reset the saturation to 100." + (interactive) + (colors//change-color-component-func "saturation" 100 t)) + +(defun colors/start-change-color-lightness () + "Initiate the overlay map to change the lightness." + (interactive) + (colors/change-color-component-overlay-map "lightness")) + +(defun colors/change-color-lightness-up () + "Increase the lightness by 5 units." + (interactive) + (colors//change-color-component-func "lightness" 5)) + +(defun colors/change-color-lightness-down () + "Decrease the lightness by 5 units." + (interactive) + (colors//change-color-component-func "lightness" -5)) + +(defun colors/change-color-lightness-reset () + "Reset the lightness to 40." + (interactive) + (colors//change-color-component-func "lightness" 40 t)) + +(defun colors//change-color-component-func + (component inc &optional reset) + "Change the color component by adding INC value to it. If RESET is not + nil the color component is set to INC." + (let* ((var (intern (format + "rainbow-identifiers-cie-l*a*b*-%s" component))) + (new-value (+ (eval var) inc))) + (if reset + (set var inc) + (progn + (if (< new-value 0) + (setq new-value 0)) + (set var new-value))) + (font-lock-fontify-buffer) + (colors/change-color-component-overlay-map component))) diff --git a/layers/+themes/colors/img/rainbow-mode.png b/layers/+themes/colors/img/rainbow-mode.png new file mode 100644 index 0000000..a8c6a64 Binary files /dev/null and b/layers/+themes/colors/img/rainbow-mode.png differ diff --git a/layers/+themes/colors/img/rainbow_dash.png b/layers/+themes/colors/img/rainbow_dash.png new file mode 100644 index 0000000..508bfe1 Binary files /dev/null and b/layers/+themes/colors/img/rainbow_dash.png differ diff --git a/layers/+themes/colors/img/theme-tweaks-python.png b/layers/+themes/colors/img/theme-tweaks-python.png new file mode 100644 index 0000000..f94c9f0 Binary files /dev/null and b/layers/+themes/colors/img/theme-tweaks-python.png differ diff --git a/layers/+themes/colors/local/nyan-mode/README.org b/layers/+themes/colors/local/nyan-mode/README.org new file mode 100644 index 0000000..39f1c3c --- /dev/null +++ b/layers/+themes/colors/local/nyan-mode/README.org @@ -0,0 +1,74 @@ +#+TITLE:nyan-mode + +* Table of Contents :TOC_4_gh:noexport: + - [[#nyan-mode---turn-your-emacs-into-nyanmacs-][Nyan Mode - Turn your Emacs into Nyanmacs! :)]] + - [[#fork-modifications][Fork modifications]] + - [[#introduction][Introduction]] + - [[#features][Features]] + - [[#using-nyan-mode-with-custom-modeline][Using Nyan Mode with custom modeline]] + - [[#known-issues][Known issues]] + - [[#credits][Credits]] + +* Nyan Mode - Turn your Emacs into Nyanmacs! :) + +** Fork modifications +- the starting nyan cat image has no rainbow behind it, +- the starting rainbow image has zigzags, +- the animation loop is not endless and occurs only when nyan cat moves. + +** Introduction + + *WARNING, MIND DUMBING CONTENT INSIDE.* + +"Nyan-mode. It's things like this that make me proud to be an emacs user." - [[http://twitter.com/#!/mitchellh/status/104931263479156736][mitchellh]] + +Nyanmacs is expanding!! [[http://temporal.pr0.pl/devblog/2011/08/25/introducing-nyan-mode-el-turn-your-emacs-into-nyanmacs/][Read the story so far]]! :). + +[[file:screenshot.png]] + +Nyan Mode is an analog indicator of your position in the buffer. The +Cat should go from left to right in your mode-line, as you move your +point from 0% to 100%. + +** Features + - Mind dumbing content included, + - Experimental animation (M-x nyan-start-animation, M-x nyan-stop-animation), + - Wavy rainbow (M-x set-variable nyan-wavy-trail t), + - Music, mplayer is needed (M-x nyan-start-music, M-x nyan-stop-music), + - Customizable properties. + +** Using Nyan Mode with custom modeline +For those who were asking, or are planning to, [[http://friendfeed.com/amitp/b4097da0/nyan-mode-turn-your-emacs-into-nyanmacs][Amit Patel shared]] +some tips on how to make nyan-mode work with custom modeline. + +He basically changed the mode-line-format to include: +#+begin_src emacs-lisp + (:eval (list (nyan-create))) +#+end_src + +** Known issues +It's my second attempt to write a minor mode in Emacs, so there will +definiely be some bugs. + +This version uses XPM images, which should be supported by default by +most Emacs 23 installations, Windows included. In case it doesn't +work, try switching to master-png branch. This branch, however, may +have it's own issues: + +There was a problem with displaying PNG images, which require libpng +to be available for Emacs. The lib is sometimes missing (e.g. some +Windows installation). To make it work on Windows, one needs to +download a proper DLL and put it into emacs bin/ folder. To see which +DLL is needed, do: M-x describe-variable image-library-alist +. + +Customizing nyan-animate-nyancat is broken; don't do it. + +** Credits + +Code and idea inspired by sml-modeline.el, written by Lennart Borgman. +See: http://bazaar.launchpad.net/~nxhtml/nxhtml/main/annotate/head%3A/util/sml-modeline.el + +For animated Nyan Cat, I used frames [[http://media.photobucket.com/image/nyan%20cat%20sprites/DryBowser455/th_NyanCatSprite.png?t=1304659408][by DryBowser455]]. + +Nyanyanyanyanyanyanya! diff --git a/layers/+themes/colors/local/nyan-mode/img/nyan-frame-1.xpm b/layers/+themes/colors/local/nyan-mode/img/nyan-frame-1.xpm new file mode 100644 index 0000000..00196af --- /dev/null +++ b/layers/+themes/colors/local/nyan-mode/img/nyan-frame-1.xpm @@ -0,0 +1,170 @@ +/* XPM */ +static char *nyan_frame_1[] = { +/* columns rows colors chars-per-pixel */ +"25 15 149 2 ", +" c black", +". c #070B0F", +"X c #0C0C0C", +"o c #041C0C", +"O c #000810", +"+ c #070917", +"@ c #0F1011", +"# c #02191F", +"$ c #111111", +"% c #161616", +"& c #082903", +"* c #142700", +"= c #083919", +"- c #292B00", +"; c #3C3400", +": c #120B2D", +"> c #001020", +", c #3F1E31", +"< c #172635", +"1 c #222222", +"2 c gray15", +"3 c #2B2525", +"4 c #2A2A2A", +"5 c gray18", +"6 c #3E2525", +"7 c #2C2F32", +"8 c gray22", +"9 c #3A3C3E", +"0 c gray24", +"q c #490C00", +"w c #7C0B10", +"e c #4C2400", +"r c #4C3100", +"t c #483F00", +"y c #403326", +"u c #4B3C2D", +"i c #423B34", +"p c #3D4100", +"a c #615600", +"s c #09264A", +"d c #1D2877", +"f c #322E75", +"g c #522244", +"h c #434343", +"j c #464646", +"k c #4C4646", +"l c gray29", +"z c gray30", +"x c #514C51", +"c c gray34", +"v c #54575A", +"b c #5D5D5D", +"n c #745D46", +"m c #775E5E", +"M c #614C61", +"N c #6D4C6D", +"B c #625962", +"V c gray38", +"C c #646464", +"Z c #686868", +"A c #7B6C6C", +"S c gray45", +"D c #767676", +"F c #7B7B7B", +"G c gray50", +"H c #BF1119", +"J c #F52A02", +"K c #FC7800", +"L c #947256", +"P c #26B210", +"I c #438500", +"U c #2CCB13", +"Y c #20D15C", +"T c #889000", +"R c #C4AC00", +"E c #FBA500", +"W c #F0D300", +"Q c #BF9973", +"! c #202C81", +"~ c #263498", +"^ c #432AAB", +"/ c #5536D9", +"( c #1E7FF7", +") c #4D43E9", +"_ c #5247F7", +"` c #885788", +"' c #A261A2", +"] c #AA66AA", +"[ c #AE68AE", +"{ c #FF5FC5", +"} c #C576C5", +"| c #D17DD1", +" . c #FF66CC", +".. c #F069C9", +"X. c #FF68CE", +"o. c #E073CD", +"O. c #FF6BD1", +"+. c #FF72D8", +"@. c #FF77DD", +"#. c #FF7CE2", +"$. c #0A819C", +"%. c #0EA7CB", +"&. c #1E80F7", +"*. c #868686", +"=. c #888888", +"-. c gray56", +";. c gray59", +":. c gray60", +">. c #A68F8F", +",. c #A09999", +"<. c #A89999", +"1. c #B09999", +"2. c #B59999", +"3. c #A0A0A0", +"4. c gray65", +"5. c #D79999", +"6. c #F69999", +"7. c #FF9999", +"8. c #D8AD82", +"9. c #F0BB99", +"0. c #F0B6A2", +"q. c #FFBBBB", +"w. c #FFBCB9", +"e. c #F0C090", +"r. c #FFCC99", +"t. c #FFC7A2", +"y. c #FFC7A4", +"u. c #D882D8", +"i. c #FF95D5", +"p. c #FFB3CC", +"a. c #E086E0", +"s. c #FF80E6", +"d. c #FF85EB", +"f. c #FF86EC", +"g. c #FF8AF0", +"h. c #FF8DF3", +"j. c #FF8FF5", +"k. c #F794F7", +"l. c #FF90F6", +"z. c #FF9DF7", +"x. c #FF92F8", +"c. c #FF94FA", +"v. c #FF97FD", +"b. c #FF99FF", +"n. c #FFA6E6", +"m. c #FFA8E0", +"M. c #FFA8E2", +"N. c gray81", +"B. c None", +/* pixels */ +"g g g g g g , y y y y y y y y y y y y 7 B.B.B.B.B.", +"H H H H H w L r.w.p.p.p.p.p.p.p.p.p.y.8.8 B.B.B.B.", +"J J J J J q e.w.b.b.b.b.{ b. .x.b.b.m.r.n B.B.B.B.", +"K K K K K e 0.b. .x.b.b.b.b.u.} x.h.x.m.n B.B.B.B.", +"E E E E E r 0.b.b.b.b.b.b.| M z ] #.x.m.n B.l B.B.", +"R ; ; a W t 0.b.b.b.b. .x.' b ;.B [ b.m.n V :.l B.", +"T 8 -.1 p - 0.b.b.f.b.b.b.' b :.:.b 1 4 V :.:.l B.", +"I * 8 *.4 0.b.b.+.b.b...N F :.:.:.:.:.:.:.:.S B.", +"U P & 8 =.1 0.#.s.b.b.b.o.8 :.3.4.Z :.:.:.N.j :.4 ", +"Y Y Y = o 0.b.b.b.h.x.a.8 <.>.2 V :.D Z 8 k 2.3 ", +"%.%.%.%.$.# 9.m.@.x.f.f.a.8 5.6.*.F :.V :.b 2.7.6 ", +"&.&.&.&.&.s 9.y.i.b.b.b.k.` A 1.V % 1 X 4 X ,.m B.", +"_ _ _ ) f 1 i Q Q Q Q Q Q Q u V S S S S S S v B.B.", +"/ / / ^ l :.j : O l 4 > B.B.B.. l 1 B.% l % B.B.B.", +"~ ~ ~ d % 1 O ! > 1 < B.B.B.B.B.2 % B.B.1 B.B.B.B." +}; diff --git a/layers/+themes/colors/local/nyan-mode/img/nyan-frame-2.xpm b/layers/+themes/colors/local/nyan-mode/img/nyan-frame-2.xpm new file mode 100644 index 0000000..f768df7 --- /dev/null +++ b/layers/+themes/colors/local/nyan-mode/img/nyan-frame-2.xpm @@ -0,0 +1,157 @@ +/* XPM */ +static char *nyan_frame_2[] = { +/* columns rows colors chars-per-pixel */ +"25 15 136 2 ", +" c #00070E", +". c #07090A", +"X c #070B0F", +"o c #0C0C0C", +"O c #000A14", +"+ c #100D1C", +"@ c #0F1011", +"# c #111111", +"$ c gray9", +"% c #152900", +"& c #083417", +"* c #180F3E", +"= c #032D37", +"- c #202020", +"; c #252525", +": c #2B2525", +"> c #2A2A2A", +", c #3E2525", +"< c #3F3127", +"1 c #3C3229", +"2 c gray20", +"3 c gray22", +"4 c #3F3F3F", +"5 c #431C38", +"6 c #403326", +"7 c #4B3C2D", +"8 c #254900", +"9 c #227C13", +"0 c #626800", +"q c #6C720A", +"w c #6F7509", +"e c #764939", +"r c #1E2974", +"t c #322E75", +"y c #522244", +"u c #075568", +"i c #414141", +"p c #464646", +"a c #4C4646", +"s c gray29", +"d c gray30", +"f c #584E44", +"g c #514C51", +"h c gray34", +"j c #54575A", +"k c #5D5D5D", +"l c #775E5E", +"z c #5B5E61", +"x c #614C61", +"c c #6D4C6D", +"v c #625962", +"b c gray38", +"n c #646464", +"m c #686868", +"M c #7B6C6C", +"N c #6F706F", +"B c gray45", +"V c #767676", +"C c #7B7B7B", +"Z c gray49", +"A c #851601", +"S c #930D13", +"D c #BF1119", +"F c #F52A02", +"G c #894100", +"H c #885900", +"J c #827300", +"K c #FC7800", +"L c #14843A", +"P c #20D15C", +"I c #B2BD00", +"U c #FBA500", +"Y c #F0D300", +"T c #B28E6B", +"R c #B6926E", +"E c #BF9973", +"W c #212E87", +"Q c #263498", +"! c #432AAB", +"~ c #104586", +"^ c #5536D9", +"/ c #1E7FF7", +"( c #4D43E9", +") c #5247F7", +"_ c #885788", +"` c #AA5599", +"' c #A261A2", +"] c #AE68AE", +"[ c #C576C5", +"{ c #D17DD1", +"} c #FF68CE", +"| c #FF6DD3", +" . c #FF77DD", +".. c #FF79DF", +"X. c #FF7BE1", +"o. c #FF7DE3", +"O. c #0EA7CB", +"+. c #1E80F7", +"@. c gray59", +"#. c gray60", +"$. c #A68F8F", +"%. c #A09999", +"&. c #A89999", +"*. c #B09999", +"=. c #B59999", +"-. c #A0A0A0", +";. c gray65", +":. c #D79999", +">. c #F69999", +",. c #FF9999", +"<. c #F7C694", +"1. c #FFCA9E", +"2. c #FFC5A7", +"3. c #FFC1AF", +"4. c #D882D8", +"5. c #E083DD", +"6. c #FFA4C8", +"7. c #FFB3CC", +"8. c #FFAFD2", +"9. c #E086E0", +"0. c #FF80E6", +"q. c #FF83E9", +"w. c #F08AE9", +"e. c #FF8EEB", +"r. c #FF88EE", +"t. c #FF8AF0", +"y. c #FF8EF4", +"u. c #F794F7", +"i. c #FF90F6", +"p. c #FF94FA", +"a. c #FF97FD", +"s. c #FF9CF9", +"d. c #FF99FF", +"f. c #FFA0F0", +"g. c gray81", +"h. c None", +/* pixels */ +"y y y y y 5 < < < < 6 6 6 6 6 6 < < < h.h.h.h.h.h.", +"D D D D S e <.3.7.7.7.7.7.7.7.7.7.3.<.f h.h.h.h.h.", +"F F F F A T 2.f.s.d.d.} y.X.X.d.s.f.2.T h.h.h.h.h.", +"K K K K G T s...0.s.d.d.s.d.4.[ i.y.s.T h.h.h.h.h.", +"U U U U H T s.d.d.d.d.d.s.{ x g ` 0.s.T h.h.d h.h.", +"Y Y Y Y J T s.d.d.d.X.X.d.' k @.v ] s.T z #.d h.", +"w ; w I 0 T s.d.0.s.d.d.d.' k #.#.k ; ; b #.#.d h.", +"; #.> 8 % T s.d...d.d...w.c C #.#.#.#.#.#.#.#.B h.", +"9 k C B 4 T y.| d.d.d.0.9.3 #.-.;.m #.#.#.g.a #.; ", +"P L & N 4 T s.s.d.d.r.d.9.3 &.$.; m #.C m 3 a *.: ", +"O.O.O.u = T 8.0.0.y.X.d.9.3 :.>.Z Z #.b #.z *.,., ", +"+.+./ / ~ T 1.6.i.d.s.d.u._ M *.b $ ; o ; o %.l h.", +") ) ) ( t ; R E E E E E E E 7 b B B B B B B j h.h.", +"^ ^ ^ ! s #.+ * 2 i X h.h.h.h.X d ; h.# d @ h.h.h.", +"Q Q Q r @ ; r W h.- h.h.h.h.h.h.; # h.h.; . h.h.h." +}; diff --git a/layers/+themes/colors/local/nyan-mode/img/nyan-frame-3.xpm b/layers/+themes/colors/local/nyan-mode/img/nyan-frame-3.xpm new file mode 100644 index 0000000..288cf89 --- /dev/null +++ b/layers/+themes/colors/local/nyan-mode/img/nyan-frame-3.xpm @@ -0,0 +1,159 @@ +/* XPM */ +static char *nyan_frame_3[] = { +/* columns rows colors chars-per-pixel */ +"25 15 138 2 ", +" c black", +". c #00070F", +"X c #0E0E0E", +"o c #0B1700", +"O c #061B02", +"+ c #030C16", +"@ c #02191F", +"# c #151515", +"$ c #1B1B1B", +"% c gray11", +"& c #0B3204", +"* c #363900", +"= c #27221C", +"- c #0B0F2D", +"; c #001122", +": c #3F1E31", +"> c #03252E", +", c #1E262E", +"< c gray15", +"1 c #2A2A2A", +"2 c #2C2C2C", +"3 c #2C2F32", +"4 c gray22", +"5 c #3A3C3E", +"6 c #3C3C3C", +"7 c #490C00", +"8 c #7C0B10", +"9 c #4C2400", +"0 c #4C3100", +"q c #483F00", +"w c #403326", +"e c #145C08", +"r c #3C7501", +"t c #191041", +"y c #18154A", +"u c #052749", +"i c #002E5D", +"p c #212646", +"a c #373E44", +"s c #522244", +"d c #643C64", +"f c #285059", +"g c #414141", +"h c #484848", +"j c gray30", +"k c #5C4242", +"l c #554755", +"z c #544C54", +"x c #5E4D5E", +"c c #5A5A5A", +"v c #5D5D5D", +"b c #745D46", +"n c #634463", +"m c #614C61", +"M c gray38", +"N c #6F6161", +"B c #6D6D6D", +"V c gray45", +"C c #777777", +"Z c gray48", +"A c gray49", +"S c #BF1119", +"D c #F52A02", +"F c #FC7800", +"G c #947256", +"H c #847373", +"J c #4D9801", +"K c #2CCB13", +"L c #189E45", +"P c #B4BF00", +"I c #FBA500", +"U c #F0D300", +"Y c #BF9973", +"T c #263498", +"R c #165FB9", +"E c #5536D9", +"W c #196ED5", +"Q c #1A70D8", +"! c #1E7FF7", +"~ c #5247F7", +"^ c #A261A2", +"/ c #B26BB2", +"( c #C95BAC", +") c #FF5FC5", +"_ c #C979C9", +"` c #D17DD1", +"' c #FF66CC", +"] c #FF68CE", +"[ c #FF6BD1", +"{ c #FF72D8", +"} c #FF77DD", +"| c #0C92B2", +" . c gray51", +".. c #848484", +"X. c #8B8B8B", +"o. c #8D8D8D", +"O. c #9D8888", +"+. c gray57", +"@. c #979797", +"#. c gray60", +"$. c #A69999", +"%. c #AA9999", +"&. c #AF9999", +"*. c #B39999", +"=. c gray70", +"-. c #CE9999", +";. c #DD9999", +":. c #F09999", +">. c #FF9999", +",. c #D8AD82", +"<. c #F0BB99", +"1. c #F0B6A2", +"2. c #FFBBBB", +"3. c #FFBCB9", +"4. c #F0C090", +"5. c #FFCC99", +"6. c #FFC7A2", +"7. c #FFC7A4", +"8. c #D580D5", +"9. c #DC84DC", +"0. c #FF95D5", +"q. c #FFB3CC", +"w. c #E88BE8", +"e. c #FF80E6", +"r. c #FF85EB", +"t. c #FF86EC", +"y. c #FF8AF0", +"u. c #FF8DF3", +"i. c #FF8FF5", +"p. c #FF90F6", +"a. c #FF9DF7", +"s. c #FF92F8", +"d. c #FF94FA", +"f. c #FF97FD", +"g. c #FF99FF", +"h. c #FFA6E6", +"j. c #FFA8E0", +"k. c None", +/* pixels */ +"s s s s s s : w w w w w w w w w w w w 3 k.k.k.k.k.", +"S S S S S 8 G 5.3.q.q.q.q.q.q.q.q.q.7.,.4 k.k.k.k.", +"D D D D D 7 4.3.g.g.g.g.) g.' s.g.g.h.5.b k.k.k.k.", +"F F F F F 9 1.g.' s.g.g.g.g.g._ ` u.s.j.b k.k.k.k.", +"I I I I I 0 1.g.g.g.g.g.g.g./ z x ( s.j.b k.k.j k.", +"U U U U U q 1.g.g.g.g.' s.g.d .o.z 9.j.b + A #.< ", +"P P P P P * 1.g.g.t.g.g.g.g.d .#.#.4 < < .#.#.< ", +"J J J J r o 1.g.g.{ g.g.{ ` m X.#.#.#.#.#.#.#.#.M ", +"K K e & O 1.} e.g.g.g.e.^ v #.=.C .#.#.#.=.c @.", +"L # Z +.B , 1.g.g.g.s.s.g.^ v &.H < .#.c A < N *.", +"| f j 4 > @ <.j.} s.t.t.g.^ v :.;.B X. .C #.M -.>.", +"! Q R R W u <.7.0.g.g.g.g.w.n O.&.g % % # < 1 $.k ", +"~ ~ ~ ~ ~ y 4 Y Y Y Y Y Y Y Y = V V V V V V V a k.", +"E E E E E t Y , ; X j % k.k.k.k.; 1 j . k.4 4 k.k.", +"T T T T T - < p i k.< X k.k.k.k.k.k.1 k.k., % k.k." +}; diff --git a/layers/+themes/colors/local/nyan-mode/img/nyan-frame-4.xpm b/layers/+themes/colors/local/nyan-mode/img/nyan-frame-4.xpm new file mode 100644 index 0000000..4c26764 --- /dev/null +++ b/layers/+themes/colors/local/nyan-mode/img/nyan-frame-4.xpm @@ -0,0 +1,157 @@ +/* XPM */ +static char *nyan_frame_4[] = { +/* columns rows colors chars-per-pixel */ +"25 15 136 2 ", +" c #00070E", +". c #07090A", +"X c #070B0F", +"o c #0C0C0C", +"O c #000A14", +"+ c #100D1C", +"@ c #0F1011", +"# c #111111", +"$ c gray9", +"% c #152900", +"& c #0B3204", +"* c #180F3E", +"= c #032D37", +"- c #192633", +"; c #202020", +": c gray15", +"> c #2B2525", +", c #2A2A2A", +"< c #3E2525", +"1 c #3F3127", +"2 c #3C3229", +"3 c gray20", +"4 c gray22", +"5 c #3F3F3F", +"6 c #431C38", +"7 c #403326", +"8 c #4B3C2D", +"9 c #284E00", +"0 c #1B7F3D", +"q c #626800", +"w c #764939", +"e c #1E2974", +"r c #322E75", +"t c #522244", +"y c #065062", +"u c #414141", +"i c #464646", +"p c #4C4646", +"a c gray29", +"s c gray30", +"d c #584E44", +"f c #514C51", +"g c gray34", +"h c #54575A", +"j c #5D5D5D", +"k c #775E5E", +"l c #5B5E61", +"z c #614C61", +"x c #6D4C6D", +"c c #625962", +"v c gray38", +"b c #646464", +"n c #686868", +"m c #7B6C6C", +"M c #6F706F", +"N c gray45", +"B c #767676", +"V c #7B7B7B", +"C c gray49", +"Z c #851601", +"A c #930D13", +"S c #BF1119", +"D c #F52A02", +"F c #894100", +"G c #885900", +"H c #827300", +"J c #FC7800", +"K c #1B800C", +"L c #4D9801", +"P c #2CCB13", +"I c #B4BF00", +"U c #FBA500", +"Y c #F0D300", +"T c #B28E6B", +"R c #B6926E", +"E c #BF9973", +"W c #212E87", +"Q c #263498", +"! c #432AAB", +"~ c #104586", +"^ c #1A5091", +"/ c #1A5195", +"( c #5536D9", +") c #1D7EF5", +"_ c #4D43E9", +"` c #5247F7", +"' c #885788", +"] c #AA5599", +"[ c #A261A2", +"{ c #AE68AE", +"} c #C576C5", +"| c #D17DD1", +" . c #FF68CE", +".. c #FF6DD3", +"X. c #FF77DD", +"o. c #FF79DF", +"O. c #FF7BE1", +"+. c #FF7DE3", +"@. c gray59", +"#. c gray60", +"$. c #A68F8F", +"%. c #A09999", +"&. c #A89999", +"*. c #B09999", +"=. c #B59999", +"-. c #A0A0A0", +";. c gray65", +":. c #D79999", +">. c #F69999", +",. c #FF9999", +"<. c #F7C694", +"1. c #FFCA9E", +"2. c #FFC5A7", +"3. c #FFC1AF", +"4. c #D882D8", +"5. c #E083DD", +"6. c #FFA4C8", +"7. c #FFB3CC", +"8. c #FFAFD2", +"9. c #E086E0", +"0. c #FF80E6", +"q. c #FF83E9", +"w. c #F08AE9", +"e. c #FF8EEB", +"r. c #FF88EE", +"t. c #FF8AF0", +"y. c #FF8EF4", +"u. c #F794F7", +"i. c #FF90F6", +"p. c #FF94FA", +"a. c #FF97FD", +"s. c #FF9CF9", +"d. c #FF99FF", +"f. c #FFA0F0", +"g. c gray81", +"h. c None", +/* pixels */ +"t t t t t 6 1 7 7 7 7 7 7 7 7 7 1 1 1 h.h.h.h.h.h.", +"S S S S A w <.3.7.7.7.7.7.7.7.7.7.3.<.d h.h.h.h.h.", +"D D D D Z T 2.f.d.d.d. .i.+.+.d.s.f.2.T h.h.h.h.h.", +"J J J J F T s.o.+.s.d.d.d.s.| } i.y.s.T h.h.h.h.h.", +"U U U U G T s.d.d.d.d.d.d.| z f ] 0.s.T h.h.s h.h.", +"Y Y Y Y H T s.d.d.d.+.+.d.[ j @.c { s.T l #.a h.", +"I I I I q T s.d.r.d.d.d.d.[ j #.#.j : : v #.#.s h.", +"L L L 9 % T s.s.o.d.d.o.w.x V #.#.#.#.#.#.#.#.N h.", +"P K & M 5 T e...d.d.d.r.5.4 #.-.-.v #.#.#.g.p #.: ", +"0 l C N 5 T s.d.d.y.r.d.5.4 &.$.: j #.V v 5 p *.> ", +": #.: y = T 8.r.r.y.+.d.9.4 :.>.V @.#.v #.j *.,.< ", +"/ : ^ ) ~ T 1.6.y.d.d.d.u.' m *.v $ : o : o %.k h.", +"` ` ` _ r : R E E E E E E E 8 v N N N N N N h h.h.", +"( ( ( ! i #.+ * 3 u X h.h.h.h.X s : h.# s # h.h.h.", +"Q Q Q e @ : e W - ; h.h.h.h.h.h.: # h.h.: . h.h.h." +}; diff --git a/layers/+themes/colors/local/nyan-mode/img/nyan-frame-5.xpm b/layers/+themes/colors/local/nyan-mode/img/nyan-frame-5.xpm new file mode 100644 index 0000000..3841bd7 --- /dev/null +++ b/layers/+themes/colors/local/nyan-mode/img/nyan-frame-5.xpm @@ -0,0 +1,157 @@ +/* XPM */ +static char *nyan_frame_5[] = { +/* columns rows colors chars-per-pixel */ +"25 15 136 2 ", +" c black", +". c #020F06", +"X c #070B0F", +"o c #08090C", +"O c #0C0C0C", +"+ c #1D1F00", +"@ c #020912", +"# c #000A14", +"$ c #131313", +"% c #161616", +"& c #191919", +"* c #251E17", +"= c #083417", +"- c #292B00", +"; c #3F1E31", +": c #04323D", +"> c #232323", +", c #222126", +"< c gray14", +"1 c gray15", +"2 c #2B2525", +"3 c #20262C", +"4 c #2A2A2A", +"5 c #3E2525", +"6 c #2C2F32", +"7 c gray20", +"8 c gray22", +"9 c #3A3C3E", +"0 c #490C00", +"q c #7C0B10", +"w c #4C2400", +"e c #4C3100", +"r c #483F00", +"t c #403326", +"y c #4B3C2D", +"u c #236119", +"i c #6F7509", +"p c #241856", +"a c #1F265A", +"s c #522244", +"d c #414141", +"f c #464646", +"g c #4C4646", +"h c #494949", +"j c gray31", +"k c #514C51", +"l c gray34", +"z c #54575A", +"x c #5D5D5D", +"c c #5F5F5F", +"v c #745D46", +"b c #614C61", +"n c #6D4C6D", +"m c gray38", +"M c #646464", +"N c gray40", +"B c #686868", +"V c #7B6C6C", +"C c #727272", +"Z c gray45", +"A c #7B7B7B", +"S c gray50", +"D c #BF1119", +"F c #F52A02", +"G c #FC7800", +"H c #947256", +"J c #20980E", +"K c #1AAF4D", +"L c #20D15C", +"P c #868F00", +"I c #FBA500", +"U c #F0D300", +"Y c #BF9973", +"T c #23308F", +"R c #263498", +"E c #39329C", +"W c #1354A2", +"Q c #5536D9", +"! c #5247F7", +"~ c #885788", +"^ c #A261A2", +"/ c #AA66AA", +"( c #AE68AE", +") c #FF5FC5", +"_ c #C576C5", +"` c #D17DD1", +"' c #FF66CC", +"] c #F069C9", +"[ c #FF68CE", +"{ c #E073CD", +"} c #FF6BD1", +"| c #FF72D8", +" . c #FF77DD", +".. c #FF79DF", +"X. c #0EA7CB", +"o. c #1E80F7", +"O. c gray59", +"+. c gray60", +"@. c #A68F8F", +"#. c #A89999", +"$. c #B09999", +"%. c #B59999", +"&. c #A0A0A0", +"*. c gray65", +"=. c #D79999", +"-. c #F69999", +";. c #FF9999", +":. c #D8AD82", +">. c #F0BB99", +",. c #F0B6A2", +"<. c #FFBBBB", +"1. c #FFBCB9", +"2. c #F0C090", +"3. c #FFCC99", +"4. c #FFC7A2", +"5. c #D882D8", +"6. c #FF95D5", +"7. c #FFB3CC", +"8. c #E086E0", +"9. c #FF80E6", +"0. c #FF85EB", +"q. c #FF86EC", +"w. c #FF8AF0", +"e. c #FF8DF3", +"r. c #FF8FF5", +"t. c #F794F7", +"y. c #FF90F6", +"u. c #FF9DF7", +"i. c #FF92F8", +"p. c #FF94FA", +"a. c #FF97FD", +"s. c #FF99FF", +"d. c #FFA6E6", +"f. c #FFA8E0", +"g. c gray81", +"h. c None", +/* pixels */ +"s s s s s s ; t t t t t t t t t t t t 6 h.h.h.h.h.", +"D D D D D q H 3.1.7.7.7.7.7.7.7.7.7.4.:.9 h.h.h.h.", +"F F F F F 0 2.1.s.s.s.s.) s.' i.s.s.d.3.v h.h.h.h.", +"G G G G G w ,.s.' i.s.s.s.s.5._ u.e.p.f.v h.h.h.h.", +"I I I I I e ,.s.s.s.s.s.s.` b j / .i.f.v h.j h.h.", +"U U U U U r ,.s.s.s.s.' i.^ x O.x ( u.f.v x O.h h.", +"i 1 1 + P - ,.s.s.0.s.s.s.^ x +.+.l 2 2 m +.+.j h.", +"$ C +.j 4 ,.s.s.| s.s.] n A +.+.+.+.+.+.+.+.C h.", +"J u 1 1 h 1 ,. .9.s.s.s.{ 8 +.&.*.m +.+.+.g.d +.1 ", +"L L L K = . ,.s.s.s.e.i.8.8 #.@., x +.A N 9 g %.2 ", +"X.X.X.X.X.: >.f. .i.0.0.8.8 =.-.H O.+.m +.m %.;.5 ", +"o.o.o.o.W # 2.4.6.s.s.s.t.~ V $.m % 1 O 3 # +.V h.", +"! ! ! E 4 1 * Y Y Y Y Y Y Y y m C C C C C C z h.h.", +"Q Q Q 1 +.m p & j X h.h.h.h.# d 7 h.# j 1 h.h.h.h.", +"R R R o 1 a T a 1 h.h.h.h.h.h.3 & h.h.1 $ h.h.h.h." +}; diff --git a/layers/+themes/colors/local/nyan-mode/img/nyan-frame-6.xpm b/layers/+themes/colors/local/nyan-mode/img/nyan-frame-6.xpm new file mode 100644 index 0000000..7a61f05 --- /dev/null +++ b/layers/+themes/colors/local/nyan-mode/img/nyan-frame-6.xpm @@ -0,0 +1,165 @@ +/* XPM */ +static char *nyan_frame_6[] = { +/* columns rows colors chars-per-pixel */ +"25 15 144 2 ", +" c black", +". c #020F06", +"X c #070B0F", +"o c #08090C", +"O c #0C0C0C", +"+ c #020912", +"@ c #000A14", +"# c #111111", +"$ c #151515", +"% c #1D1711", +"& c #251E17", +"* c #083417", +"= c #212305", +"- c #292B00", +"; c #3C3400", +": c #3F1E31", +"> c #04323D", +", c #202020", +"< c #222126", +"1 c #252525", +"2 c #2A2A2A", +"3 c gray18", +"4 c #3E2525", +"5 c #2C2F32", +"6 c #342D34", +"7 c gray20", +"8 c gray22", +"9 c #3A3C3E", +"0 c #3F3F3F", +"q c #490C00", +"w c #7C0B10", +"e c #4C2400", +"r c #4C3100", +"t c #483F00", +"y c #403326", +"u c #402A38", +"i c #24451F", +"p c #394C25", +"a c #241856", +"s c #1F265A", +"d c #1E297A", +"f c #522244", +"g c #414141", +"h c #464646", +"j c gray29", +"k c gray31", +"l c #554755", +"z c #5E4D5E", +"x c #515151", +"c c #5C5650", +"v c #5A5A5A", +"b c #5D5D5D", +"n c #745D46", +"m c #634463", +"M c #6D4C6D", +"N c #656565", +"B c #6C6C6C", +"V c gray45", +"C c #767676", +"Z c #797979", +"A c #7C7C7C", +"S c #BF1119", +"D c #F52A02", +"F c #FC7800", +"G c #947256", +"H c #9A7B7B", +"J c #A57272", +"K c #26B210", +"L c #438500", +"P c #2CCB13", +"I c #1AAF4D", +"U c #20D15C", +"Y c #868F00", +"T c #988600", +"R c #889000", +"E c #FBA500", +"W c #EACE00", +"Q c #F0D300", +"! c #BF9973", +"~ c #263498", +"^ c #39329C", +"/ c #1354A2", +"( c #5536D9", +") c #1E7FF7", +"_ c #5247F7", +"` c #885788", +"' c #A261A2", +"] c #C95BAC", +"[ c #E060B9", +"{ c #FF5FC5", +"} c #FF66CC", +"| c #FF68CE", +" . c #E073CD", +".. c #FF6BD1", +"X. c #FF72D8", +"o. c #FF77DD", +"O. c #FF79DF", +"+. c #0EA7CB", +"@. c #1E80F7", +"#. c #848484", +"$. c #888888", +"%. c gray55", +"&. c #929292", +"*. c #979797", +"=. c gray60", +"-. c gray62", +";. c #A79999", +":. c #B59999", +">. c gray63", +",. c gray74", +"<. c #C79999", +"1. c #D79999", +"2. c #F69999", +"3. c #FF9999", +"4. c #D8AD82", +"5. c #F0BB99", +"6. c #F0B6A2", +"7. c #FFBBBB", +"8. c #FFBCB9", +"9. c #F0C090", +"0. c #FFCC99", +"q. c #FFC7A2", +"w. c #FFC7A4", +"e. c #D580D5", +"r. c #FF95D5", +"t. c #FFB3CC", +"y. c #E086E0", +"u. c #E88BE8", +"i. c #FF80E6", +"p. c #FF85EB", +"a. c #FF86EC", +"s. c #FF8DF3", +"d. c #FF8FF5", +"f. c #F090F0", +"g. c #F794F7", +"h. c #FF90F6", +"j. c #FF9DF7", +"k. c #FF92F8", +"l. c #FF94FA", +"z. c #FF97FD", +"x. c #FF99FF", +"c. c #FFA6E6", +"v. c #FFA8E2", +"b. c None", +/* pixels */ +"f f f f f f : y y y y y y y y y y y y 5 b.b.b.b.b.", +"S S S S S w G 0.8.t.t.t.t.t.t.t.t.t.q.4.9 b.b.b.b.", +"D D D D D q 9.8.x.x.x.x.{ x.} k.l.x.c.0.n b.b.b.b.", +"F F F F F e 6.x.} k.x.x.x.u.m 6 e.s.l.v.n b., b.b.", +"E E E E E r 6.x.x.x.x.x.x.' b &.z ] k.c.n 6 =.j b.", +"Q T ; W Q t 6.x.x.x.x.} k.' b =.$.l 6 6 c &.=.j b.", +"R j =.= R - 6.x.x.a.x.x.g.` B =.=.=.=.=.;.>.*.b b.", +"L p #.j x $ 6.x.x.X.x.x.[ 8 =.-.-.A =.=.=.,.N =.3 ", +"P K i 0 =.3 6.o.i.x.x.x. .8 =.&.3 v *.C N k 3 *., ", +"U U U I * . 6.x.x.x.k.k.y.8 1.2.%.$.*.A =.A :.3.4 ", +"+.+.+.+.+.> 5.v.o.k.a.a.f.M H <.N 3 j $ k $ ;.J b.", +") @.) ) / @ 9.q.r.x.x.x.x.u.m #.#.C C C C V C b.b.", +"_ _ _ ^ b j & ! ! ! ! ! ! ! ! % O $ @ b.b.b.", +"( ( ( , =.B a , k X b.b.b.b.@ g 6 b.@ N h b.b.b.b.", +"~ ~ ~ X , s d # , b.b.b.b.b.b., b.b.b., $ b.b.b.b." +}; diff --git a/layers/+themes/colors/local/nyan-mode/img/nyan-start.xpm b/layers/+themes/colors/local/nyan-mode/img/nyan-start.xpm new file mode 100644 index 0000000..3da12e5 --- /dev/null +++ b/layers/+themes/colors/local/nyan-mode/img/nyan-start.xpm @@ -0,0 +1,157 @@ +/* XPM */ +static char *nyan[] = { +/* columns rows colors chars-per-pixel */ +"25 15 136 2 ", +" c black", +". c #020F06", +"X c #070B0F", +"o c #08090C", +"O c #0C0C0C", +"+ c #1D1F00", +"@ c #020912", +"# c #000A14", +"$ c #131313", +"% c #161616", +"& c #191919", +"* c #251E17", +"= c #083417", +"- c #292B00", +"; c #3F1E31", +": c #04323D", +"> c #232323", +", c #222126", +"< c gray14", +"1 c gray15", +"2 c #2B2525", +"3 c #20262C", +"4 c #2A2A2A", +"5 c #3E2525", +"6 c #2C2F32", +"7 c gray20", +"8 c gray22", +"9 c #3A3C3E", +"0 c #490C00", +"q c #7C0B10", +"w c #4C2400", +"e c #4C3100", +"r c #483F00", +"t c #403326", +"y c #4B3C2D", +"u c #236119", +"i c #6F7509", +"p c #241856", +"a c #1F265A", +"s c #522244", +"d c #414141", +"f c #464646", +"g c #4C4646", +"h c #494949", +"j c gray31", +"k c #514C51", +"l c gray34", +"z c #54575A", +"x c #5D5D5D", +"c c #5F5F5F", +"v c #745D46", +"b c #614C61", +"n c #6D4C6D", +"m c gray38", +"M c #646464", +"N c gray40", +"B c #686868", +"V c #7B6C6C", +"C c #727272", +"Z c gray45", +"A c #7B7B7B", +"S c gray50", +"D c #BF1119", +"F c #F52A02", +"G c #FC7800", +"H c #947256", +"J c #20980E", +"K c #1AAF4D", +"L c #20D15C", +"P c #868F00", +"I c #FBA500", +"U c #F0D300", +"Y c #BF9973", +"T c #23308F", +"R c #263498", +"E c #39329C", +"W c #1354A2", +"Q c #5536D9", +"! c #5247F7", +"~ c #885788", +"^ c #A261A2", +"/ c #AA66AA", +"( c #AE68AE", +") c #FF5FC5", +"_ c #C576C5", +"` c #D17DD1", +"' c #FF66CC", +"] c #F069C9", +"[ c #FF68CE", +"{ c #E073CD", +"} c #FF6BD1", +"| c #FF72D8", +" . c #FF77DD", +".. c #FF79DF", +"X. c #0EA7CB", +"o. c #1E80F7", +"O. c gray59", +"+. c gray60", +"@. c #A68F8F", +"#. c #A89999", +"$. c #B09999", +"%. c #B59999", +"&. c #A0A0A0", +"*. c gray65", +"=. c #D79999", +"-. c #F69999", +";. c #FF9999", +":. c #D8AD82", +">. c #F0BB99", +",. c #F0B6A2", +"<. c #FFBBBB", +"1. c #FFBCB9", +"2. c #F0C090", +"3. c #FFCC99", +"4. c #FFC7A2", +"5. c #D882D8", +"6. c #FF95D5", +"7. c #FFB3CC", +"8. c #E086E0", +"9. c #FF80E6", +"0. c #FF85EB", +"q. c #FF86EC", +"w. c #FF8AF0", +"e. c #FF8DF3", +"r. c #FF8FF5", +"t. c #F794F7", +"y. c #FF90F6", +"u. c #FF9DF7", +"i. c #FF92F8", +"p. c #FF94FA", +"a. c #FF97FD", +"s. c #FF99FF", +"d. c #FFA6E6", +"f. c #FFA8E0", +"g. c gray81", +"h. c None", +/* pixels */ +"h.h.h.h.h.h.; t t t t t t t t t t t t 6 h.h.h.h.h.", +"h.h.h.h.h.q H 3.1.7.7.7.7.7.7.7.7.7.4.:.9 h.h.h.h.", +"h.h.h.h.h.0 2.1.s.s.s.s.) s.' i.s.s.d.3.v h.h.h.h.", +"h.h.h.h.h.w ,.s.' i.s.s.s.s.5._ u.e.p.f.v h.h.h.h.", +"h.h.h.h.h.e ,.s.s.s.s.s.s.` b j / .i.f.v h.j h.h.", +"h.h.h.h.h.r ,.s.s.s.s.' i.^ x O.x / u.f.v x O.d h.", +"h.1 1 + h.- ,.s.s.0.s.s.s.^ x +.+.x 2 2 m +.+.j h.", +"$ C +.j 4 ,.s.s.| s.s.] n A +.+.+.+.+.+.+.+.C h.", +"h.u 1 1 h 1 ,. .9.s.s.s.{ 8 +.&.&.B +.+.+.g.g +.1 ", +"h.h.h.h.= . ,.s.s.s.e.i.8.8 #.@., m +.A N 9 g $.2 ", +"h.h.h.h.h.: >.f. .i.0.0.8.8 =.-.H O.+.m +.c $.;.5 ", +"h.h.h.h.W # 2.4.6.s.s.s.t.~ V $.m $ 1 O 3 # +.V h.", +"h.h.h.E 4 1 * Y Y Y Y Y Y Y y m C C C C C C z h.h.", +"h.h.h.1 +.m p & j X h.h.h.h.# d 7 h.h.j 1 h.h.h.h.", +"h.h.h.o 1 a T a 1 h.h.h.h.h.h.3 & h.h.1 $ h.h.h.h." +}; diff --git a/layers/+themes/colors/local/nyan-mode/img/nyan.xpm b/layers/+themes/colors/local/nyan-mode/img/nyan.xpm new file mode 100644 index 0000000..45123da --- /dev/null +++ b/layers/+themes/colors/local/nyan-mode/img/nyan.xpm @@ -0,0 +1,157 @@ +/* XPM */ +static char *nyan[] = { +/* columns rows colors chars-per-pixel */ +"25 15 136 2 ", +" c black", +". c #020F06", +"X c #070B0F", +"o c #08090C", +"O c #0C0C0C", +"+ c #1D1F00", +"@ c #020912", +"# c #000A14", +"$ c #131313", +"% c #161616", +"& c #191919", +"* c #251E17", +"= c #083417", +"- c #292B00", +"; c #3F1E31", +": c #04323D", +"> c #232323", +", c #222126", +"< c gray14", +"1 c gray15", +"2 c #2B2525", +"3 c #20262C", +"4 c #2A2A2A", +"5 c #3E2525", +"6 c #2C2F32", +"7 c gray20", +"8 c gray22", +"9 c #3A3C3E", +"0 c #490C00", +"q c #7C0B10", +"w c #4C2400", +"e c #4C3100", +"r c #483F00", +"t c #403326", +"y c #4B3C2D", +"u c #236119", +"i c #6F7509", +"p c #241856", +"a c #1F265A", +"s c #522244", +"d c #414141", +"f c #464646", +"g c #4C4646", +"h c #494949", +"j c gray31", +"k c #514C51", +"l c gray34", +"z c #54575A", +"x c #5D5D5D", +"c c #5F5F5F", +"v c #745D46", +"b c #614C61", +"n c #6D4C6D", +"m c gray38", +"M c #646464", +"N c gray40", +"B c #686868", +"V c #7B6C6C", +"C c #727272", +"Z c gray45", +"A c #7B7B7B", +"S c gray50", +"D c #BF1119", +"F c #F52A02", +"G c #FC7800", +"H c #947256", +"J c #20980E", +"K c #1AAF4D", +"L c #20D15C", +"P c #868F00", +"I c #FBA500", +"U c #F0D300", +"Y c #BF9973", +"T c #23308F", +"R c #263498", +"E c #39329C", +"W c #1354A2", +"Q c #5536D9", +"! c #5247F7", +"~ c #885788", +"^ c #A261A2", +"/ c #AA66AA", +"( c #AE68AE", +") c #FF5FC5", +"_ c #C576C5", +"` c #D17DD1", +"' c #FF66CC", +"] c #F069C9", +"[ c #FF68CE", +"{ c #E073CD", +"} c #FF6BD1", +"| c #FF72D8", +" . c #FF77DD", +".. c #FF79DF", +"X. c #0EA7CB", +"o. c #1E80F7", +"O. c gray59", +"+. c gray60", +"@. c #A68F8F", +"#. c #A89999", +"$. c #B09999", +"%. c #B59999", +"&. c #A0A0A0", +"*. c gray65", +"=. c #D79999", +"-. c #F69999", +";. c #FF9999", +":. c #D8AD82", +">. c #F0BB99", +",. c #F0B6A2", +"<. c #FFBBBB", +"1. c #FFBCB9", +"2. c #F0C090", +"3. c #FFCC99", +"4. c #FFC7A2", +"5. c #D882D8", +"6. c #FF95D5", +"7. c #FFB3CC", +"8. c #E086E0", +"9. c #FF80E6", +"0. c #FF85EB", +"q. c #FF86EC", +"w. c #FF8AF0", +"e. c #FF8DF3", +"r. c #FF8FF5", +"t. c #F794F7", +"y. c #FF90F6", +"u. c #FF9DF7", +"i. c #FF92F8", +"p. c #FF94FA", +"a. c #FF97FD", +"s. c #FF99FF", +"d. c #FFA6E6", +"f. c #FFA8E0", +"g. c gray81", +"h. c None", +/* pixels */ +"s s s s s s ; t t t t t t t t t t t t 6 h.h.h.h.h.", +"D D D D D q H 3.1.7.7.7.7.7.7.7.7.7.4.:.9 h.h.h.h.", +"F F F F F 0 2.1.s.s.s.s.) s.' i.s.s.d.3.v h.h.h.h.", +"G G G G G w ,.s.' i.s.s.s.s.5._ u.e.p.f.v h.h.h.h.", +"I I I I I e ,.s.s.s.s.s.s.` b j / .i.f.v h.j h.h.", +"U U U U U r ,.s.s.s.s.' i.^ x O.x / u.f.v x O.d h.", +"i 1 1 + P - ,.s.s.0.s.s.s.^ x +.+.x 2 2 m +.+.j h.", +"$ C +.j 4 ,.s.s.| s.s.] n A +.+.+.+.+.+.+.+.C h.", +"J u 1 1 h 1 ,. .9.s.s.s.{ 8 +.&.&.B +.+.+.g.g +.1 ", +"L L L K = . ,.s.s.s.e.i.8.8 #.@., m +.A N 9 g $.2 ", +"X.X.X.X.X.: >.f. .i.0.0.8.8 =.-.H O.+.m +.c $.;.5 ", +"o.o.o.o.W # 2.4.6.s.s.s.t.~ V $.m $ 1 O 3 # +.V h.", +"! ! ! E 4 1 * Y Y Y Y Y Y Y y m C C C C C C z h.h.", +"Q Q Q 1 +.m p & j X h.h.h.h.# d 7 h.h.j 1 h.h.h.h.", +"R R R o 1 a T a 1 h.h.h.h.h.h.3 & h.h.1 $ h.h.h.h." +}; diff --git a/layers/+themes/colors/local/nyan-mode/img/outerspace.xpm b/layers/+themes/colors/local/nyan-mode/img/outerspace.xpm new file mode 100644 index 0000000..a487c08 --- /dev/null +++ b/layers/+themes/colors/local/nyan-mode/img/outerspace.xpm @@ -0,0 +1,142 @@ +/* XPM */ +static char *outerspace[] = { +/* columns rows colors chars-per-pixel */ +"8 15 120 2 ", +" c None", +". c black", +"X c black", +"o c black", +"O c black", +"+ c black", +"@ c black", +"# c black", +"$ c black", +"% c black", +"& c black", +"* c black", +"= c black", +"- c black", +"; c black", +": c black", +"> c black", +", c black", +"< c black", +"1 c black", +"2 c black", +"3 c black", +"4 c black", +"5 c black", +"6 c black", +"7 c black", +"8 c black", +"9 c black", +"0 c black", +"q c black", +"w c black", +"e c black", +"r c black", +"t c black", +"y c black", +"u c black", +"i c black", +"p c black", +"a c black", +"s c black", +"d c black", +"f c black", +"g c black", +"h c black", +"j c black", +"k c black", +"l c black", +"z c black", +"x c black", +"c c black", +"v c black", +"b c black", +"n c black", +"m c black", +"M c black", +"N c black", +"B c black", +"V c black", +"C c black", +"Z c black", +"A c black", +"S c black", +"D c black", +"F c black", +"G c black", +"H c black", +"J c black", +"K c black", +"L c black", +"P c black", +"I c black", +"U c black", +"Y c black", +"T c black", +"R c black", +"E c black", +"W c black", +"Q c black", +"! c black", +"~ c black", +"^ c black", +"/ c black", +"( c black", +") c black", +"_ c black", +"` c black", +"' c black", +"] c black", +"[ c black", +"{ c black", +"} c black", +"| c black", +" . c black", +".. c black", +"X. c black", +"o. c black", +"O. c black", +"+. c black", +"@. c black", +"#. c black", +"$. c black", +"%. c black", +"&. c black", +"*. c black", +"=. c black", +"-. c black", +";. c black", +":. c black", +">. c black", +",. c black", +"<. c black", +"1. c black", +"2. c black", +"3. c black", +"4. c black", +"5. c black", +"6. c black", +"7. c black", +"8. c black", +"9. c black", +/* pixels */ +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" " +}; diff --git a/layers/+themes/colors/local/nyan-mode/img/rainbow-start.xpm b/layers/+themes/colors/local/nyan-mode/img/rainbow-start.xpm new file mode 100644 index 0000000..3e458ae --- /dev/null +++ b/layers/+themes/colors/local/nyan-mode/img/rainbow-start.xpm @@ -0,0 +1,43 @@ +/* XPM */ +static char *rainbow[] = { +/* columns rows colors chars-per-pixel */ +"8 15 22 1 ", +" c #522244", +". c #BF1119", +"X c #F52A02", +"o c #FC7800", +"O c #FBA500", +"+ c #FCA500", +"@ c #F0D300", +"# c #B4BF00", +"$ c #B5BF00", +"% c #4D9801", +"& c #4E9802", +"* c #4E9801", +"= c #2CCB13", +"- c #20D15C", +"; c #0EA7CB", +": c #0EA6CB", +"> c #1E7FF7", +", c #1E80F7", +"< c #5247F7", +"1 c #5536D9", +"2 c #263498", +"T c None", +/* pixels */ +"TTT ", +"TTTT....", +"TTTXXXXX", +"TToooooo", +"TTTOO+O+", +"TTTT@@@@", +"TTT##$##", +"TT&*&&&&", +"TTT=====", +"TTTT----", +"TTT:;;:;", +"TT,>,,,,", +"TTT<<<<<", +"TTTT1111", +"TTT22222" +}; diff --git a/layers/+themes/colors/local/nyan-mode/img/rainbow.xpm b/layers/+themes/colors/local/nyan-mode/img/rainbow.xpm new file mode 100644 index 0000000..1ed1bc2 --- /dev/null +++ b/layers/+themes/colors/local/nyan-mode/img/rainbow.xpm @@ -0,0 +1,42 @@ +/* XPM */ +static char *rainbow[] = { +/* columns rows colors chars-per-pixel */ +"8 15 21 1 ", +" c #522244", +". c #BF1119", +"X c #F52A02", +"o c #FC7800", +"O c #FBA500", +"+ c #FCA500", +"@ c #F0D300", +"# c #B4BF00", +"$ c #B5BF00", +"% c #4D9801", +"& c #4E9802", +"* c #4E9801", +"= c #2CCB13", +"- c #20D15C", +"; c #0EA7CB", +": c #0EA6CB", +"> c #1E7FF7", +", c #1E80F7", +"< c #5247F7", +"1 c #5536D9", +"2 c #263498", +/* pixels */ +" ", +"........", +"XXXXXXXX", +"oooooooo", +"OOOOO+O+", +"@@@@@@@@", +"#####$##", +"%&&*&&&&", +"========", +"--------", +";;;:;;:;", +">,,>,,,,", +"<<<<<<<<", +"11111111", +"22222222" +}; diff --git a/layers/+themes/colors/local/nyan-mode/mus/nyanlooped.mp3 b/layers/+themes/colors/local/nyan-mode/mus/nyanlooped.mp3 new file mode 100644 index 0000000..fe406b8 Binary files /dev/null and b/layers/+themes/colors/local/nyan-mode/mus/nyanlooped.mp3 differ diff --git a/layers/+themes/colors/local/nyan-mode/nyan-mode.el b/layers/+themes/colors/local/nyan-mode/nyan-mode.el new file mode 100644 index 0000000..eb4fe9f --- /dev/null +++ b/layers/+themes/colors/local/nyan-mode/nyan-mode.el @@ -0,0 +1,262 @@ +;;; nyan-mode.el --- Nyan Cat shows position in current buffer in mode-line. +;;; +;;; Nyanyanyanyanyanyanya! +;;; +;;; Author: Jacek "TeMPOraL" Zlydach +;;; URL: http://nyan-mode.buildsomethingamazing.com +;;; Version: 0.2 +;;; Keywords: nyan, cat, lulz, pop tart cat, build something amazing +;;; +;;; Inspired by (and in few places copied from) sml-modeline.el, +;;; written by Lennart Borgman +;;; See: http://bazaar.launchpad.net/~nxhtml/nxhtml/main/annotate/head%3A/util/sml-modeline.el + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; LICENSE +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; 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, 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; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth +;; Floor, Boston, MA 02110-1301, USA. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; Some TODOs +;;; * Investigate why wavy rainbow didn't work on Antoszka's computer. +;;; * Refactor-out :set lambdas in customs if possible. +;;; * MAYBE add something to protect users from going to 0 with nyanbar width? +;;; * Add credits for used images. +(defgroup nyan nil + "Customization group for `nyan-mode'." + :group 'frames) + +(defun nyan-refresh () + "Refresh after option changes if loaded." + (when (featurep 'nyan-mode) + (when (and (boundp 'nyan-mode) + nyan-mode) + (nyan-mode -1) + (nyan-mode 1)))) + +(defcustom nyan-animation-frame-interval 0.2 + "Number of seconds between animation frames." + :set (lambda (sym val) + (set-default sym val) + (nyan-refresh)) + :group 'nyan) + +(defvar nyan-animation-timer nil) +(defvar nyan-animation-loop-count 0) +(defvar nyan-animation-loop-max 1) + +(defun nyan-start-animation () + (interactive) + (when (not nyan-animation-timer) + (setq nyan-animation-timer + (run-at-time "0 sec" + nyan-animation-frame-interval + 'nyan-swich-anim-frame) + nyan-animation-loop-count 0))) + +(defun nyan-stop-animation () + (interactive) + (when nyan-animation-timer + (cancel-timer nyan-animation-timer) + (setq nyan-animation-timer nil))) + +;; mplayer needs to be installed for that +(defun nyan-start-music () + (interactive) + (start-process-shell-command "nyan-music" "nyan-music" (concat "mplayer " +nyan-music+ " -loop 0"))) + +(defun nyan-stop-music () + (interactive) + (kill-process "nyan-music")) + +;;; FIXME bug, doesn't work for antoszka. +(defcustom nyan-wavy-trail nil + "If enabled, Nyan Cat's rainbow trail will be wavy." + :type '(choice (const :tag "Enabled" t) + (const :tag "Disabled" nil)) + :set (lambda (sym val) + (set-default sym val) + (nyan-refresh)) + :group 'nyan) + +(defcustom nyan-bar-length 32 + "Length of Nyan Cat bar in units; each unit is equal to an 8px + image. Minimum of 3 units are required for Nyan Cat." + :set (lambda (sym val) + (set-default sym val) + (nyan-refresh)) + :group 'nyan) + +(defcustom nyan-animate-nyancat nil + "Enable animation for Nyan Cat. +This can be t or nil." + :type '(choice (const :tag "Enabled" t) + (const :tag "Disabled" nil)) + :set (lambda (sym val) + (set-default sym val) + (if val + (nyan-start-animation) + (nyan-stop-animation)) + (nyan-refresh)) + :group 'nyan) + +(defcustom nyan-cat-face-number 1 + "Select cat face number for console." + ) + +(defconst +nyan-directory+ (file-name-directory (or load-file-name buffer-file-name))) + +(defconst +nyan-cat-size+ 3) + +(defconst +nyan-cat-image+ (concat +nyan-directory+ "img/nyan.xpm")) +(defconst +nyan-cat-start-image+ (concat +nyan-directory+ "img/nyan-start.xpm")) +(defconst +nyan-rainbow-image+ (concat +nyan-directory+ "img/rainbow.xpm")) +(defconst +nyan-rainbow-start-image+ (concat +nyan-directory+ "img/rainbow-start.xpm")) +(defconst +nyan-outerspace-image+ (concat +nyan-directory+ "img/outerspace.xpm")) + +(defconst +nyan-music+ (concat +nyan-directory+ "mus/nyanlooped.mp3")) + +;;; Load images of Nyan Cat an it's rainbow. +(defvar nyan-cat-image (create-image +nyan-cat-image+ 'xpm nil :ascent 'center)) +(defvar nyan-cat-start-image (create-image +nyan-cat-start-image+ 'xpm nil :ascent 'center)) + +(defvar nyan-animation-frames (mapcar (lambda (id) + (create-image (concat +nyan-directory+ (format "img/nyan-frame-%d.xpm" id)) + 'xpm nil :ascent 'center)) + '(1 2 3 4 5 6))) + +(defvar nyan-last-rainbow-count 0) + +(defvar nyan-current-frame 0) + +(defconst +catface+ [ + ["[]*" "[]#"] + ["(*^ー゚)" "( ^ー^)" "(^ー^ )" "(゚ー^*)"] + ["(´ω`三 )" "( ´ω三` )" "( ´三ω` )" "( 三´ω`)" + "( 三´ω`)" "( ´三ω` )" "( ´ω三` )" "(´ω`三 )"] + ["(´д`;)" "( ´д`;)" "( ;´д`)" "(;´д` )"] + ["(」・ω・)」" "(/・ω・)/" "(」・ω・)」" "(/・ω・)/" + "(」・ω・)」" "(/・ω・)/" "(」・ω・)」" "\(・ω・)/"] + ["(>ワ<三   )" "( >ワ三<  )" + "(  >三ワ< )" "(   三>ワ<)" + "(  >三ワ< )" "( >ワ三<  )"]]) + +(defun nyan-swich-anim-frame () +(when (> nyan-animation-loop-count nyan-animation-loop-max) + (nyan-stop-animation)) + (setq nyan-current-frame (% (+ 1 nyan-current-frame) 6)) + (when (equal nyan-current-frame 5) + (setq nyan-animation-loop-count (1+ nyan-animation-loop-count))) + (redraw-modeline)) + +(defun nyan-get-anim-frame (rainbows &optional start) + (if (and nyan-animation-timer (> rainbows 0)) + (nth nyan-current-frame nyan-animation-frames) + (if start nyan-cat-start-image nyan-cat-image))) + +(defun nyan-wavy-rainbow-ascent (number) + (if nyan-animation-timer + (min 100 (+ 81 + (* 3 (abs (- (/ 6 2) + (% (+ number nyan-current-frame) + 6)))))) + (if (< (% number 6) 3) 90 'center))) + +(defun nyan-number-of-rainbows () + (round (/ (* (round (* 100 + (/ (- (float (point)) + (float (point-min))) + (float (point-max))))) + (- nyan-bar-length +nyan-cat-size+)) + 100))) + +(defun catface () (aref +catface+ nyan-cat-face-number)) + +(defun catface-index () + (min (round (/ (* (round (* 100 + (/ (- (float (point)) + (float (point-min))) + (float (point-max))))) + (length (catface))) + 100)) (- (length (catface)) 1))) + +(defun nyan-create () + (let* ((rainbows (nyan-number-of-rainbows)) + (outerspaces (- nyan-bar-length rainbows +nyan-cat-size+)) + (rainbow-string "") + (rainbow-start t) + (nyancat-string (propertize + (aref (catface) (catface-index)) + 'display (nyan-get-anim-frame rainbows (eq rainbows 0)))) + (outerspace-string "")) + + (if (and nyan-animate-nyancat + (not (equal nyan-last-rainbow-count rainbows))) + (nyan-start-animation)) + (setq nyan-last-rainbow-count rainbows) + + (dotimes (number rainbows) + (setq rainbow-string + (concat rainbow-string + (propertize + "|" + 'display (create-image (if rainbow-start +nyan-rainbow-start-image+ + +nyan-rainbow-image+) + 'xpm nil + :ascent + (if (and nyan-wavy-trail + (or (not nyan-animate-nyancat) + (and nyan-animate-nyancat nyan-animation-timer))) + (nyan-wavy-rainbow-ascent number) + 'center))))) + (setq rainbow-start nil) + ) + (dotimes (number outerspaces) + (setq outerspace-string + (concat outerspace-string + (propertize + "-" + 'display (create-image +nyan-outerspace-image+ + 'xpm nil :ascent (if nyan-animation-timer 95 'center)))))) + ;; Compute Nyan Cat string. + (concat rainbow-string + nyancat-string + outerspace-string))) + +(defvar nyan-old-car-mode-line-position nil) + +;;;###autoload +(define-minor-mode nyan-mode + "Use NyanCat to show buffer size and position in mode-line. +You can customize this minor mode, see option `nyan-mode'. + +Note: If you turn this mode on then you probably want to turn off +option `scroll-bar-mode'." + :global t + :group 'nyan + (if nyan-mode + (progn + (unless nyan-old-car-mode-line-position + (setq nyan-old-car-mode-line-position (car mode-line-position))) + (setcar mode-line-position '(:eval (list (nyan-create))))) + (setcar mode-line-position nyan-old-car-mode-line-position))) + + +(provide 'nyan-mode) + +;;; nyan-mode.el ends here diff --git a/layers/+themes/colors/packages.el b/layers/+themes/colors/packages.el new file mode 100644 index 0000000..baed236 --- /dev/null +++ b/layers/+themes/colors/packages.el @@ -0,0 +1,125 @@ +;;; packages.el --- Colors Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq colors-packages + '( + ;; not working well for now + ;; rainbow-blocks + (nyan-mode :location local) + color-identifiers-mode + rainbow-identifiers + rainbow-mode + )) + +;; (defun colors/init-rainbow-blocks () +;; (use-package rainbow-blocks +;; :disabled t +;; :init (add-hook 'emacs-lisp-mode-hook 'rainbow-blocks-mode))) + +(defun colors/init-nyan-mode () + (use-package nyan-mode + :if colors-enable-nyan-cat-progress-bar + :config + (progn + (setq nyan-wavy-trail t) + (setq nyan-animate-nyancat t) + (nyan-mode) + ;; explicitly re-enable the cat for the first GUI client + (spacemacs|do-after-display-system-init + (nyan-mode -1) + (nyan-mode)) + + (spacemacs|add-toggle nyan-cat-progress-bar + :mode nyan-mode + :documentation "Show a nyan cat progress bar in the mode-line." + :evil-leader "tmn")))) + +(defun colors/init-color-identifiers-mode () + (use-package color-identifiers-mode + :commands color-identifiers-mode + :defer t + :init + (progn + (when (eq 'variables colors-colorize-identifiers) + (global-color-identifiers-mode)) + (spacemacs/declare-prefix "Ci" "colors-identifiers") + (spacemacs|add-toggle color-identifiers-mode + :status color-identifiers-mode + :on (progn + (when (bound-and-true-p rainbow-identifiers-mode) + (rainbow-identifiers-mode -1)) + (color-identifiers-mode)) + :off (color-identifiers-mode -1) + :documentation "Colorize variables." + :evil-leader "tCv") + (spacemacs|add-toggle global-color-identifiers-mode + :status global-color-identifiers-mode + :on (progn + (when (bound-and-true-p global-rainbow-identifiers-mode) + (global-rainbow-identifiers-mode -1)) + (global-color-identifiers-mode)) + :off (global-color-identifiers-mode -1) + :documentation "Colorize variables globally." + :evil-leader "tC C-v")) + :config (spacemacs|hide-lighter color-identifiers-mode))) + +(defun colors/init-rainbow-identifiers () + (use-package rainbow-identifiers + :commands (global-rainbow-identifiers-mode + rainbow-identifiers-mode) + :init + (progn + (setq rainbow-identifiers-choose-face-function 'rainbow-identifiers-cie-l*a*b*-choose-face + rainbow-identifiers-cie-l*a*b*-saturation 100 + rainbow-identifiers-cie-l*a*b*-lightness 40 + ;; override theme faces + rainbow-identifiers-faces-to-override '(highlight-quoted-symbol + font-lock-keyword-face + font-lock-function-name-face + font-lock-variable-name-face)) + (defadvice spacemacs/post-theme-init (after colors/post-theme-init activate) + "Adjust lightness and brightness of rainbow-identifiers on post theme init." + (colors//tweak-theme-colors spacemacs--cur-theme)) + ;; key bindings + (spacemacs/declare-prefix "Ci" "colors-identifiers") + (spacemacs|add-toggle rainbow-identifier + :status rainbow-identifiers-mode + :on (progn + (when (bound-and-true-p color-identifiers-mode) + (color-identifiers-mode -1)) + (rainbow-identifiers-mode)) + :off (rainbow-identifiers-mode -1) + :documentation "Colorize all identifiers." + :evil-leader "tCa") + (with-eval-after-load 'rainbow-identifiers + (define-global-minor-mode global-rainbow-identifiers-mode + rainbow-identifiers-mode colors//rainbow-identifiers-mode-maybe)) + (spacemacs|add-toggle global-rainbow-identifiers-mode + :status global-rainbow-identifiers-mode + :on (progn + (when (bound-and-true-p global-color-identifiers-mode) + (global-color-identifiers-mode -1)) + (global-rainbow-identifiers-mode)) + :off (global-rainbow-identifiers-mode -1) + :documentation "Colorize identifiers globally." + :evil-leader "tC C-a") + (spacemacs/set-leader-keys "Cis" 'colors/start-change-color-saturation) + (spacemacs/set-leader-keys "Cil" 'colors/start-change-color-lightness) + ;; tweak colors of current theme + (colors//tweak-theme-colors spacemacs--cur-theme) + (when (eq 'all colors-colorize-identifiers) + (global-rainbow-identifiers-mode))))) + +(defun colors/init-rainbow-mode () + (use-package rainbow-mode + :defer t + :init (spacemacs/set-leader-keys "tCc" 'rainbow-mode) + :config (spacemacs|hide-lighter rainbow-mode))) diff --git a/layers/+themes/themes-megapack/README.org b/layers/+themes/themes-megapack/README.org new file mode 100644 index 0000000..b59afef --- /dev/null +++ b/layers/+themes/themes-megapack/README.org @@ -0,0 +1,16 @@ +#+TITLE: Themes Megapack layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#what-is-this][What is this?]] + - [[#install][Install]] + +* What is this? +This simple contribution layer is an example. It installs around 100 themes +for Emacs. You can try them easily by invoking helm-themes with: ~SPC T s~. + +You can see samples of all included themes in this [[http://themegallery.robdor.com][theme gallery]] from [[http://www.twitter.com/robmerrell][Rob Merrell]]. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =themes-megapack= to the existing =dotspacemacs-configuration-layers= list in this +file. diff --git a/layers/+themes/themes-megapack/packages.el b/layers/+themes/themes-megapack/packages.el new file mode 100644 index 0000000..e36c942 --- /dev/null +++ b/layers/+themes/themes-megapack/packages.el @@ -0,0 +1,115 @@ +;;; packages.el --- Themes Mega-Pack Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq themes-megapack-packages + '( + afternoon-theme + alect-themes + ample-theme + ample-zen-theme + apropospriate-theme + anti-zenburn-theme + ;; contains errors + ; badger-theme + badwolf-theme + birds-of-paradise-plus-theme + bubbleberry-theme + busybee-theme + cherry-blossom-theme + clues-theme + color-theme-sanityinc-solarized + color-theme-sanityinc-tomorrow + cyberpunk-theme + dakrone-theme + darkburn-theme + darkmine-theme + darkokai-theme + darktooth-theme + django-theme + dracula-theme + espresso-theme + farmhouse-theme + firebelly-theme + flatland-theme + flatui-theme + gandalf-theme + gotham-theme + grandshell-theme + gruber-darker-theme + gruvbox-theme + hc-zenburn-theme + hemisu-theme + heroku-theme + inkpot-theme + ir-black-theme + jazz-theme + jbeans-theme + light-soap-theme + lush-theme + majapahit-theme + material-theme + minimal-theme + moe-theme + molokai-theme + monokai-theme + monochrome-theme + mustang-theme + naquadah-theme + niflheim-theme + noctilux-theme + obsidian-theme + occidental-theme + omtose-phellack-theme + oldlace-theme + organic-green-theme + pastels-on-dark-theme + phoenix-dark-mono-theme + phoenix-dark-pink-theme + planet-theme + professional-theme + purple-haze-theme + railscasts-theme + reverse-theme + seti-theme + smyx-theme + soft-charcoal-theme + soft-morning-theme + soft-stone-theme + soothe-theme + spacegray-theme + subatomic-theme + subatomic256-theme + sublime-themes + sunny-day-theme + tango-2-theme + tango-plus-theme + tangotango-theme + tao-theme + ;; contains error + ; tommyh-theme + toxi-theme + tronesque-theme + twilight-anti-bright-theme + twilight-bright-theme + twilight-theme + ujelly-theme + underwater-theme + zen-and-art-theme + zenburn-theme + zonokai-theme + )) + +;; define programmatically the init functions +(dolist (pkg themes-megapack-packages) + (eval `(defun ,(intern (format "themes-megapack/init-%S" pkg)) nil))) + +(defun themes-megapack/init-darkokai-theme () + (setq darkokai-mode-line-padding 1)) diff --git a/layers/+themes/theming/README.org b/layers/+themes/theming/README.org new file mode 100644 index 0000000..e99f60b --- /dev/null +++ b/layers/+themes/theming/README.org @@ -0,0 +1,87 @@ +#+TITLE: Theming layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#usage][Usage]] + - [[#attributes][Attributes]] + - [[#faces][Faces]] + - [[#headers][Headers]] + +* Description +This layer allows for a simple way of modifying themes. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =theming= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Usage +To use this layer, set the value of =theming-modifications=. It should be a list +of the following form: + +#+begin_src emacs-lisp + ((theme1 (face1 attributes...) + (face2 attributes...) + ...) + (theme2 (face1 attributes...) + (face2 attributes...) + ...) + ...) +#+end_src + +This will apply the given attributes to the relevant faces whenever the +appropriate theme is loaded. To update without changing the theme, use ~SPC SPC +spacemacs/update-theme~. + +* Attributes +See [[http://www.gnu.org/software/emacs/manual/html_node/elisp/Face-Attributes.html#Face-Attributes][face attributes]] in the Emacs manual for more information. Some of the more +common attributes you might want to tweak are the following: + +- =:inherit= :: the name of a face to inherit attributes from +- =:foreground= and =:background= :: Hexadecimal color strings +- =:height= :: typically a floating point number (1.0 gives the same height as + the underlying face) +- =:weight= :: typically =bold= or =normal= +- =:underline= :: typically =nil= or =t= +- =:slant= :: typically =oblique=, =italic= or =normal= +- =:box= :: set to =t= to draw a box around characters in the foreground + +* Faces +To see a list over all loaded faces and what they look like, use ~SPC SPC +list-faces-display~. You can also use ~SPC h d c~ (describe character) on a +character to see its face. + +Some of the most common faces to modify are the syntactical elements: +- =font-lock-builtin-face= +- =font-lock-comment-delimiter-face= +- =font-lock-comment-face= +- =font-lock-constant-face= +- =font-lock-doc-face= +- =font-lock-function-name-face= +- =font-lock-keyword-face= +- =font-lock-preprocessor-face= +- =font-lock-string-face= +- =font-lock-type-face= +- =font-lock-variable-name-face= +- =font-lock-warning-face= + +As well as the mode-line faces for the active and inactive windows: +- =powerline-active1= +- =powerline-active2= +- =powerline-inactive1= +- =powerline-inactive2= +- =mode-line= +- =mode-line-inactive= + +* Headers +This layer includes three additional layer variables for tweaking headings. +Allowed values are a list of themes in which the given effect should happen, or +the symbol =all= to apply it on all themes. + +- =theming-headings-inherit-from-default= :: inherits all headings from the + default face to avoid non-monospaced fonts +- =theming-headings-same-size= :: sets the =:height= attribute to one on all + headings to give them the same size as the rest of the text +- =theming-headings-bold= :: sets the =:weight= attribute to bold on all + headings diff --git a/layers/+themes/theming/config.el b/layers/+themes/theming/config.el new file mode 100644 index 0000000..8784457 --- /dev/null +++ b/layers/+themes/theming/config.el @@ -0,0 +1,60 @@ +;;; config.el --- Theming Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar theming-modifications '() + "An alist of theme modifications. Each element should +be on the form (THEME . SPEC), where THEME is a symbol +representing a theme, and SPEC is an alist mapping faces +to face specs (see `defface').") + +(defvar theming-headings-inherit-from-default '() + "A list of themes where all headings should inherit +from the default face, or the symbol `all'.") + +(defvar theming-headings-same-size '() + "A list of themes where all headings should have the +same size, or the symbol `all'.") + +(defvar theming-headings-bold '() + "A list of themes where all headings should be bold, +or the symbol `all'.") + +(defvar spacemacs--theming-modified-faces '()) + +(defvar spacemacs--theming-header-faces + '(font-latex-sectioning-0-face + font-latex-sectioning-1-face + font-latex-sectioning-2-face + font-latex-sectioning-3-face + font-latex-sectioning-4-face + font-latex-sectioning-5-face + font-latex-slide-title-face + info-title-1 + info-title-2 + info-title-3 + info-title-4 + markdown-header-face + markdown-header-face-1 + markdown-header-face-2 + markdown-header-face-3 + markdown-header-face-4 + markdown-header-face-5 + markdown-header-face-6 + org-document-title + org-level-1 + org-level-2 + org-level-3 + org-level-4 + org-level-5 + org-level-6 + org-level-7 + org-level-8) + "List of header faces.") diff --git a/layers/+themes/theming/funcs.el b/layers/+themes/theming/funcs.el new file mode 100644 index 0000000..1472f9a --- /dev/null +++ b/layers/+themes/theming/funcs.el @@ -0,0 +1,46 @@ +;;; config.el --- Theming Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spacemacs//in-or-all (key seq) + (or (eq 'all seq) (memq key seq))) + +(defun spacemacs//theming (theme &optional no-confirm no-enable) + "Removes existing user theming and applies customizations for the given +theme." + (unless no-enable + + ;; Remove existing modifications + (dolist (face spacemacs--theming-modified-faces) + (custom-set-faces `(,face ((t ()))))) + (setq spacemacs--theming-modified-faces nil) + + ;; Headings + (let ((mods nil)) + (when (spacemacs//in-or-all theme theming-headings-inherit-from-default) + (setq mods (plist-put mods :inherit 'default))) + (when (spacemacs//in-or-all theme theming-headings-same-size) + (setq mods (plist-put mods :height 1.0))) + (when (spacemacs//in-or-all theme theming-headings-bold) + (setq mods (plist-put mods :weight 'bold))) + (when mods + (dolist (face spacemacs--theming-header-faces) + (custom-set-faces `(,face ((t ,mods)))) + (push face spacemacs--theming-modified-faces)))) + + ;; Add new modifications + (dolist (spec (append (cdr (assq theme theming-modifications)) + (cdr (assq t theming-modifications)))) + (custom-set-faces `(,(car spec) ((t ,(cdr spec))))) + (push (car spec) spacemacs--theming-modified-faces)))) + +(defun spacemacs/update-theme () + (interactive) + (spacemacs//theming spacemacs--cur-theme)) diff --git a/layers/+themes/theming/packages.el b/layers/+themes/theming/packages.el new file mode 100644 index 0000000..bf17153 --- /dev/null +++ b/layers/+themes/theming/packages.el @@ -0,0 +1,19 @@ +;;; packages.el --- Theming Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defconst theming-packages + '((theming :location local))) + +(defun theming/init-theming () + ;; Apply theme customizations after any call to load-theme + (advice-add 'load-theme :after 'spacemacs//theming) + ;; Apply the initial customizations now, because load-theme has already been called + (spacemacs//theming spacemacs--cur-theme)) diff --git a/layers/+tools/ansible/README.org b/layers/+tools/ansible/README.org new file mode 100644 index 0000000..ff57bec --- /dev/null +++ b/layers/+tools/ansible/README.org @@ -0,0 +1,22 @@ +#+TITLE: Ansible layer + +[[file:img/ansible.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + +* Description +This layer adds support for Ansible-flavored YAML buffers and Jinja2 templates. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =ansible= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key bindings + +| Key Binding | Description | +|-------------+------------------------------------------| +| ~SPC m h a~ | looks up documentation using [[https://github.com/lunaryorn/ansible-doc.el][ansible-doc]] | diff --git a/layers/+tools/ansible/config.el b/layers/+tools/ansible/config.el new file mode 100644 index 0000000..e859943 --- /dev/null +++ b/layers/+tools/ansible/config.el @@ -0,0 +1,15 @@ +;;; config.el --- Ansible Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Brian Hicks +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; detect filenames compatible with Ansible's recommended layout. +;; http://docs.ansible.com/playbooks_best_practices.html#directory-layout +(setq ansible/ansible-filename-re + "\\(site\.yml\\|roles/.+\.yml\\|group_vars/.+\\|host_vars/.+\\)") diff --git a/layers/+tools/ansible/funcs.el b/layers/+tools/ansible/funcs.el new file mode 100644 index 0000000..5c7a0fe --- /dev/null +++ b/layers/+tools/ansible/funcs.el @@ -0,0 +1,19 @@ +;;; funcs.el --- Ansible Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Brian Hicks +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(defun ansible/ansible-should-enable? () + (and (stringp buffer-file-name) + (string-match ansible/ansible-filename-re buffer-file-name))) + +(defun ansible/ansible-maybe-enable () + (when (ansible/ansible-should-enable?) (ansible 1))) + +(defun ansible/ansible-doc-maybe-enable () + (when (ansible/ansible-should-enable?) (ansible-doc-mode 1))) diff --git a/layers/+tools/ansible/img/ansible.png b/layers/+tools/ansible/img/ansible.png new file mode 100644 index 0000000..3d12c5f Binary files /dev/null and b/layers/+tools/ansible/img/ansible.png differ diff --git a/layers/+tools/ansible/layers.el b/layers/+tools/ansible/layers.el new file mode 100644 index 0000000..c14d396 --- /dev/null +++ b/layers/+tools/ansible/layers.el @@ -0,0 +1,12 @@ +;;; layers.el --- Ansible Layer layers File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Brian Hicks +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(configuration-layer/declare-layers '(yaml)) diff --git a/layers/+tools/ansible/packages.el b/layers/+tools/ansible/packages.el new file mode 100644 index 0000000..5494c28 --- /dev/null +++ b/layers/+tools/ansible/packages.el @@ -0,0 +1,44 @@ +;;; packages.el --- Ansible Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Brian Hicks +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(setq ansible-packages + '(ansible + ansible-doc + company + jinja2-mode + yaml-mode)) + +(defun ansible/init-ansible () + (use-package ansible + :defer t + :init (add-to-list 'auto-mode-alist + '("\\(group_vars/.+\\|host_vars/.+\\)" . yaml-mode)))) + +(defun ansible/init-ansible-doc () + (use-package ansible-doc :defer t)) + +(defun ansible/post-init-company () + ;; ansible-mode requires ac-user-dictionary-files. If the + ;; config is using company-mode this variable will not be + ;; set, so we set it to a dummy value. + ;; + ;; Tracking here: + ;; https://github.com/k1LoW/emacs-ansible/issues/2 + (defvar ac-user-dictionary-files nil)) + +(defun ansible/init-jinja2-mode () + (use-package jinja2-mode + :mode ("\\.j2\\'" . jinja2-mode) + :defer t)) + +(defun ansible/post-init-yaml-mode () + (spacemacs/set-leader-keys-for-major-mode 'yaml-mode "ha" 'ansible-doc) + (spacemacs/add-to-hook 'yaml-mode-hook '(ansible/ansible-maybe-enable + ansible/ansible-doc-maybe-enable))) diff --git a/layers/+tools/cfengine/README.org b/layers/+tools/cfengine/README.org new file mode 100644 index 0000000..da7c42a --- /dev/null +++ b/layers/+tools/cfengine/README.org @@ -0,0 +1,59 @@ +#+TITLE: CFEngine layer + +[[file:./img/agent.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#configuration][Configuration]] + - [[#set-file-permission-on-save][Set file permission on save]] + - [[#indendation][Indendation]] + - [[#key-bindings][Key bindings]] + +* Description +This layer makes working with CFEngine policy easier: +- Syntax highlighting +- On the fly syntax checks (via =syntax-checking= layer) +- Auto completion (via =auto-completion= layer) + +* Install +Add =cfengine= to the =dotspacemacs-configuration-layers= in your =~/.spacemacs= +to use this layer. + +* Configuration +** Set file permission on save +Here is a function to set permissions to 600 on save, this can help avoid +errors like: + +=File ./example.cf (owner 1000) is writable by others (security exception)= + +#+BEGIN_SRC elisp +(defun cfengine-permissions-policy-owner-only () + "If file starts with a shebang, make `buffer-file-name' executable" + (save-excursion + (set-file-modes buffer-file-name #o600) + (message (concat "Made " buffer-file-name " accessibly only by the owner (600).")))) + +(add-hook 'after-save-hook 'cfengine-permissions-policy-owner-only nil 'make-it-local) +#+END_SRC + +** Indendation +If you like attributes to be intended from the promiser set =Indentation amount +from anchor= to =2=. For example: + +#+begin_src cfengine3 + bundle agent main + { + vars: + + "promiser" + string => "value", + comment => "Indented 2 spaces from promiser"; + } +#+end_src + +* Key bindings + +| Key Binding | Description | +|-------------+-----------------------| +| ~ m j~ | Reformats JSON string | diff --git a/layers/+tools/cfengine/config.el b/layers/+tools/cfengine/config.el new file mode 100644 index 0000000..39d6d7e --- /dev/null +++ b/layers/+tools/cfengine/config.el @@ -0,0 +1,12 @@ +;;; config.el --- CFEgine Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Nick Anderson +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(spacemacs|defvar-company-backends cfengine3-mode) diff --git a/layers/+tools/cfengine/img/agent.png b/layers/+tools/cfengine/img/agent.png new file mode 100644 index 0000000..d5b7dc9 Binary files /dev/null and b/layers/+tools/cfengine/img/agent.png differ diff --git a/layers/+tools/cfengine/packages.el b/layers/+tools/cfengine/packages.el new file mode 100644 index 0000000..7ccba0f --- /dev/null +++ b/layers/+tools/cfengine/packages.el @@ -0,0 +1,34 @@ +;;; packages.el --- cfengine layer packages file for Spacemacs. +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Nick Anderson +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defconst cfengine-packages + '( + (cfengine3-mode :location built-in) + company + eldoc + flycheck + )) + +(defun cfengine/init-cfengine3-mode () + (use-package cfengine3-mode + :defer t + :mode ("\\.cf\\'" . cfengine3-mode) + :init (spacemacs/set-leader-keys-for-major-mode 'cfengine3-mode + "j" 'cfengine3-reformat-json-string))) + +(defun cfengine/post-init-company () + (spacemacs|add-company-hook cfengine3-mode)) + +(defun cfengine/post-init-eldoc () + (add-hook 'cfengine3-mode-hook 'eldoc-mode)) + +(defun cfengine/post-init-flycheck () + (spacemacs/add-flycheck-hook 'cfengine3-mode-hook)) diff --git a/layers/+tools/chrome/README.org b/layers/+tools/chrome/README.org new file mode 100644 index 0000000..60d8eca --- /dev/null +++ b/layers/+tools/chrome/README.org @@ -0,0 +1,58 @@ +#+TITLE: Chrome layer + +[[file:img/chrome.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#chrome-extension][Chrome extension]] + - [[#configuration][Configuration]] + +* Description +This layer provides some integration with the Google Chrome browser. + +** Features +- Edit text boxes with Emacs using [[http://melpa.org/#/edit-server][edit-server]] + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =chrome= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Chrome extension +[[http://melpa.org/#/edit-server][edit-server]] is a server that responds to edit requests sent Chrome via the +Google Chrome extension [[https://chrome.google.com/webstore/detail/edit-with-emacs/ljobjlafonikaiipfkggjbhkghgicgoh][Edit with Emacs]]. You have to install this extension. + +More information can be found on [[http://www.emacswiki.org/emacs/Edit_with_Emacs][Emacs Wiki]]. +The edit server is configured to start automatically when Spacemacs starts. + +* Configuration +Use =edit-server-url-major-mode-alist= to choose a major mode initialization +function based on =edit-server-url=, or fall back to +=edit-server-default-major-mode= that has a current value of =markdown-mode=. + +#+BEGIN_SRC emacs-lisp + (defun dotspacemacs/user-config () + ;; Open github text areas as org buffers + ;; currently they are opened as markdown + (setq edit-server-url-major-mode-alist + '(("github\\.com" . org-mode)))) +#+END_SRC + +To change frame defaults (width, height, etc. use =edit-server-new-frame-alist=) + +#+BEGIN_SRC emacs-lisp + (add-to-list 'edit-server-new-frame-alist '(width . 140)) + (add-to-list 'edit-server-new-frame-alist '(height . 60)) +#+END_SRC + +If you want Emacs to switch focus to Chrome after done editing, you can utilize =edit-server-done-hook=. +Emacs cannot control focus of windows for external apps, so you need to use some sort of command line window manager like =wmctrl=. +The following example works on OS X: + +#+BEGIN_SRC emacs-lisp + (add-hook 'edit-server-done-hook (lambda () (shell-command "open -a \"Google Chrome\""))) +#+END_SRC diff --git a/layers/+tools/chrome/img/chrome.png b/layers/+tools/chrome/img/chrome.png new file mode 100644 index 0000000..1710c03 Binary files /dev/null and b/layers/+tools/chrome/img/chrome.png differ diff --git a/layers/+tools/chrome/packages.el b/layers/+tools/chrome/packages.el new file mode 100644 index 0000000..592a8d0 --- /dev/null +++ b/layers/+tools/chrome/packages.el @@ -0,0 +1,28 @@ +;;; packages.el --- Chrome Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Ben Hayden +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq chrome-packages '( + edit-server + gmail-message-mode + )) + +(defun chrome/init-edit-server () + (use-package edit-server + :init + (progn + (edit-server-start)) + :config + (progn + (setq edit-server-default-major-mode 'markdown-mode)) + )) + +(defun chrome/init-gmail-message-mode ( ) + (use-package gmail-message-mode)) diff --git a/layers/+tools/command-log/README.org b/layers/+tools/command-log/README.org new file mode 100644 index 0000000..3df6701 --- /dev/null +++ b/layers/+tools/command-log/README.org @@ -0,0 +1,22 @@ +#+TITLE: command-log layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + +* Description +command-log can be used to demo Emacs to an audience. When activated, +keystrokes get logged into a designated buffer, along with the command +bound to them. For more info check [[https://github.com/lewang/command-log-mode][command-log-mode]]. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =command-log= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key bindings + +| Key Binding | Description | +|-------------+------------------------| +| ~SPC a L~ | Toggle the command log | diff --git a/layers/+tools/command-log/packages.el b/layers/+tools/command-log/packages.el new file mode 100644 index 0000000..9e42073 --- /dev/null +++ b/layers/+tools/command-log/packages.el @@ -0,0 +1,33 @@ +;;; packages.el --- command-log Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq command-log-packages + ;; bmag/command-log-mode is a fork of lewang/command-log-mode, and there + ;; is an open PR to merge the fork into the original repo. + ;; TODO when the PR is merged upstream, change to use the original package + ;; from MELPA (IOW remove :location argument) + '((command-log-mode :location (recipe :fetcher github + :repo "bmag/command-log-mode" + :branch "color")))) + +(defun command-log/init-command-log-mode () + (use-package command-log-mode + :commands global-command-log-mode + ;; :commands (clm/open-command-log-buffer global-command-log-mode spacemacs/toggle-command-log-mode) + :init + (spacemacs/set-leader-keys "aL" #'global-command-log-mode) + :config + (setq clm/log-command-exceptions* (append clm/log-command-exceptions* + '(evil-next-line + evil-previous-line + evil-forward-char + evil-backward-char)) + command-log-mode-auto-show t))) diff --git a/layers/+tools/dash/README.org b/layers/+tools/dash/README.org new file mode 100644 index 0000000..e022ce6 --- /dev/null +++ b/layers/+tools/dash/README.org @@ -0,0 +1,70 @@ +#+TITLE: Dash layer + +[[file:img/dash.png]] + +[[file:img/zeal.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#dash-os-x][Dash (OS X)]] + - [[#zeal-linux--windows][Zeal (Linux & Windows)]] + - [[#check-documentation-for-x-at-point][Check Documentation for x-at-point]] + - [[#key-bindings][Key bindings]] + - [[#helm-dash-and-counsel-dash][helm-dash and counsel-dash]] + +* Description +- [[http://kapeli.com/dash][dash]] :: Is a great tool for quick access to various sets of documentation, + only available in OS X. + +- [[https://github.com/stanaka/dash-at-point][dash-at-point]] :: Is the package used to integrate =dash= in Emacs. It will try + to intelligently guess specific docsets to use based off of + your current mode. + +- [[http://zealdocs.org/][zeal]] :: Zeal is an offline documentation browser inspired by Dash, + available for Linux and Windows. + +- [[https://github.com/jinzhu/zeal-at-point][zeal-at-point]] :: Run zeal-at-point to search the word at point (or string in + region), then Zeal is launched and search the word. Use + prefix argument C-u to edit the search string first. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =dash= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Dash (OS X) + +You have to install [[http://kapeli.com/dash][dash]] on your machine. + +It is recommended to set the =HUD mode= in your Dash application preferences +when using this layer. + +** Zeal (Linux & Windows) + +You have to install [[http://zealdocs.org/][zeal]] on your machine. + +Then install the docsets you use more frequently + +** Check Documentation for x-at-point + +See the documentation [[https://github.com/stanaka/dash-at-point#Usage][dash-at-point-usage]] , or [[https://github.com/jinzhu/zeal-at-point][zeal-at-point]] for more +information on customizing specific docsets for modes. + +* Key bindings + +| Key Binding | Description | +|-------------+-----------------------------------------------------------------| +| ~SPC d d~ | Lookup thing at point in Dash or Zeal | +| ~SPC d D~ | Lookup thing at point in Dash or Zeal within a specified Docset | +| ~SPC d h~ | Lookup thing at point in helm-dash or counsel-dash | +| ~SPC d H~ | Lookup in helm-dash or counsel-dash within a specified Docset | + +** helm-dash and counsel-dash +=dash-at-point= is linked to the GUI app and is only available for OSX. On +linux, you can use =zeal-at-point= which is linked to the GUI app too, but it's +open source. + +Or you can use [[https://github.com/areina/helm-dash][helm-dash]] when using =helm= and [[https://github.com/nathankot/counsel-dash][counsel-dash]] when using =ivy=, +which requires no additional application. You can use +=dash/helm-dash-docset-newpath= to set the location path of your docsets. diff --git a/layers/+tools/dash/config.el b/layers/+tools/dash/config.el new file mode 100644 index 0000000..e139c2e --- /dev/null +++ b/layers/+tools/dash/config.el @@ -0,0 +1,13 @@ +;;; config.el --- Dash Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar helm-dash-docset-newpath "~/.docsets" + "Path containing dash docsets.") diff --git a/layers/+tools/dash/funcs.el b/layers/+tools/dash/funcs.el new file mode 100644 index 0000000..101acb2 --- /dev/null +++ b/layers/+tools/dash/funcs.el @@ -0,0 +1,16 @@ +;;; funcs.el --- Dash Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun dash//activate-package-docsets (path) + "Add dash docsets from specified PATH." + (setq helm-dash-docsets-path path + helm-dash-common-docsets (helm-dash-installed-docsets)) + (message (format "activated %d docsets from: %s" + (length helm-dash-common-docsets) path))) diff --git a/layers/+tools/dash/img/dash.png b/layers/+tools/dash/img/dash.png new file mode 100644 index 0000000..2c88855 Binary files /dev/null and b/layers/+tools/dash/img/dash.png differ diff --git a/layers/+tools/dash/img/zeal.png b/layers/+tools/dash/img/zeal.png new file mode 100644 index 0000000..5388783 Binary files /dev/null and b/layers/+tools/dash/img/zeal.png differ diff --git a/layers/+tools/dash/packages.el b/layers/+tools/dash/packages.el new file mode 100644 index 0000000..d0e9e46 --- /dev/null +++ b/layers/+tools/dash/packages.el @@ -0,0 +1,60 @@ + ;; see conditional package inclusion +(setq dash-packages + '( + (helm-dash :toggle (configuration-layer/package-usedp 'helm)) + (counsel-dash :toggle (configuration-layer/package-usedp 'ivy)) + )) + +(cond + ((spacemacs/system-is-mac) + (push 'dash-at-point dash-packages)) + ((or (spacemacs/system-is-linux) + (spacemacs/system-is-mswindows)) + (push 'zeal-at-point dash-packages))) + +(defun dash/init-helm-dash () + (use-package helm-dash + :defer t + :init + (spacemacs/set-leader-keys + "dh" 'helm-dash-at-point + "dH" 'helm-dash) + :config + (dash//activate-package-docsets helm-dash-docset-newpath))) + +(defun dash/init-counsel-dash () + (use-package counsel-dash + :defer t + :init + (spacemacs/set-leader-keys + "dh" 'counsel-dash-at-point + "dH" 'counsel-dash) + (defun counsel-dash-at-point () + "Counsel dash with selected point" + (interactive) + (counsel-dash + (if (use-region-p) + (buffer-substring-no-properties (region-beginning) (region-end)) + (substring-no-properties (or (thing-at-point 'symbol) ""))))) + :config + (dash//activate-package-docsets helm-dash-docset-newpath))) + +(defun dash/init-dash-at-point () + (use-package dash-at-point + :defer t + :init + (progn + (spacemacs/set-leader-keys "dd" 'dash-at-point) + (spacemacs/set-leader-keys "dD" 'dash-at-point-with-docset)))) + +(defun dash/init-zeal-at-point () + (use-package zeal-at-point + :defer t + :init + (spacemacs/set-leader-keys + "dd" 'zeal-at-point + "dD" 'zeal-at-point-set-docset) + :config + ;; This lets users seach in multiple docsets + (push '(web-mode . "html,css,javascript") zeal-at-point-mode-alist) + )) diff --git a/layers/+tools/deft/README.org b/layers/+tools/deft/README.org new file mode 100644 index 0000000..5d4fbb3 --- /dev/null +++ b/layers/+tools/deft/README.org @@ -0,0 +1,50 @@ +#+TITLE: Deft layer + +* Table of Content :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#differences-from-default][Differences from default]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#configuration][Configuration]] + - [[#key-bindings][Key Bindings]] + +* Description +[[http://jblevins.org/projects/deft/][Deft]] is an Emacs mode inspired by =Notational Velocity= for quickly +browsing and creating notes. + +** Differences from default +This layer sets the default to use filenames for note titles as well as +=org-mode= for editing. The default extension is =org=. The default +configuration is set to recognize =org=, =md=, and =txt= extensions. If +you prefer that =Deft= recognize other extensions set an alternate +configuration by adding the following in your config file: + +#+Begin_SRC emacs-lisp + (setq deft-extensions '("org" "md" "txt")) +#+END_SRC + +Just add or substitute your preferred extension. + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =deft= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Configuration +By default deft tries to put notes in =~/.deft= but you can change +this like so in your =dotspacemacs/user-config= function: + +#+BEGIN_SRC emacs-lisp +(setq deft-directory "~/Dropbox/notes") +#+END_SRC + +* Key Bindings + +| Key Binding | Description | +|-------------+----------------------------------| +| ~SPC a n~ | Open Deft (works globally) | +| ~SPC m d~ | Delete selected note | +| ~SPC m r~ | Rename selected note | +| ~SPC m i~ | Toggle to regex search | +| ~SPC m n~ | Create new file with filter text | diff --git a/layers/+tools/deft/packages.el b/layers/+tools/deft/packages.el new file mode 100644 index 0000000..39e3d04 --- /dev/null +++ b/layers/+tools/deft/packages.el @@ -0,0 +1,39 @@ +;;; packages.el --- deft Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq deft-packages + '(deft)) + +(defun deft/init-deft () + (use-package deft + :defer t + :init + (progn + (setq deft-extensions '("org" "md" "txt") + deft-text-mode 'org-mode + deft-use-filename-as-title t + deft-use-filter-string-for-filename t) + (spacemacs/set-leader-keys "an" 'spacemacs/deft) + + (defun spacemacs/deft () + "Helper to call deft and then fix things so that it is nice and works" + (interactive) + (deft) + ;; Hungry delete wrecks deft's DEL override + (when (fboundp 'hungry-delete-mode) + (hungry-delete-mode -1)) + ;; When opening it you always want to filter right away + (evil-insert-state nil))) + :config (spacemacs/set-leader-keys-for-major-mode 'deft-mode + "d" 'deft-delete-file + "i" 'deft-toggle-incremental-search + "n" 'deft-new-file + "r" 'deft-rename-file))) diff --git a/layers/+tools/docker/README.org b/layers/+tools/docker/README.org new file mode 100644 index 0000000..1254446 --- /dev/null +++ b/layers/+tools/docker/README.org @@ -0,0 +1,48 @@ +#+TITLE: Docker layer + +[[file:img/docker.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[Description][Description]] + - [[Install][Install]] + - [[Usage][Usage]] + - [[TRAMP access to docker containers][TRAMP access to docker containers]] + - [[Key bindings][Key bindings]] + +* Description +This layer provides syntax highlighting and build functionality for Docker files +as well as TRAMP access to running docker containers. + +It also includes basic Docker container and image management provided by +[[https://github.com/Silex/docker.el][docker.el.]] + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =docker= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Usage +** TRAMP access to docker containers +This relies on the [[https://github.com/emacs-pe/docker-tramp.el][docker-tramp]] package which uses ~docker exec~ available in +docker versions > 1.3. + +=docker-tramp= adds a new prefix =/docker:= that you can use with ~SPC f f~, +this prefix allows to acces your docker containers and also provides +auto-completion of the running containers. + +* Key bindings + +| Key Binding | Description | +|-------------+----------------------------------------------------| +| ~SPC m c b~ | build current buffer via =dockerfile-build-buffer= | +| ~SPC D c~ | list docker containers | +| ~SPC D d~ | delete image | +| ~SPC D e~ | unpause container | +| ~SPC D F~ | pull image | +| ~SPC D i~ | list docker images | +| ~SPC D k~ | delete container | +| ~SPC D o~ | stop container | +| ~SPC D p~ | pause container | +| ~SPC D P~ | push image | +| ~SPC D r~ | restart container | +| ~SPC D s~ | start container | diff --git a/layers/+tools/docker/img/docker.png b/layers/+tools/docker/img/docker.png new file mode 100644 index 0000000..d9f5f78 Binary files /dev/null and b/layers/+tools/docker/img/docker.png differ diff --git a/layers/+tools/docker/packages.el b/layers/+tools/docker/packages.el new file mode 100644 index 0000000..1592564 --- /dev/null +++ b/layers/+tools/docker/packages.el @@ -0,0 +1,53 @@ +;;; packages.el --- docker Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2015 Sylvain Benner +;; Copyright (c) 2015 Alan Zimmerman & Contributors +;; +;; Author: Alan Zimmerman +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defconst docker-packages + '( + docker + docker-tramp + dockerfile-mode + )) + +(defun docker/init-docker () + (use-package docker + :defer t + :init + (progn + (spacemacs/declare-prefix "D" "Docker") + (evil-leader/set-key + "Dc" 'docker-containers + "Dd" 'docker-rmi + "De" 'docker-unpause + "DF" 'docker-pull + "Dk" 'docker-rm + "Di" 'docker-images + "Do" 'docker-stop + "DP" 'docker-push + "Dp" 'docker-pause + "Dr" 'docker-restart + "Ds" 'docker-start))) + (with-eval-after-load 'docker-containers + (evilified-state-evilify-map docker-containers-mode-map + :mode docker-containers-mode)) + (with-eval-after-load 'docker-images + (evilified-state-evilify-map docker-images-mode-map + :mode docker-images-mode))) + +(defun docker/init-docker-tramp () + (use-package docker-tramp + :defer t)) + +(defun docker/init-dockerfile-mode () + (use-package docker-mode + :defer t + :config (evil-leader/set-key-for-mode 'dockerfile-mode + "mcb" 'dockerfile-build-buffer))) diff --git a/layers/+tools/fasd/README.org b/layers/+tools/fasd/README.org new file mode 100644 index 0000000..25a742f --- /dev/null +++ b/layers/+tools/fasd/README.org @@ -0,0 +1,39 @@ +#+TITLE: fasd layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#fasd][fasd]] + - [[#keybindings][Keybindings]] + +* Description + +This layer adds integration of [[https://github.com/clvv/fasd][fasd]] which is a command line tool +to quickly jump between locations in a POSIX shell. + +The integration is implemented in the package [[https://github.com/steckerhalter/emacs-fasd][emacs-fasd]]. + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =fasd= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** fasd +[[https://github.com/clvv/fasd][fasd]] must be installed on your system. The general installation +instructions can be found in the repository [[https://github.com/clvv/fasd#install][README]] + +On OS X, it can be installed via [[https://github.com/Homebrew/homebrew][homebrew]]: + +#+BEGIN_SRC sh + $ brew install fasd +#+END_SRC + +* Keybindings + +| Key Binding | Description | +|-------------+------------------------------------| +| ~SPC f a s~ | find a file or directory with fasd | +| ~SPC f a d~ | find a directory with fasd | +| ~SPC f a f~ | find a file with fasd | diff --git a/layers/+tools/fasd/packages.el b/layers/+tools/fasd/packages.el new file mode 100644 index 0000000..8065fed --- /dev/null +++ b/layers/+tools/fasd/packages.el @@ -0,0 +1,29 @@ +(setq fasd-packages + '( + fasd + )) + +(defun fasd-find-file-only () + (interactive) + (fasd-find-file -1)) + +(defun fasd-find-directory-only () + (interactive) + (fasd-find-file 1)) + +(defun fasd/init-fasd () + "initializes fasd-emacs and adds a key binding to `SPC f z'" + (use-package fasd + :init + (progn + (global-fasd-mode 1) + (spacemacs/declare-prefix "fa" "fasd-find") + (spacemacs/set-leader-keys "fad" 'fasd-find-directory-only) + (spacemacs/set-leader-keys "faf" 'fasd-find-file-only) + (spacemacs/set-leader-keys "fas" 'fasd-find-file) + + ;; we will fall back to using the default completing-read function, which is helm once helm is loaded. + (setq fasd-completing-read-function 'nil) + ) + ) + ) diff --git a/layers/+tools/finance/README.org b/layers/+tools/finance/README.org new file mode 100644 index 0000000..20a1043 --- /dev/null +++ b/layers/+tools/finance/README.org @@ -0,0 +1,55 @@ +#+TITLE: Finance layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#configuration][Configuration]] + - [[#ledger][Ledger]] + - [[#key-bindings][Key bindings]] + - [[#ledger][Ledger]] + +* Description + +This layer adds finance related packages: +- [[https://github.com/ledger/ledger][ledger]] support via [[https://github.com/ledger/ledger/tree/next/lisp][ledger-mode]] + +[[file:img/ledger.png]] + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =finance= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Configuration + +** Ledger + +You can set what column transaction posts are aligned to on +the right by setting the variable =ledger-post-amount-alignment-column= in +your =dotspacemacs/user-config=. The default value, set in the layer, is =62=. + +#+BEGIN_SRC emacs-lisp + (defun dotspacemacs/user-config () + (setq ledger-post-amount-alignment-column 68)) +#+END_SRC + +* Key bindings + +** Ledger + +| Key Binding | Description | +|-------------+-----------------------------------------------| +| ~SPC m a~ | add a transaction | +| ~SPC m b~ | edit a post amount with Emacs Calculator mode | +| ~SPC m c~ | toggle 'cleared' flag on transaction or post | +| ~SPC m C~ | sort and align the entire buffer | +| ~SPC m d~ | delete current transaction | +| ~SPC m p~ | display balance at point | +| ~SPC m q~ | align a single transaction's posts | +| ~SPC m r~ | reconcile an account | +| ~SPC m R~ | display a report | +| ~SPC m t~ | append an effective date to a post | +| ~SPC m y~ | set the year for quicker entry | +| ~SPC m RET~ | set the month for quicker entry | diff --git a/layers/+tools/finance/config.el b/layers/+tools/finance/config.el new file mode 100644 index 0000000..f64dcdf --- /dev/null +++ b/layers/+tools/finance/config.el @@ -0,0 +1,14 @@ +;;; config.el --- Finance Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(spacemacs|defvar-company-backends ledger-mode) diff --git a/layers/+tools/finance/img/ledger.png b/layers/+tools/finance/img/ledger.png new file mode 100644 index 0000000..3a68a8f Binary files /dev/null and b/layers/+tools/finance/img/ledger.png differ diff --git a/layers/+tools/finance/packages.el b/layers/+tools/finance/packages.el new file mode 100644 index 0000000..53876a2 --- /dev/null +++ b/layers/+tools/finance/packages.el @@ -0,0 +1,53 @@ +;;; packages.el --- Finance Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq finance-packages + '( + company + (flycheck-ledger :toggle (configuration-layer/package-usedp 'flycheck)) + ledger-mode + )) + + +(defun finance/init-flycheck-ledger () + (with-eval-after-load 'flycheck + (require 'flycheck-ledger))) + +(defun finance/init-ledger-mode () + (use-package ledger-mode + :mode ("\\.\\(ledger\\|ldg\\)\\'" . ledger-mode) + :defer t + :init + (progn + (setq ledger-post-amount-alignment-column 62) + (push 'company-capf company-backends-ledger-mode) + (spacemacs/set-leader-keys-for-major-mode 'ledger-mode + "hd" 'ledger-delete-current-transaction + "a" 'ledger-add-transaction + "b" 'ledger-post-edit-amount + "c" 'ledger-toggle-current + "C" 'ledger-mode-clean-buffer + "l" 'ledger-display-ledger-stats + "p" 'ledger-display-balance-at-point + "q" 'ledger-post-align-xact + "r" 'ledger-reconcile + "R" 'ledger-report + "t" 'ledger-insert-effective-date + "y" 'ledger-set-year + "RET" 'ledger-set-month) + ;; temporary hack to work-around an issue with evil-define-key + ;; more info: https://bitbucket.org/lyro/evil/issues/301/evil-define-key-for-minor-mode-does-not + ;; TODO remove this hack if the limitation is removed upstream + (add-hook 'ledger-mode-hook 'evil-normalize-keymaps) + (evilified-state-evilify ledger-report-mode ledger-report-mode-map)))) + +(defun finance/post-init-company () + (spacemacs|add-company-hook ledger-mode)) diff --git a/layers/+tools/geolocation/README.org b/layers/+tools/geolocation/README.org new file mode 100644 index 0000000..a14d213 --- /dev/null +++ b/layers/+tools/geolocation/README.org @@ -0,0 +1,119 @@ +#+TITLE: Geolocation layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#supported-packages-in-this-layer][Supported packages in this layer]] + - [[#install][Install]] + - [[#configuration][Configuration]] + - [[#location][Location]] + - [[#theme-changer][theme-changer]] + - [[#sunshine-weather-forecast][sunshine (weather forecast)]] + - [[#osx-location][osx-location]] + - [[#key-bindings][Key Bindings]] + - [[#weather][Weather]] + +* Description +This layer offers few location sensitive adjustment to Emacs, such as +automatically switching between light (day) and dark (night) themes, weather +forecast and on OS X, also automatic tracking of location, using OS X's +CoreLocation services. + +** Supported packages in this layer +- [[https://github.com/aaronbieber/sunshine.el/blob/master/sunshine.el][sunshine]] +- [[https://github.com/purcell/osx-location][osx-location]] + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =geolocation= to the existing =dotspacemacs-configuration-layers= list in this +file. + +All services are disable by default. To enable all, or some of them, add instead +something like this: + +#+BEGIN_SRC emacs-lisp + (geolocation :variables + geolocation-enable-automatic-theme-changer t + geolocation-enable-location-service t + geolocation-enable-weather-forecast t) +#+END_SRC + +* Configuration +** Location +Set location manually by setting the following variables to the +=dotspacemacs/user-config= function of your dotfile: + +#+BEGIN_SRC emacs-lisp + (setq calendar-location-name "Barcelona, Spain" + calendar-latitude 41.23 + calendar-longitude 1.80) +#+END_SRC + +On OS X, all of these variables get setup automatically if the ~osx-location~ +service was enabled (Wifi must be turned on to make it work). In this case, if +~calendar-location-name~ was omitted, it'll be stringed-up ~calendar-latitude~ +and ~calendar-longitude~ i.e. "41.23, 1.80". + +** theme-changer +This layer implement a simple "theme changer" which, when enabled, will switch +between first two themes the user has setup in ~dotspacemacs-themes~. First +theme listed will be used as light variant, while the second as the the dark. +Other themes will be ignored by this layer, though they are still available for +cycling, etc. + +** sunshine (weather forecast) +Sunshine display local weather forecast. + +Setup [[http://home.openweathermap.org/][OpenWeatherMap]] API key. +Set ~sunshine-appid~ to some hash string from the openweathermap +website. You need to sign up to the website to get a API key. + +#+BEGIN_SRC emacs-lisp + (setq sunshine-appid "your-apikey") +#+END_SRC + +Configure your location by setting the variable sunshine-location. You +can provide a string, like "New York, NY" or a ZIP code, like "90210". +This variable is available through the Customize facility. + When specifying a ZIP code, you may receive results from a foreign +country. This is due to weird behavior from OpenWeatherMap. To resolve +this, append a comma and the country code after the ZIP code. Note the +lack of a space in the example below. + +#+BEGIN_SRC emacs-lisp +(setq sunshine-location "90210,USA") +#+END_SRC + +It will use the imperial unit system by default. To switch to metric, add +~sunshine-units 'metric~ to the variables list for this layer, or add this. + +#+BEGIN_SRC emacs-lisp + (setq sunshine-units 'metric) +#+END_SRC + +Weather forecast icons are disabled by default, and can be toggled by pressing +`i' within this mode's main buffer. + +To display weather forecast icons by default ("pretty mode"), add +~sunshine-show-icons t~ to the variables list for this layer, or add this: + +#+BEGIN_SRC emacs-lisp + (setq sunshine-show-icons t) +#+END_SRC + +[[file:img/emacs-sunshine.jpg]] + +** osx-location +OS X users can take adavantage of automatic geogrphical discovery using the OS' +CoreLocation system service, implemented as a long running background process. A +helper script will need to be given proper access first time this layer is +activated. + +[[file:img/emacs-location-helper.jpg]] + +* Key Bindings +** Weather + +| Evil | Holy | Command | +|-----------+------+-----------------------------------------------| +| ~SPC a w~ | | Display pretty weather forecast | +| ~SPC a W~ | | Display quick weather forecast in mini buffer | diff --git a/layers/+tools/geolocation/config.el b/layers/+tools/geolocation/config.el new file mode 100644 index 0000000..a5bd9c4 --- /dev/null +++ b/layers/+tools/geolocation/config.el @@ -0,0 +1,20 @@ +;;; config.el --- geolocation configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar geolocation-enable-automatic-theme-changer nil + "If non nil enable the automatic change of theme based on the current time.") + +(defvar geolocation-enable-location-service nil + "If non nil enable the OS X location service support.") + +(defvar geolocation-enable-weather-forecast nil + "If non nil enable the weather forecast service.") + diff --git a/layers/+tools/geolocation/extensions.el b/layers/+tools/geolocation/extensions.el new file mode 100644 index 0000000..924e9d6 --- /dev/null +++ b/layers/+tools/geolocation/extensions.el @@ -0,0 +1,19 @@ +;;; extensions.el --- geolocation configuration File for Spacemacs +;; +;; Copyright (c) 2012-2014 Sylvain Benner +;; Copyright (c) 2014-2015 Uri Sharf & Contributors +;; +;; Author: Uri Sharf +;; URL: https://github.com/usharf/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq geolocation-post-extensions '(theme-changer)) + +(defun geolocation/init-theme-changer () + "Initialize theme-changer" + (use-package theme-changer + :if (and geolocation-enable-automatic-theme-changer + (> (length dotspacemacs-themes) 1)))) diff --git a/layers/+tools/geolocation/extensions/theme-changer/theme-changer.el b/layers/+tools/geolocation/extensions/theme-changer/theme-changer.el new file mode 100644 index 0000000..2cf4a73 --- /dev/null +++ b/layers/+tools/geolocation/extensions/theme-changer/theme-changer.el @@ -0,0 +1,33 @@ +;;; theme-changer.el --- geolocation configuration File for Spacemacs +;; +;; Copyright (c) 2012-2014 Sylvain Benner +;; Copyright (c) 2014-2015 Uri Sharf & Contributors +;; +;; Author: Uri Sharf +;; URL: https://github.com/usharf/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(require 'rase) + +(defun theme-changer/switch-themes (sun-event &optional first-run) + "Switch first two themes in dotspacemacs-themes on sunrise and sunset." + (if first-run ; set theme on initialization + (cond ((memq sun-event '(sunrise midday)) + (load-theme (nth 0 dotspacemacs-themes) t)) + ((memq sun-event '(sunset midnight)) + (load-theme (nth 1 dotspacemacs-themes) t))) + (cond ((eq sun-event 'sunrise) ; after initialization deal only with + ; sunrise and sunset + (load-theme (nth 0 dotspacemacs-themes) t)) + ((eq sun-event 'sunset) + (load-theme (nth 1 dotspacemacs-themes) t)))) + ) + +(with-eval-after-load 'rase ; probably redaundant because it's a post extension + (add-hook 'rase-functions 'theme-changer/switch-themes) + (rase-start t)) + +(provide 'theme-changer) diff --git a/layers/+tools/geolocation/img/emacs-location-helper.jpg b/layers/+tools/geolocation/img/emacs-location-helper.jpg new file mode 100644 index 0000000..a755bbc Binary files /dev/null and b/layers/+tools/geolocation/img/emacs-location-helper.jpg differ diff --git a/layers/+tools/geolocation/img/emacs-sunshine.jpg b/layers/+tools/geolocation/img/emacs-sunshine.jpg new file mode 100644 index 0000000..b74ea7e Binary files /dev/null and b/layers/+tools/geolocation/img/emacs-sunshine.jpg differ diff --git a/layers/+tools/geolocation/packages.el b/layers/+tools/geolocation/packages.el new file mode 100644 index 0000000..4135f76 --- /dev/null +++ b/layers/+tools/geolocation/packages.el @@ -0,0 +1,117 @@ +;;; packages.el --- geolocation configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Uri Sharf +;; URL: https://github.com/usharf/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq geolocation-packages + '( + osx-location + popwin + rase + sunshine + theme-changer + )) + +(defun geolocation/init-osx-location () + "Initialize osx-location" + (use-package osx-location + :if geolocation-enable-location-service + :defer t + :init + (progn + (when (spacemacs/system-is-mac) + (add-hook 'osx-location-changed-hook + (lambda () + (let ((location-changed-p nil) + (_longitude (/ (truncate (* osx-location-longitude 10)) 10.0)) ; one decimal point, no rounding + (_latitdue (/ (truncate (* osx-location-latitude 10)) 10.0))) + (unless (equal (bound-and-true-p calendar-longitude) _longitude) + (setq calendar-longitude _longitude + location-changed-p t)) + (unless (equal (bound-and-true-p calendar-latitude) _latitdue) + (setq calendar-latitude _latitdue + location-changed-p t)) + (when (and (configuration-layer/layer-usedp 'geolocation) location-changed-p) + (message "Location changed %s %s (restarting rase-timer)" calendar-latitude calendar-longitude) + (rase-start t) + )))) + (osx-location-watch))))) + +(defun geolocation/init-rase () + (use-package rase + :defer t + :init + (progn + (add-hook 'osx-location-changed-hook + (lambda () + (setq calendar-latitude osx-location-latitude + calendar-longitude osx-location-longitude) + (unless (bound-and-true-p calendar-location-name) + (setq calendar-location-name + (format "%s, %s" + osx-location-latitude + osx-location-longitude))))) + (osx-location-watch) + (defadvice rase-start (around test-calendar activate) + "Don't call `raise-start' if `calendar-latitude' or +`calendar-longitude' are not bound yet, or still nil. + +This is setup this way because `rase.el' does not test these +values, and will fail under such conditions, when calling +`solar.el' functions. + +Also, it allows users who enabled service such as `osx-location' +to not have to set these variables manually when enabling this layer." + (if (and (bound-and-true-p calendar-longitude) + (bound-and-true-p calendar-latitude)) + ad-do-it)) + (rase-start t) + ))) + +(defun geolocation/init-sunshine () + "Initialize sunshine" + (use-package sunshine + :if geolocation-enable-weather-forecast + :commands (sunshine-forecast sunshine-quick-forecast) + :init + (progn + (spacemacs/set-leader-keys + "aw" 'sunshine-forecast + "aW" 'sunshine-quick-forecast)) + :config + (progn + (evilified-state-evilify-map sunshine-mode-map + :mode sunshine-mode + :bindings + (kbd "q") 'quit-window + (kbd "i") 'sunshine-toggle-icons) + + ;; just in case location was not set by user, or on OS X, + ;; if wasn't set up automatically, will not work with Emac's + ;; default for ;; `calendar-location-name' + (when (not (boundp 'sunshine-location)) + (setq sunshine-location (format "%s, %s" + calendar-latitude + calendar-longitude))) + ))) + +(defun geolocation/init-theme-changer () + "Initialize theme-changer" + (use-package theme-changer + :if geolocation-enable-automatic-theme-changer + :config + (progn + (when (> (length dotspacemacs-themes) 1) + (change-theme (nth 0 dotspacemacs-themes) + (nth 1 dotspacemacs-themes)))))) + +(defun geolocation/post-init-popwin () + ;; Pin the weather forecast to the bottom window + (push '("*Sunshine*" :dedicated t :position bottom) + popwin:special-display-config)) diff --git a/layers/+tools/imenu-list/README.org b/layers/+tools/imenu-list/README.org new file mode 100644 index 0000000..20820f2 --- /dev/null +++ b/layers/+tools/imenu-list/README.org @@ -0,0 +1,40 @@ +#+TITLE: imenu-list layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#screenshot][Screenshot]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + - [[#from-any-buffer][From any buffer]] + - [[#from-imenu-list-buffer][From imenu-list buffer]] + +* Description +This layer uses [[https://github.com/bmag/imenu-list][imenu-list]] to show the current buffer's index in a side bar. + +This is similar to `SPC j i` but displayed in a persistent sidebar instead of +a completion buffer. + +* Screenshot + +[[file:img/imenu-list-example.png]] + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =imenu-list= to the existing =dotspacemacs-configuration-layers= list in +this file. + +* Key bindings +** From any buffer + +| Key Binding | Description | +|-------------+--------------------------| +| ~SPC b i~ | toggle imenu-list window | + +** From imenu-list buffer + +| Key Binding | Description | +|-------------+--------------------------------------------------------| +| ~q~ | quit imenu-list window | +| ~RET~ | go to current entry | +| ~d~ | display current entry, keep focus on imenu-list window | +| ~f~ | fold/unfold current section | diff --git a/layers/+tools/imenu-list/img/imenu-list-example.png b/layers/+tools/imenu-list/img/imenu-list-example.png new file mode 100644 index 0000000..5b310df Binary files /dev/null and b/layers/+tools/imenu-list/img/imenu-list-example.png differ diff --git a/layers/+tools/imenu-list/packages.el b/layers/+tools/imenu-list/packages.el new file mode 100644 index 0000000..53ebf3e --- /dev/null +++ b/layers/+tools/imenu-list/packages.el @@ -0,0 +1,36 @@ +;;; packages.el --- imenu-list Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defconst imenu-list-packages + '( + golden-ratio + imenu-list + )) + +(defun imenu-list/pre-init-golden-ratio () + (spacemacs|use-package-add-hook golden-ratio + :post-config + (add-to-list 'golden-ratio-exclude-buffer-regexp "^\\*Ilist\\*"))) + +(defun imenu-list/init-imenu-list () + (use-package imenu-list + :defer t + :init + (progn + (setq imenu-list-focus-after-activation t + imenu-list-auto-resize t) + (spacemacs/set-leader-keys "bi" #'imenu-list-minor-mode)) + :config + (evilified-state-evilify-map imenu-list-major-mode-map + :mode imenu-list-major-mode + :bindings + "d" #'imenu-list-display-entry + "q" #'imenu-list-minor-mode))) diff --git a/layers/+tools/nginx/README.org b/layers/+tools/nginx/README.org new file mode 100644 index 0000000..a736052 --- /dev/null +++ b/layers/+tools/nginx/README.org @@ -0,0 +1,16 @@ +#+TITLE: nginx layer + +[[file:img/nginx.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + +* Description +[[https://github.com/ajc/nginx-mode][nginx-mode]] for editing [[http://nginx.org][nginx]] configuration files. +It adds basic syntax highlighting and syntax-aware tabbing. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =nginx= to the existing =dotspacemacs-configuration-layers= list in this +file. diff --git a/layers/+tools/nginx/img/nginx.png b/layers/+tools/nginx/img/nginx.png new file mode 100644 index 0000000..6711c52 Binary files /dev/null and b/layers/+tools/nginx/img/nginx.png differ diff --git a/layers/+tools/nginx/packages.el b/layers/+tools/nginx/packages.el new file mode 100644 index 0000000..8e43d5f --- /dev/null +++ b/layers/+tools/nginx/packages.el @@ -0,0 +1,15 @@ +;;; packages.el --- nginx layer packages file for Spacemacs. +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Nathaniel Waisbrot +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defconst nginx-packages '(nginx-mode)) + +(defun nginx/init-nginx-mode () + (use-package nginx-mode :defer t)) diff --git a/layers/+tools/pandoc/README.org b/layers/+tools/pandoc/README.org new file mode 100644 index 0000000..a1d14f2 --- /dev/null +++ b/layers/+tools/pandoc/README.org @@ -0,0 +1,39 @@ +#+TITLE: Pandoc layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#pandoc][Pandoc]] + - [[#usage][Usage]] + - [[#key-bindings][Key Bindings]] + +* Description + +This layer adds support for [[http://johnmacfarlane.net/pandoc][Pandoc]]. + +Pandoc is a universal document converter. It makes it easy to e.g. convert a +Markdown file to org mode or vice versa. It can also export your text to PDF or +DOCX. + +This layer automatically install an org exporter using the [[https://github.com/kawabata/ox-pandoc][ox-pandoc]]. + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =pandoc= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Pandoc +To use the mode please [[http://pandoc.org/installing.html][install]] pandoc first. + +* Usage +For a full list of possible conversions see the [[http://johnmacfarlane.net/pandoc][Pandoc documentation]]. +An explanation of all the options offered by =pandoc-mode= can be found at the +[[http://joostkremers.github.io/pandoc-mode][Pandoc-mode website]]. + +* Key Bindings + +| Key Binding | Description | +|-------------+---------------------------------| +| ~SPC P /~ | Start pandoc-mode and open menu | diff --git a/layers/+tools/pandoc/funcs.el b/layers/+tools/pandoc/funcs.el new file mode 100644 index 0000000..13c27b1 --- /dev/null +++ b/layers/+tools/pandoc/funcs.el @@ -0,0 +1,16 @@ +;;; packages.el --- pandoc Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Christoph Paulik +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spacemacs/run-pandoc () + "Start pandoc for the buffer and open the menu" + (interactive) + (pandoc-mode) + (pandoc-main-hydra/body)) diff --git a/layers/+tools/pandoc/packages.el b/layers/+tools/pandoc/packages.el new file mode 100644 index 0000000..f85ca37 --- /dev/null +++ b/layers/+tools/pandoc/packages.el @@ -0,0 +1,33 @@ +;;; packages.el --- pandoc Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Christoph Paulik +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq pandoc-packages + '(pandoc-mode + ox-pandoc + )) + +(defun pandoc/init-pandoc-mode () + "Initialize my package" + (use-package pandoc-mode + :defer t + :commands spacemacs/run-pandoc + :config + (progn + (setq pandoc-data-dir (concat spacemacs-cache-directory "pandoc/")) + (add-hook 'pandoc-mode-hook 'pandoc-load-default-settings)) + :init + (spacemacs/set-leader-keys "P/" 'spacemacs/run-pandoc))) + +(defun pandoc/init-ox-pandoc () + (use-package ox-pandoc + :defer t + :init + (with-eval-after-load 'org (require 'ox-pandoc)))) diff --git a/layers/+tools/pdf-tools/README.org b/layers/+tools/pdf-tools/README.org new file mode 100644 index 0000000..1b288e8 --- /dev/null +++ b/layers/+tools/pdf-tools/README.org @@ -0,0 +1,207 @@ +#+TITLE: pdf-tools layer + +[[file:img/pdf.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#prerequisites][Prerequisites]] + - [[#dotfile][Dotfile]] + - [[#usage][Usage]] + - [[#known-issues][Known Issues]] + - [[#key-bindings][Key bindings]] + - [[#pdf-view][PDF View]] + - [[#leader-keys][Leader keys]] + - [[#outline-buffer-mode][Outline buffer mode]] + - [[#annotation-list-mode][Annotation list mode]] + - [[#occur-mode][Occur mode]] + +* Description +This layer enables support for the [[https://github.com/politza/pdf-tools][pdf-tools]] package. + +According to the official repository: + +#+begin_quote +"PDF Tools is, among other things, a replacement of DocView for PDF files. The +key difference is, that pages are not pre-rendered by e.g. ghostscript and +stored in the file-system, but rather created on-demand and stored in memory." +#+end_quote + +Examples of features that =pdf-tools= provides: +- Use =occur= in the pdf file; +- Show all headings in a outline buffer; +- Manipulate annotations. + +* Install +** Prerequisites +Linux is the only operating system officially supported, but it's possible to +use =pdf-tools= on OS X as well, and possibly on other Unix flavors. + +You'll need to install a few libraries. Check the [[https://github.com/politza/pdf-tools#server-prerequisites][instructions]] on +=pdf-tools= page. Note that compiling from source might not be necessary, as +the documentation states. + +If you use a Debian based system such as Ubuntu, you can skip this step, as +=pdf-tools= installation asks whether you want it to try to download +automatically all dependencies using ~apt-get~. + +** Dotfile +After installing the dependencies, add this to your =~/.spacemacs=. + +#+begin_src emacs-lisp + (setq-default dotspacemacs-configuration-layers '(pdf-tools)) +#+end_src + +After that, syncronize your configuration with ~SPC f e R~. This will pop up a +window showing the compilation process. + +If everything goes right, the compilation won't display any error and you will +be able to see /PDFView/ (instead of /DocView/) on the spaceline after opening a +pdf file. + +If the compilation run successfully but you get +~Error (use-package): pdf-tools :config: No executable `epdfinfo' found~, +try restarting Spacemacs ([[https://github.com/politza/pdf-tools/issues/31][issue]]). + +If the compilation does not run successfully, you should confirm whether all +dependencies are properly installed and run the command ~pdf-tools-install~. + +* Usage +Use ~SPC m .~ to activate the pdf-tools transient state. +The keybindings that the transient displays can be also accessed using ~SPC m~. The +navigation keybindings can be used directly. + +Try out opening the outline (~O~). The outline window shows the structure of the +pdf, displaying all headings. + +You can set annotations by selecting regions and right clicking on the buffer. +Additionally, all annotation related functions can be accessed with ~SPC m a~. + +Searching with =occur= can be done by using =pdf-occur= (~SPC m s s~). + +Tips: +- You'll probably want to use =pdf-view-set-slice-from-bounding-box= (bound to + ~SPC m s b~) This command trims the blank parts of the + lateral margins, making the useful portion larger. +- The last visited page is not saved across Emacs sessions. If you want save it, + use the bookmarks commands on ~SPC j b~ to save and go to a bookmark. + +* Known Issues +Due to =image-mode='s behaviour, the =pdf-tools= buffer might go back to the +first page after switching windows. If this happens, you can quickly go back to +the previous page in history with =pdf-history-backward= (~``~ in Evil state and +~B~ in Emacs state.) + +* Key bindings +If you use Emacs editing style, check the key bindings at the [[https://github.com/politza/pdf-tools#some-keybindings][pdf-tools page]]. + +** PDF View + +| *Key Binding* | *Description* | +|----------------------+-------------------------------------------| +| *Navigation* | | +|----------------------+-------------------------------------------| +| ~M-SPC~ or ~s-M-SPC~ | pdf-tools transient state | +| ~0/$~ | Left/right full scroll | +| ~J~ | Move to next page | +| ~K~ | Move to previous page | +| ~u~ | Scroll page up | +| ~d~ | Scroll page down | +| ~gg~ | Go to the first page | +| ~G~ | Go to the last page | +| ~gt~ | Go to page | +| ~gl~ | Go to label (usually the line as printed) | +| ~C-u~ | Scroll up | +| ~C-d~ | Scroll down | +| ~``~ | Go to last page in the history | +| ~m~ | Set mark | +| ~'~ | Go to mark | +| ~y~ | Yank selected region | +|----------------------+-------------------------------------------| +| *Search* | | +|----------------------+-------------------------------------------| +| ~/~ | Search forward | +| ~?~ | Search backward | +|----------------------+-------------------------------------------| +| *Actions* | | +|----------------------+-------------------------------------------| +| ~o~ | Follow link | +| ~O~ | Show outline | +| ~r~ | Refresh file | +|----------------------+-------------------------------------------| +| *Zoom* | | +|----------------------+-------------------------------------------| +| ~+/-~ | Zoom in/out | +| ~zr~ | Reset zoom | +|----------------------+-------------------------------------------| + +/For evil users/: Note that the search keys activate =isearch=, which works +differently from the default Evil search. To go to the next match, use ~C-s~. + +** Leader keys + +| *Key Binding* | *Description* | +|-----------------------+-------------------------------------------| +| *Slicing* | | +|-----------------------+-------------------------------------------| +| ~SPC m s m~ | Set slice using mouse | +| ~SPC m s b~ | Set slice from bounding box | +| ~SPC m s r~ | Reset slice | +|-----------------------+-------------------------------------------| +| *Annotations* | | +|-----------------------+-------------------------------------------| +| ~SPC m a D~ | Delete annotation (select it with mouse) | +| ~SPC m a a~ | List all attachments in a dired buffer | +| ~SPC m a h~ | Highlight visual selection | +| ~SPC m a l~ | List all annotations | +| ~SPC m a m~ | Add markup annotation to visual selection | +| ~SPC m a o~ | Strikeout visual selection | +| ~SPC m a s~ | Add squiggly to visual selection | +| ~SPC m a t~ | Add annotation text | +| ~SPC m a u~ | Underline to visual selection | +|-----------------------+-------------------------------------------| +| *Fit image to window* | | +|-----------------------+-------------------------------------------| +| ~SPC m f w~ | Fit width to window | +| ~SPC m f h~ | Fit height to window | +| ~SPC m f p~ | Fit page to window | +|-----------------------+-------------------------------------------| +| *Other* | | +|-----------------------+-------------------------------------------| +| ~SPC m n~ | Toggle night view mode | +| ~SPC m s~ | Run =pdf-occur= | +| ~SPC m p~ | Display print version | + +** Outline buffer mode + +| *Key Binding* | *Description* | +|---------------+-------------------------------------------------------| +| ~S-tab~ | Expand all trees | +| ~RET~ | Follow link | +| ~M-RET~ | Follow link and close outline window | +| ~o~ | Go to pdf view window | +| ~``~ | Move to the heading correspondent to the current page | +| ~''~ | Move to the heading correspondent to the current page | +| ~f~ | Go to selected heading without leaving outline buffer | +| ~F~ | Enable follow mode | +| ~q~ | Quit | +| ~Q~ | Quit and kill outline buffer | + +Note that you can use also typical Vim keys such as ~j~ and ~G~. + +** Annotation list mode + +| Key Binding | Description | +|-------------+-------------------------------| +| ~d~ | Mark for deletion | +| ~x~ | Apply action for marked items | +| ~u~ | Unmark item | +| ~q~ | Quit | + +** Occur mode + +| Key Binding | Description | +|-------------+----------------| +| ~q~ | Quit | +| ~g~ | Refresh buffer | +| ~r~ | Refresh buffer | diff --git a/layers/+tools/pdf-tools/img/pdf.png b/layers/+tools/pdf-tools/img/pdf.png new file mode 100644 index 0000000..38e3c4b Binary files /dev/null and b/layers/+tools/pdf-tools/img/pdf.png differ diff --git a/layers/+tools/pdf-tools/packages.el b/layers/+tools/pdf-tools/packages.el new file mode 100644 index 0000000..7fc5235 --- /dev/null +++ b/layers/+tools/pdf-tools/packages.el @@ -0,0 +1,166 @@ +;;; packages.el --- pdf-tools Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2014 Sylvain Benner +;; Copyright (c) 2014-2016 Sylvain Benner & Contributors +;; +;; Author: André Peric Tavares +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq pdf-tools-packages '(pdf-tools)) + +(defun pdf-tools/init-pdf-tools () + (use-package pdf-tools + :defer t + :mode (("\\.pdf\\'" . pdf-view-mode)) + :config + (progn + (pdf-tools-install) + + (spacemacs|define-transient-state pdf-tools + :title "PDF-tools transient state" + :on-enter (setq which-key-inhibit t) + :on-exit (setq which-key-inhibit nil) + :evil-leader-for-mode (pdf-view-mode . ".") + :doc + " + Navigation^^^^ Scale/Fit^^ Annotations^^ Actions^^ Other^^ + ----------^^^^--------------- ---------^^------------------ -----------^^------ -------^^---------- -----^^--- + [_j_/_k_] scroll down/up [_W_] fit to width [_al_] list [_s_] search [_q_] quit + [_h_/_l_] scroll left/right [_H_] fit to height [_at_] text [_O_] outline + [_d_/_u_] pg down/up [_P_] fit to page [_aD_] delete [_p_] print + [_J_/_K_] next/prev pg [_m_] slice using mouse [_am_] markup [_o_] open link + [_0_/_$_] full scroll l/r [_b_] slice from bounding box ^^ [_r_] revert + ^^^^ [_R_] reset slice ^^ [_t_] attachments + ^^^^ [_zr_] reset zoom ^^ [_n_] night mode + " + :bindings + ;; Navigation + ("j" pdf-view-next-line-or-next-page) + ("k" pdf-view-previous-line-or-previous-page) + ("l" image-forward-hscroll) + ("h" image-backward-hscroll) + ("J" pdf-view-next-page) + ("K" pdf-view-previous-page) + ("u" pdf-view-scroll-down-or-previous-page) + ("d" pdf-view-scroll-up-or-next-page) + ("0" image-bol) + ("$" image-eol) + ;; Scale/Fit + ("W" pdf-view-fit-width-to-window) + ("H" pdf-view-fit-height-to-window) + ("P" pdf-view-fit-page-to-window) + ("m" pdf-view-set-slice-using-mouse) + ("b" pdf-view-set-slice-from-bounding-box) + ("R" pdf-view-reset-slice) + ("zr" pdf-view-scale-reset) + ;; Annotations + ("aD" pdf-annot-delete) + ("at" pdf-annot-attachment-dired :exit t) + ("al" pdf-annot-list-annotations :exit t) + ("am" pdf-annot-add-markup-annotation) + ;; Actions + ("s" pdf-occur :exit t) + ("O" pdf-outline :exit t) + ("p" pdf-misc-print-document :exit t) + ("o" pdf-links-action-perform :exit t) + ("r" pdf-view-revert-buffer) + ("t" pdf-annot-attachment-dired :exit t) + ("n" pdf-view-midnight-minor-mode) + ;; Other + ("q" nil :exit t)) + + (spacemacs/declare-prefix-for-mode 'pdf-view-mode "ma" "annotations") + (spacemacs/declare-prefix-for-mode 'pdf-view-mode "mf" "fit") + (spacemacs/declare-prefix-for-mode 'pdf-view-mode "ms" "slice/search") + (spacemacs/set-leader-keys-for-major-mode 'pdf-view-mode + ;; Slicing image + "sm" 'pdf-view-set-slice-using-mouse + "sb" 'pdf-view-set-slice-from-bounding-box + "sr" 'pdf-view-reset-slice + ;; Annotations + "aD" 'pdf-annot-delete + "at" 'pdf-annot-attachment-dired + "ah" 'pdf-annot-add-highlight-markup-annotation + "al" 'pdf-annot-list-annotations + "am" 'pdf-annot-add-markup-annotation + "ao" 'pdf-annot-add-strikeout-markup-annotation + "as" 'pdf-annot-add-squiggly-markup-annotation + "at" 'pdf-annot-add-text-annotation + "au" 'pdf-annot-add-underline-markup-annotation + ;; Fit image to window + "fw" 'pdf-view-fit-width-to-window + "fh" 'pdf-view-fit-height-to-window + "fp" 'pdf-view-fit-page-to-window + ;; Other + "ss" 'pdf-occur + "p" 'pdf-misc-print-document + "O" 'pdf-outline + "n" 'pdf-view-midnight-minor-mode) + + (evil-define-key 'visual pdf-view-mode-map "y" 'pdf-view-kill-ring-save) + + ;; TODO: Make `/', `?' and `n' work like in Evil + (evilified-state-evilify pdf-view-mode pdf-view-mode-map + ;; Navigation + "0" 'image-bol + "$" 'image-eol + "j" 'pdf-view-next-line-or-next-page + "k" 'pdf-view-previous-line-or-previous-page + "l" 'image-forward-hscroll + "h" 'image-backward-hscroll + "J" 'pdf-view-next-page + "K" 'pdf-view-previous-page + "gg" 'pdf-view-first-page + "G" 'pdf-view-last-page + "gt" 'pdf-view-goto-page + "gl" 'pdf-view-goto-label + "u" 'pdf-view-scroll-down-or-previous-page + "d" 'pdf-view-scroll-up-or-next-page + (kbd "C-u") 'pdf-view-scroll-down-or-previous-page + (kbd "C-d") 'pdf-view-scroll-up-or-next-page + (kbd "``") 'pdf-history-backward + ;; Search + "/" 'isearch-forward + "?" 'isearch-backward + ;; Actions + "r" 'pdf-view-revert-buffer + "o" 'pdf-links-action-perform + "O" 'pdf-outline + "zr" 'pdf-view-scale-reset) + (evilified-state-evilify pdf-outline-buffer-mode pdf-outline-buffer-mode-map + "-" 'negative-argument + "j" 'next-line + "k" 'previous-line + "gk" 'outline-backward-same-level + "gj" 'outline-forward-same-level + (kbd "") 'show-all + "gh" 'pdf-outline-up-heading + "gg" 'beginning-of-buffer + "G" 'pdf-outline-end-of-buffer + "TAB" 'outline-toggle-children + "RET" 'pdf-outline-follow-link + (kbd "M-RET") 'pdf-outline-follow-link-and-quit + "f" 'pdf-outline-display-link + [mouse-1] 'pdf-outline-mouse-display-link + "o" 'pdf-outline-select-pdf-window + "``" 'pdf-outline-move-to-current-page + "''" 'pdf-outline-move-to-current-page + "Q" 'pdf-outline-quit-and-kill + "q" 'quit-window + "F" 'pdf-outline-follow-mode) + (evilified-state-evilify pdf-annot-list-mode pdf-annot-list-mode-map + "f" 'pdf-annot-list-display-annotation-from-id + "d" 'tablist-flag-forward + "x" 'tablist-do-flagged-delete + "u" 'tablist-unmark-forward + "q" 'tablist-quit) + (evilified-state-evilify pdf-occur-buffer-mode pdf-occur-buffer-mode-map + "q" 'tablist-quit + "g" 'pdf-occur-revert-buffer-with-args + "r" 'pdf-occur-revert-buffer-with-args + "*" 'spacemacs/enter-ahs-forward + "?" 'evil-search-backward)))) diff --git a/layers/+tools/prodigy/README.org b/layers/+tools/prodigy/README.org new file mode 100644 index 0000000..331b55e --- /dev/null +++ b/layers/+tools/prodigy/README.org @@ -0,0 +1,55 @@ +#+TITLE: Prodigy layer + +[[file:img/prodigy.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key Bindings]] + - [[#spawn-prodigy][Spawn prodigy]] + - [[#navigate-through-it][Navigate through it]] + +* Description + +This layer adds support for the [[https://github.com/rejeep/prodigy.el][prodigy]] package to manage external services from +within Emacs, check the package's documentation for more details. + +It is recommended to put your prodigy services in the =dotspacemacs/user-config= +part of your =~/.spacemacs= file. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =prodigy= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key Bindings + +** Spawn prodigy + +You start prodigy with this: + +| Key Binding | Description | +|-------------+-------------------------| +| ~SPC a S~ | Open the prodigy buffer | + +** Navigate through it + +| Key Binding | Description | +|-------------+---------------------------------| +| ~h~ | First service | +| ~j~ | Next service | +| ~k~ | Previous service | +| ~l~ | Last service | +| ~H~ | Display current process | +| ~J~ | Next service with status | +| ~K~ | Previous service with status | +| ~L~ | Start prodigy | +| ~S~ | Stop prodigy | +| ~r~ | restart prodigy | +| ~d~ | Jump to the dired of service | +| ~g~ | Jump to magit-status of service | +| ~Y~ | Copy prodigy command | +| ~o~ | Browse the service | +| ~f t~ | Add tag filter | +| ~f n~ | Add name filter | +| ~F~ | Clear filters | diff --git a/layers/+tools/prodigy/img/prodigy.png b/layers/+tools/prodigy/img/prodigy.png new file mode 100644 index 0000000..72436f8 Binary files /dev/null and b/layers/+tools/prodigy/img/prodigy.png differ diff --git a/layers/+tools/prodigy/packages.el b/layers/+tools/prodigy/packages.el new file mode 100644 index 0000000..369d794 --- /dev/null +++ b/layers/+tools/prodigy/packages.el @@ -0,0 +1,30 @@ +;;; packages.el --- Prodigy Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq prodigy-packages '(prodigy)) + +(defun prodigy/init-prodigy () + (use-package prodigy + :init + (spacemacs/set-leader-keys "aS" 'prodigy) + :config + (evilified-state-evilify prodigy-mode prodigy-mode-map + "h" 'prodigy-first + "j" 'prodigy-next + "k" 'prodigy-prev + "l" 'prodigy-last + "H" 'prodigy-display-process + "J" 'prodigy-next-with-status + "K" 'prodigy-prev-with-status + "L" 'prodigy-start + "d" 'prodigy-jump-dired + "g" 'prodigy-jump-magit + "Y" 'prodigy-copy-cmd))) diff --git a/layers/+tools/puppet/README.org b/layers/+tools/puppet/README.org new file mode 100644 index 0000000..5102858 --- /dev/null +++ b/layers/+tools/puppet/README.org @@ -0,0 +1,34 @@ +#+TITLE: Puppet layer + +[[file:img/puppet.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + +* Description +This layer aims at providing support for the Puppet DSL using [[https://github.com/lunaryorn/puppet-mode][puppet-mode]]. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =puppet= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key bindings +The following key bindings are available in Puppet Mode: + +| Key Binding | Description | +|-------------+---------------------------------------------------| +| ~SPC m {~ | Move to the beginning of the current block | +| ~SPC m }~ | Move to the end of the current block | +| ~SPC m a~ | Align parameters in the current block | +| ~SPC m '​~ | Toggle string quoting between single and double | +| ~SPC m ;~ | Blank the string at point | +| ~SPC m j~ | Jump to a =class=, =define=, variable or resource | +| ~SPC m c~ | Apply the current manifest in dry-run mode | +| ~SPC m v~ | Validate the syntax of the current manifest | +| ~SPC m l~ | Check the current manifest for semantic issues | +| ~SPC m $~ | Interpolate with ${} in double quoted strings | + +Use =M-x customize-group RET puppet= to customize Puppet Mode. diff --git a/layers/+tools/puppet/config.el b/layers/+tools/puppet/config.el new file mode 100644 index 0000000..a1aee55 --- /dev/null +++ b/layers/+tools/puppet/config.el @@ -0,0 +1,14 @@ +;;; config.el --- Puppet layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(spacemacs|defvar-company-backends puppet-mode) diff --git a/layers/+tools/puppet/img/puppet.png b/layers/+tools/puppet/img/puppet.png new file mode 100644 index 0000000..70cec7f Binary files /dev/null and b/layers/+tools/puppet/img/puppet.png differ diff --git a/layers/+tools/puppet/layers.el b/layers/+tools/puppet/layers.el new file mode 100644 index 0000000..e140753 --- /dev/null +++ b/layers/+tools/puppet/layers.el @@ -0,0 +1,12 @@ +;;; layers.el --- Puppet layer layers File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(configuration-layer/declare-layer 'ruby) diff --git a/layers/+tools/puppet/packages.el b/layers/+tools/puppet/packages.el new file mode 100644 index 0000000..4a3f8f8 --- /dev/null +++ b/layers/+tools/puppet/packages.el @@ -0,0 +1,41 @@ +;;; layers.el --- Puppet layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq puppet-packages + '( + company + flycheck + puppet-mode + )) + +(defun puppet/init-puppet-mode () + (use-package puppet-mode + :defer t + :init + (progn + (spacemacs/set-leader-keys-for-major-mode 'puppet-mode + "{" 'beginning-of-defun + "}" 'end-of-defun + "$" 'puppet-interpolate + "a" 'puppet-align-block + "'" 'puppet-toggle-string-quotes + ";" 'puppet-clear-string + "j" 'imenu + "c" 'puppet-apply + "v" 'puppet-validate + "l" 'puppet-lint + )))) + +(defun puppet/post-init-company () + (spacemacs|add-company-hook puppet-mode)) + +(defun puppet/post-init-flycheck () + (spacemacs/add-flycheck-hook 'puppet-mode)) diff --git a/layers/+tools/ranger/README.org b/layers/+tools/ranger/README.org new file mode 100644 index 0000000..e9bf155 --- /dev/null +++ b/layers/+tools/ranger/README.org @@ -0,0 +1,140 @@ +#+TITLE: Ranger layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#configuration][Configuration]] + - [[#customizing][Customizing]] + - [[#parent-options][Parent options]] + - [[#preview-options][Preview options]] + - [[#key-bindings][Key Bindings]] + +* Description + +This layer brings Ranger features to spacemacs from the =ranger= package. + +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =ranger= to the existing =dotspacemacs-configuration-layers= list in this +file. + +To default with preview enabled when entering ranger: +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers + '(ranger :variables + ranger-show-preview t)) +#+END_SRC + +* Features +- use ranger to display dired with ranger like preview and stacked parent windows. + +* Configuration +Most parameters can be toggled on and off and stay within the current emacs +session. Any settings that are desired on startup should be set below. + +** Customizing + +When disabling the mode you can choose to kill the buffers that were opened +while browsing the directories. +#+BEGIN_SRC elisp +(setq ranger-cleanup-on-disable t) +#+END_SRC + +Or you can choose to kill the buffer just after you move to another entry in the +dired buffer. +#+BEGIN_SRC elisp +(setq ranger-cleanup-eagerly t) +#+END_SRC + +You can choose to show dotfiles at ranger startup, toggled by =zh= +#+BEGIN_SRC elisp +(setq ranger-show-dotfiles t) +#+END_SRC + +Define custom function used to output header of primary ranger window. Must +return a string that is placed in the header-line. +#+BEGIN_SRC elisp +(setq ranger-header-func 'ranger-header-line) +#+END_SRC + +Define custom function used to output header of parent and preview windows. Must +return a string that is placed in the header-line. +#+BEGIN_SRC elisp +(setq ranger-parent-header-func 'ranger-parent-header-line) +#+END_SRC + +** Parent options + +You can set the number of folders to nest to the left, adjusted by =z-= and =z+= +#+BEGIN_SRC elisp +(setq ranger-parent-depth 2) +#+END_SRC + +You can set the size of the parent windows as a fraction of the frame size +#+BEGIN_SRC elisp +(setq ranger-width-parents 0.12) +#+END_SRC + +When increasing number of nested parent folders, set max width as fraction of +frame size to prevent filling up entire frame with parents. +#+BEGIN_SRC elisp +(setq ranger-max-parent-width 0.12) +#+END_SRC + +** Preview options + +You can choose to show previews literally, or through find-file, toggled by =zi= +#+BEGIN_SRC elisp +(setq ranger-show-dotfiles t) +#+END_SRC + +You can set the size of the preview windows as a fraction of the frame size +#+BEGIN_SRC elisp +(setq ranger-width-preview 0.55) +#+END_SRC + +You probably don't want to open certain files like videos when using preview. To +ignore certain files when moving over them you can customize the following to +your liking: +#+BEGIN_SRC elisp +(setq ranger-ignored-extensions '("mkv" "iso" "mp4")) +#+END_SRC + +To set the max files size (in MB), set the following parameter: +#+BEGIN_SRC elisp +(setq ranger-max-preview-size 10) +#+END_SRC + +* Key Bindings + +| Key Binding | Description | +|-------------+------------------------------------------------------| +| ~SPC a r~ | launch ranger | +| ~SPC a d~ | deer (minimal ranger window in current directory) | +| ~C-p~ | (ranger) toggle ranger in dired buffer | +| ~j~ | (ranger) navigate down | +| ~k~ | (ranger) navigate up | +| ~yy~ | (ranger) copy | +| ~pp~ | (ranger) paste | +| ~R~ | (ranger) rename | +| ~D~ | (ranger) delete | +| ~C-j~ | (ranger) scroll preview window down | +| ~C-k~ | (ranger) scroll preview window up | +| ~f~ | (ranger) search for file names | +| ~i~ | (ranger) show preview of current file | +| ~zi~ | (ranger) toggle showing literal / full-text previews | +| ~zh~ | (ranger) toggle showing dotfiles | +| ~o~ | (ranger) sort options | +| ~H~ | (ranger) search through history | +| ~h~ | (ranger) go up directory | +| ~l~ | (ranger) find file / enter directory | +| ~RET~ | (ranger) find file / enter directory | +| ~q~ | (ranger) quit | +| ~r~ | (ranger) revert buffer | +| ~z-~ | (ranger) reduce number of parents | +| ~z+~ | (ranger) increment number of parents | +| ~v~ | (ranger) toggle all marks | +| ~V~ | (ranger) visually select lines | +| ~S~ | (ranger) enter shell | +| ~C-SPC~ | (ranger) mark current file | +| ~;C~ | (ranger) copy directory / copy and move directory | +| ~;+~ | (ranger) create directory | diff --git a/layers/+tools/ranger/packages.el b/layers/+tools/ranger/packages.el new file mode 100644 index 0000000..0e70239 --- /dev/null +++ b/layers/+tools/ranger/packages.el @@ -0,0 +1,44 @@ +;;; packages.el --- ranger Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Rich Alesi +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq ranger-packages + '( + (dired :location built-in) + ranger + )) + +(defun ranger//set-leader-keys () + (spacemacs/set-leader-keys + "ar" 'ranger + "ad" 'deer)) + +(defun ranger/init-ranger () + (use-package ranger + :defer t + :commands (ranger deer ranger-override-dired-fn) + :init + (progn + (ranger//set-leader-keys) + ;; set up image-dired to allow picture resize + (setq image-dired-dir (concat spacemacs-cache-directory "image-dir")) + (unless (file-directory-p image-dired-dir) + (make-directory image-dired-dir))) + :config + (define-key ranger-mode-map (kbd "-") 'ranger-up-directory))) + +(defun ranger/post-init-dired () + ;; Be sure to override dired bindings + (ranger//set-leader-keys) + ;; need to apply this to compensate for defer + (spacemacs|use-package-add-hook ranger + :post-init (when ranger-override-dired + (add-hook 'dired-mode-hook #'ranger-override-dired-fn)))) diff --git a/layers/+tools/rebox/README.org b/layers/+tools/rebox/README.org new file mode 100644 index 0000000..1feb3cc --- /dev/null +++ b/layers/+tools/rebox/README.org @@ -0,0 +1,342 @@ +#+TITLE: Rebox layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#configuration][Configuration]] + - [[#styles-cycling][Styles cycling]] + - [[#text-mode][Text mode]] + - [[#style-templates][Style Templates]] + - [[#standard-packaged-templates][Standard packaged templates]] + - [[#comments][Comments]] + - [[#text-mode][Text Mode]] + - [[#c-mode][C Mode]] + - [[#additional-templates][Additional Templates]] + - [[#key-bindings][Key bindings]] + +* Description +This layer adds support for [[https://github.com/lewang/rebox2][rebox2]] package which is a minor-mode allowing +to easily add ASCII text boxes to a buffer. + +A nice video demonstration by the package author can be found [[https://www.youtube.com/watch?v=53YeTdVtDkU][here]]. + +** Features +- Auto-wrap correctly in comments, +- Auto-fill correctly in comments, +- Boxes auto-adapt as text is inserted or deleted, +- ~S-return~ to continue a comment on the next line, +- Kill/yank within the box, +- Apparently works well with ancient ~filladpt-mode~ (see authors video). + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =rebox= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Configuration +*** Styles cycling +Box styles are identified by numbers, it is possible to cycle through a list +of styles using ~SPC x b n~. This list can be customized by setting the variable +=rebox-style-loop=. + +#+BEGIN_SRC emacs-lisp +(setq rebox-style-loop '(71 72 73)) +#+END_SRC + +*** Text mode +As text mode usage could surprise some users (e.g., when they enter M-q to fill +a paragraph) =rebox= is not enabled by default in =text-mode=. To enable it you +need to set the layer variable =rebox-enable-in-text-mode= to =t=. + +#+begin_src emacs-lisp +(setq-default dotspacemacs-configuration-layers '( + (rebox :variables rebox-enable-in-text-mode t))) +#+end_src + +* Style Templates +** Standard packaged templates +*** Comments +These templates are single line comments styles. A =#= is used here for +illustration; however, it will work equally well if the comment character is +different (e.g., lisp's =;= comment character). + +#+begin_src sh + #box-style 10 + + # box style 11 + + # box style 12 # + # ------------ # + + # ------------ # + # box style 13 # + # ------------ # + + # box style 14 # + ################ + + ################ + # box style 15 # + ################ + + #,---- + #| box style 16 + #`---- + + #,------------- + #| box style 17 + #`------------- + + ##box style 20 + + ## box style 21 + + ## box style 22 ## + ## ------------ ## + + ## ------------ ## + ## box style 23 ## + ## ------------ ## + + ## box style 24 ## + ################## + + ################## + ## box style 25 ## + ################## + + ##,---- + ##| box style 26 + ##`---- + + ##,------------- + ##| box style 27 + ##`------------- + + ###box style 30 + + # and so on repeating up to styles 5x which have 5 leading comment characters +#+end_src + +*** Text Mode +#+begin_src text + box style 111 + + | box style 112 | + +---------------+ + + +---------------+ + | box style 113 | + +---------------+ + + | box style 114 | + *===============* + + *===============* + | box style 115 | + *===============* + + ------------- + box style 116 + ------------- + + | box style 121 | + + | box style 122 | + `---------------' + + .---------------. + | box style 123 | + `---------------' + + | box style 124 | + \===============/ + + /===============\ + | box style 125 | + \===============/ + + ,---- + | box style 126 + `---- + + ,-------------- + | box style 127 + `-------------- + + ,---- + | box style 136 + `---- + + ,-------------- + | box style 137 + `-------------- + + | box style 141 + + ** box style 142 * + ****************** + + ****************** + ** box style 143 * + ****************** + + X box style 144 X + XXXXXXXXXXXXXXXXX + + XXXXXXXXXXXXXXXXX + X box style 145 X + XXXXXXXXXXXXXXXXX +#+end_src + +*** C Mode +*Note* this mode is disabled for now due to bugs in rebox. + +#+begin_src c + /* box style 111 */ + + /* box style 112 */ + /* ------------- */ + + /* ------------- */ + /* box style 113 */ + /* ------------- */ + + /* box style 114 */ + /* ============= */ + + /* ============= */ + /* box style 115 */ + /* ============= */ + + /* + box style 221 + */ + + /* . + | box style 222 | + `--------------*/ + + /*--------------. + | box style 223 | + `--------------*/ + + /* \ + | box style 224 | + \==============*/ + + /*==============\ + | box style 225 | + \==============*/ + + /* + | box style 231 + */ + + /* + | box style 232 | + *---------------*/ + + /*---------------* + | box style 233 | + *---------------*/ + + /* box style 234 */ + /*---------------*/ + + /*---------------*/ + /* box style 235 */ + /*---------------*/ + + /* + * box style 241 + */ + + /* * + * box style 242 * + *****************/ + + /***************** + * box style 243 * + *****************/ + + /* box style 244 */ + /*****************/ + + /*****************/ + /* box style 245 */ + /*****************/ + + /****************//** + * box style 246 + ********************/ +#+end_src + +** Additional Templates +These templates are added by the Spacemacs layer. + +#+begin_src sh + # + # box style 71 + # + + # ------------ + # box style 72 + # ------------ + + # ============ + # box style 73 + # ============ + + #-------------- + # box style 74 + #-------------- + + #--------------+ + # box style 75 + #--------------+ + + #============== + # box style 76 + #============== + + ## + ## box style 81 + ## + + ## ------------ + ## box style 82 + ## ------------ + + ## ============ + ## box style 83 + ## ============ + + ##-------------- + ## box style 84 + ##-------------- + + ##--------------+ + ## box style 85 + ##--------------+ + + ##============== + ## box style 86 + ##============== +#+end_src + +* Key bindings +*Note:* Use a numerical prefix argument to choose a specific style for instance +~86 SPC x b b~ to use the style 86 above. + +| Keybinding | Command | +|-------------+-------------------------------------------------------------------| +| ~SPC x b >~ | Move box to the right (point must be around left side of the box) | +| ~SPC x b <~ | Move box to the left (point must be around left side of the box) | +| ~SPC x b b~ | Draw next box defined in =rebox-style-loop= | +| ~SPC x b B~ | Draw previous box defined in =rebox-style-loop= | +| ~SPC x b c~ | Center box (point must be around left side of the box) | +| ~S-return~ | rebox-indent-new-line | diff --git a/layers/+tools/rebox/config.el b/layers/+tools/rebox/config.el new file mode 100644 index 0000000..5b70423 --- /dev/null +++ b/layers/+tools/rebox/config.el @@ -0,0 +1,13 @@ +;;; packages.el --- rebox layer configuration file for Spacemacs. +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Christian E. Hopps +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar rebox-enable-in-text-mode nil + "If non nil then `rebox-mode' in enabled in `text-mode' buffers.") diff --git a/layers/+tools/rebox/funcs.el b/layers/+tools/rebox/funcs.el new file mode 100644 index 0000000..c22d9d4 --- /dev/null +++ b/layers/+tools/rebox/funcs.el @@ -0,0 +1,22 @@ +;;; packages.el --- rebox layer function file for Spacemacs. +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Christian E. Hopps +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun rebox-enable-hook () + "Until rebox is fixed for C style comments we have to disable" + (and (not (or (eq major-mode 'c-mode) + (eq major-mode 'c++-mode) + (eq major-mode 'objc-mode))) + (rebox-mode))) + +(defun spacemacs/rebox-dwim-previous () + "Cycle to previous style in `rebox-style-loop'." + (interactive) + (rebox-dwim '(4))) diff --git a/layers/+tools/rebox/packages.el b/layers/+tools/rebox/packages.el new file mode 100644 index 0000000..44b59a7 --- /dev/null +++ b/layers/+tools/rebox/packages.el @@ -0,0 +1,77 @@ +;;; packages.el --- rebox layer packages file for Spacemacs. +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Christian E. Hopps +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defconst rebox-packages '(rebox2)) + +(defun rebox/init-rebox2 () + (use-package rebox2 + :defer t + :diminish rebox-mode + :init + (progn + (when rebox-enable-in-text-mode + (add-hook 'text-mode-hook 'rebox-mode)) + (add-hook 'prog-mode-hook 'rebox-enable-hook) + + (spacemacs|define-transient-state rebox + :title "Rebox Transient State" + :bindings + (">" rebox-space "Move right") + ("<" rebox-backspace "Move left") + ("b" rebox-dwim "Cycle next") + ("B" spacemacs/rebox-dwim-previous "Cycle previous") + ("c" rebox-center "Center")) + + (spacemacs/declare-prefix "xb" "boxes") + (spacemacs/set-leader-keys + "xb>" 'spacemacs/rebox-transient-state/rebox-space + "xb<" 'spacemacs/rebox-transient-state/rebox-backspace + "xbb" 'spacemacs/rebox-transient-state/rebox-dwim + "xbB" 'spacemacs/rebox-transient-state/spacemacs/rebox-dwim-previous + "xbc" 'spacemacs/rebox-transient-state/rebox-center)) + :config + (progn + (rebox-register-template 71 176 ["?" + "? box123456" + "?"]) + (rebox-register-template 72 176 ["? ---------" + "? box123456" + "? ---------"]) + (rebox-register-template 73 376 ["? =========" + "? box123456" + "? ========="]) + (rebox-register-template 74 176 ["?-----------" + "? box123456 " + "?-----------"]) + (rebox-register-template 75 276 ["?-----------+" + "? box123456 " + "?-----------+"]) + (rebox-register-template 76 376 ["?===========" + "? box123456 " + "?==========="]) + (rebox-register-template 81 176 ["??" + "?? box123456" + "??"]) + (rebox-register-template 82 286 ["?? ---------" + "?? box123456" + "?? ---------"]) + (rebox-register-template 83 486 ["?? =========" + "?? box123456" + "?? ========="]) + (rebox-register-template 84 286 ["??-----------" + "?? box123456 " + "??-----------"]) + (rebox-register-template 85 386 ["??-----------+" + "?? box123456 " + "??-----------+"]) + (rebox-register-template 86 486 ["??===========" + "?? box123456 " + "??==========="])))) diff --git a/layers/+tools/restclient/README.org b/layers/+tools/restclient/README.org new file mode 100644 index 0000000..d2523c2 --- /dev/null +++ b/layers/+tools/restclient/README.org @@ -0,0 +1,42 @@ +#+TITLE: Restclient layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#configuration][Configuration]] + - [[#restclient][Restclient]] + - [[#keybindings][Keybindings]] + - [[#ob-http][ob-http]] + +* Description +This is a package that lets you have a REPL-like interface for http requests +using a [[http://pashky/restclient.el][restclient]] buffer or an =org= buffer. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =restclient= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Configuration +By default the layer enables [[http://pashky/restclient.el][restclient]]. It is possible to use =org= via [[http://github.com/zweifisch/ob-http][ob-http]] +by setting the layer variable =restclient-use-org= to =t=. + +* Restclient +Any file with an =.http= extension is opened in a =restclient= buffer. +Full documentation and examples can be found in the package's [[https://github.com/pashky/restclient.el][GitHub Page]]. +Also there is an [[http://emacsrocks.com/e15.html][Emacs Rocks!]] episode of it. + +** Keybindings + +| Key Binding | Description | +|-------------+-------------------------------------------------------------| +| ~SPC m s~ | Send and stay in window (pretty-print response if possible) | +| ~SPC m S~ | Send and switch window (pretty-print response if possible) | +| ~SPC m r~ | Send and stay in window (do not attempt to pretty-print) | +| ~SPC m R~ | Send and switch window (do not attempt to pretty-print) | +| ~SPC m y~ | Copy query under the cursor as a curl command | + +* ob-http +Any file with an =.http= extension is opened in an =org= buffer with org babel +configured to use =ob-http=. +Full documentation and examples can be found in the package's [[http://github.com/zweifisch/ob-http][GitHub Page]]. diff --git a/layers/+tools/restclient/config.el b/layers/+tools/restclient/config.el new file mode 100644 index 0000000..68b469e --- /dev/null +++ b/layers/+tools/restclient/config.el @@ -0,0 +1,13 @@ +;;; config.el --- restclient configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defvar restclient-use-org nil + "If non-nil use `ob-http' instead of `restclient'.") diff --git a/layers/+tools/restclient/funcs.el b/layers/+tools/restclient/funcs.el new file mode 100644 index 0000000..7384e80 --- /dev/null +++ b/layers/+tools/restclient/funcs.el @@ -0,0 +1,15 @@ +;;; funcs.el --- restclient Layer functions File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + + +(defun restclient-http-send-current-raw-stay-in-window () + (interactive) + (restclient-http-send-current t t)) diff --git a/layers/+tools/restclient/packages.el b/layers/+tools/restclient/packages.el new file mode 100644 index 0000000..ff900c1 --- /dev/null +++ b/layers/+tools/restclient/packages.el @@ -0,0 +1,42 @@ +;;; packages.el --- restclient Layer Packages File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(setq restclient-packages + '( + golden-ratio + ob-http + restclient + )) + +(defun restclient/pre-init-golden-ratio () + (spacemacs|use-package-add-hook golden-ratio + :post-config (add-to-list 'golden-ratio-exclude-modes "restclient-mode"))) + +(defun restclient/init-ob-http () + (when restclient-use-org + (add-to-list 'auto-mode-alist '("\\.http\\'" . org-mode))) + (spacemacs|use-package-add-hook org + :post-config + (use-package ob-http + :init (add-to-list 'org-babel-load-languages '(http . t))))) + +(defun restclient/init-restclient () + (use-package restclient + :defer t + :init + (progn + (unless restclient-use-org + (add-to-list 'auto-mode-alist '("\\.http\\'" . restclient-mode))) + (spacemacs/set-leader-keys-for-major-mode 'restclient-mode + "s" 'restclient-http-send-current-stay-in-window + "S" 'restclient-http-send-current + "r" 'restclient-http-send-current-raw-stay-in-window + "R" 'restclient-http-send-current-raw + "y" 'restclient-copy-curl-command)))) diff --git a/layers/+tools/salt/README.org b/layers/+tools/salt/README.org new file mode 100644 index 0000000..6acf173 --- /dev/null +++ b/layers/+tools/salt/README.org @@ -0,0 +1,22 @@ +#+TITLE: Saltstack layer + +[[file:img/saltstack.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + +* Description +This layer provides syntax highlighting for Saltstack files. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =salt= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key bindings + +| Key Binding | Description | +|-------------+----------------------------------------------| +| ~SPC m p b~ | mmm-mode parse buffer via =mmm-parse-buffer= | diff --git a/layers/+tools/salt/img/saltstack.png b/layers/+tools/salt/img/saltstack.png new file mode 100644 index 0000000..e6cda46 Binary files /dev/null and b/layers/+tools/salt/img/saltstack.png differ diff --git a/layers/+tools/salt/packages.el b/layers/+tools/salt/packages.el new file mode 100644 index 0000000..8ff849e --- /dev/null +++ b/layers/+tools/salt/packages.el @@ -0,0 +1,27 @@ +;;; packages.el --- Salt Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Ben Hayden +;; URL: https://github.com/syl20bnr/spacemacs +;; Salt mode URL: https://github.com/beardedprojamz/salt-mode +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(setq salt-packages '(salt-mode + smartparens)) + +(defun salt/init-salt-mode () + (use-package salt-mode + :defer t + :config (spacemacs/set-leader-keys-for-major-mode 'salt-mode "pb" 'mmm-parse-buffer))) + +(defun salt/pre-init-smartparens () + (add-hook 'salt-mode-hook 'smartparens-mode) + (spacemacs|use-package-add-hook smartparens + :post-config + (progn + (sp-local-pair 'salt-mode "{{" " }}") + (sp-local-pair 'salt-mode "{%" " %}") + (sp-local-pair 'salt-mode "{#" " #}")))) diff --git a/layers/+tools/shell/README.org b/layers/+tools/shell/README.org new file mode 100644 index 0000000..65beeef --- /dev/null +++ b/layers/+tools/shell/README.org @@ -0,0 +1,213 @@ +#+TITLE: Shell layer + +[[file:img/shell.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#configuration][Configuration]] + - [[#default-shell][Default shell]] + - [[#default-shell-position-and-height][Default shell position and height]] + - [[#set-shell-for-term-and-ansi-term][Set shell for term and ansi-term]] + - [[#width-of-the-shell-popup-buffers][Width of the shell popup buffers]] + - [[#enable-em-smart-in-eshell][Enable em-smart in Eshell]] + - [[#protect-your-eshell-prompt][Protect your Eshell prompt]] + - [[#fish-shell-and-ansi-term][Fish shell and ansi-term]] + - [[#eshell][Eshell]] + - [[#key-bindings][Key bindings]] + - [[#multi-term][Multi-term]] + - [[#eshell-1][Eshell]] + +* Description +This layer configures the various shells available in Emacs. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =shell= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Configuration +** Default shell +Emacs supports three types of shell: +- the Emacs shell +- the inferior shell +- the terminal emulator +- the ANSI terminal emulator + +You can find a quick introductions to them [[https://www.masteringemacs.org/article/running-shells-in-emacs-overview][here]]. + +To define the default shell you can set the layer variable =shell-default-shell= +to the following variables: +- =eshell= +- =shell= +- =term= +- =ansi-term= +- =multi-term= + +#+BEGIN_SRC emacs-lisp +(setq-default dotspacemacs-configuration-layers + '((shell :variables shell-default-shell 'eshell))) +#+END_SRC + +The default shell is quickly accessible via a the default shortcut key ~SPC '​~. + +** Default shell position and height +It is possible to choose where the shell should pop up by setting the variable +=shell-default-position= to either =top=, =bottom=, =left=, =right=, or =full=. +Default value is =bottom=. It is also possible to set the default height in +percents with the variable =shell-default-height=. Default value is =30=. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers + '((shell :variables + shell-default-position 'bottom + shell-default-height 30))) +#+END_SRC + +** Set shell for term and ansi-term +The default shell can be set by setting the variable =shell-default-term-shell=. +Default value is =/bin/bash=. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers + '((shell :variables shell-default-term-shell "/bin/bash"))) +#+END_SRC + +** Width of the shell popup buffers +By default the popup buffer spans the full width of the current frame, if +you prefer to spans only the width of the current window then set the +layer variable =shell-default-full-span= to nil. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers + '((shell :variables shell-default-full-span nil))) +#+END_SRC + +** Enable em-smart in Eshell +From the =em-smart= documentation: + +#+BEGIN_QUOTE +The best way to get a sense of what this code is trying to do is by +using it. Basically, the philosophy represents a blend between the +ease of use of modern day shells, and the review-before-you-proceed +mentality of Plan 9's 9term. +#+END_QUOTE + +In a nutshell, when =em-smart= is enabled point won't jump at the end of the +buffer when a command is executed, it will stay at the same command prompt used +to execute the command. This allows to quickly edit the last command in the case +of a mistake. If there is no mistake and you directly type a new command then +the prompt will jump to the next prompt at the end of the buffer. + +To enable =em-smart= put the following layer variable to non-nil: + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers + '((shell :variables shell-enable-smart-eshell t))) +#+END_SRC + +** Protect your Eshell prompt +Comint mode (Shell mode) has good support for Evil mode as it inhibits movement +commands over the prompt. This has the added benefit that Evil mode functions +work sensibly. E.g. you can press ~cc~ in normal state i.e. +=evil-change-whole-line= to kill the current input and start typing a new +command. In Eshell you also kill the prompt, which is often unintended. + +By default this layer also protects the =eshell= prompt. If you want to +disable this protection you can set the variable =shell-protect-eshell-prompt= +to nil. + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers + '((shell :variables shell-protect-eshell-prompt nil))) +#+END_SRC + +** Fish shell and ansi-term +Making =fish= shell to work with =ansi-term= may be a challenge, here are +some pointers to save you time to setup your environment correctly. + +First be sure =~/.terminfo= is setup correctly by running: + +#+BEGIN_SRC fish +tic -o ~/.terminfo $TERMINFO/e/eterm-color.ti +#+END_SRC + +You can locate the =eterm-colors.ti= file with: + +#+BEGIN_SRC fish +locate eterm-color.ti +#+END_SRC + +Then setup your fish configuration file (usually at =~/.config/fish/config.fish=) + +#+BEGIN_SRC fish +# emacs ansi-term support +if test -n "$EMACS" + set -x TERM eterm-color +end + +# this function may be required +function fish_title + true +end +#+END_SRC + +Finally you may need to toggle truncated lines for some prompts to work +correctly, in the function =dotspacemacs/user-config= of your dotfile add: + +#+BEGIN_SRC emacs-lisp +(add-hook 'term-mode-hook 'toggle-truncate-lines) +#+END_SRC + +* Eshell +Some advanced configuration is setup for =eshell= in this layer: +- some elisp functions aliases for quick access + - =s= for =magit-status= in the current directory (when the =git= layer is + installed) + - =d= for =dired= + - =e= to find a file via a new buffer + - =z= for quickly jumping to a previously visited directory +- optional configuration for =em-smart= (see =Install= section for more info) +- support for visual commands via =em-term= +- working directory sensitive prompt via [[https://github.com/hiddenlotus/eshell-prompt-extras][eshell-prompt-extras]] +- advanced help support via =esh-help= (enable =el-doc= support in eshell) +- add support for auto-completion via =company= (when the =auto-completion= + layer is installed) +- pressing ~i~ in normal state will automatically jump to the prompt + +* Key bindings + +| Key Binding | Description | +|-------------+------------------------------------------------------------| +| ~SPC '​~ | Open, close or go to the default shell | +| ~SPC p '​~ | Open a shell in the project's root | +| ~SPC a s e~ | Open, close or go to an =eshell= | +| ~SPC a s i~ | Open, close or go to a =shell= | +| ~SPC a s m~ | Open, close or go to a =multi-term= | +| ~SPC a s t~ | Open, close or go to a =ansi-term= | +| ~SPC a s T~ | Open, close or go to a =term= | +| ~SPC m H~ | browse history with =helm= (works in =eshell= and =shell=) | +| ~C-j~ | next item in history | +| ~C-k~ | previous item in history | + +*Note:* You can open multiple shells using a numerical prefix argument, +for instance pressing ~2 SPC '​~ will a second default shell, the +number of shell is indicated on the mode-line. + +*Note:* Use the universal prefix argument ~SPC u SPC '​~ to open the shell +in the current buffer instead of a popup. + +** Multi-term + +| Key Binding | Description | +|-------------+------------------------------| +| ~SPC m c~ | create a new multi-term | +| ~SPC m n~ | go to next multi-term | +| ~SPC m p~ | go to previous multi-term | +| ~SPC p $ t~ | run multi-term shell in root | + +** Eshell + +| Key Binding | Description | +|--------------------+--------------------------------------------| +| ~SPC m H~ or ~M-l~ | shell commands history using a helm buffer | diff --git a/layers/+tools/shell/config.el b/layers/+tools/shell/config.el new file mode 100644 index 0000000..2180aa8 --- /dev/null +++ b/layers/+tools/shell/config.el @@ -0,0 +1,51 @@ +;;; config.el --- shell configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Emacs built-in variables + +;; move point to the end of buffer on new output +(setq comint-move-point-for-output t) + +;; Add shell buffers to useful buffers list +(push "\\*\\(ansi-term\\|eshell\\|shell\\|terminal\.\+\\)\\(-[0-9]+\\)?\\*" + spacemacs-useful-buffers-regexp) + +;; Variables + +(spacemacs|defvar-company-backends eshell-mode) + +(defvar shell-default-shell (if (eq window-system 'w32) + 'eshell + 'ansi-term) + "Default shell to use in Spacemacs. Possible values are `eshell', `shell', +`term' and `ansi-term'.") + +(defvar shell-default-position 'bottom + "Position of the shell. Possible values are `top', `bottom', `full', +`left' and `right'.") + +(defvar shell-default-height 30 + "Height in percents for the shell window.") + +(defvar shell-default-term-shell shell-file-name + "Default shell to use in `term' and `ansi-term' shells.") + +(defvar shell-enable-smart-eshell nil + "If non-nil then `em-smart' is enabled. `em-smart' allows to quickly review +commands, modify old commands or enter a new one.") + +(defvar shell-protect-eshell-prompt t + "If non-nil then eshell's prompt is protected. This means that +movement to the prompt is inhibited like for `comint-mode' +prompts and the prompt is made read-only") + +(defvar shell-default-full-span t + "If non-nil, the `shell' buffer spans full width of a frame.") diff --git a/layers/+tools/shell/funcs.el b/layers/+tools/shell/funcs.el new file mode 100644 index 0000000..c56e147 --- /dev/null +++ b/layers/+tools/shell/funcs.el @@ -0,0 +1,167 @@ +;;; funcs.el --- Shell Layer functions File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spacemacs/projectile-shell-pop () + "Open a term buffer at projectile project root." + (interactive) + (let ((default-directory (projectile-project-root))) + (call-interactively 'spacemacs/default-pop-shell))) + +(defun spacemacs/disable-hl-line-mode () + "Locally disable global-hl-line-mode" + (interactive) + (setq-local global-hl-line-mode nil)) + +(defun spacemacs/init-eshell-xterm-color () + "Initialize xterm coloring for eshell" + (setq-local xterm-color-preserve-properties t) + (make-local-variable 'eshell-preoutput-filter-functions) + (add-hook 'eshell-preoutput-filter-functions 'xterm-color-filter) + (setq-local eshell-output-filter-functions + (remove 'eshell-handle-ansi-color + eshell-output-filter-functions))) + +(defun ansi-term-handle-close () + "Close current term buffer when `exit' from term buffer." + (when (ignore-errors (get-buffer-process (current-buffer))) + (set-process-sentinel (get-buffer-process (current-buffer)) + (lambda (proc change) + (when (string-match "\\(finished\\|exited\\)" + change) + (kill-buffer (process-buffer proc)) + (when (> (count-windows) 1) + (delete-window))))))) + +(defun spacemacs/default-pop-shell () + "Open the default shell in a popup." + (interactive) + (let ((shell (if (eq 'multi-term shell-default-shell) + 'multiterm + shell-default-shell))) + (call-interactively (intern (format "spacemacs/shell-pop-%S" shell))))) + +(defmacro make-shell-pop-command (func &optional shell) + "Create a function to open a shell via the function FUNC. +SHELL is the SHELL function to use (i.e. when FUNC represents a terminal)." + (let* ((name (symbol-name func))) + `(defun ,(intern (concat "spacemacs/shell-pop-" name)) (index) + ,(format (concat "Toggle a popup window with `%S'.\n" + "Multiple shells can be opened with a numerical prefix " + "argument. Using the universal prefix argument will " + "open the shell in the current buffer instead of a " + "popup buffer.") func) + (interactive "P") + (require 'shell-pop) + (if (equal '(4) index) + ;; no popup + (,func ,shell) + (shell-pop--set-shell-type + 'shell-pop-shell-type + (backquote (,name + ,(concat "*" name "*") + (lambda nil (,func ,shell))))) + (shell-pop index))))) + +(defun projectile-multi-term-in-root () + "Invoke `multi-term' in the project's root." + (interactive) + (projectile-with-default-dir (projectile-project-root) (multi-term))) + +(defun spacemacs//toggle-shell-auto-completion-based-on-path () + "Deactivates automatic completion on remote paths. +Retrieving completions for Eshell blocks Emacs. Over remote +connections the delay is often annoying, so it's better to let +the user activate the completion manually." + (if (file-remote-p default-directory) + (setq-local company-idle-delay nil) + (setq-local company-idle-delay 0.2))) + +(defun spacemacs//eshell-switch-company-frontend () + "Sets the company frontend to `company-preview-frontend' in e-shell mode." + (setq-local company-frontends '(company-preview-frontend))) + +(defun spacemacs//eshell-auto-end () + "Move point to end of current prompt when switching to insert state." + (when (and (eq major-mode 'eshell-mode) + ;; Not on last line, we might want to edit within it. + (not (eq (line-end-position) (point-max)))) + (end-of-buffer))) + +(defun spacemacs//protect-eshell-prompt () + "Protect Eshell's prompt like Comint's prompts. + +E.g. `evil-change-whole-line' won't wipe the prompt. This +is achieved by adding the relevant text properties." + (let ((inhibit-field-text-motion t)) + (add-text-properties + (point-at-bol) + (point) + '(rear-nonsticky t + inhibit-line-move-field-capture t + field output + read-only t + front-sticky (field inhibit-line-move-field-capture))))) + +(defun spacemacs//init-eshell () + "Stuff to do when enabling eshell." + (setq pcomplete-cycle-completions nil) + (if (bound-and-true-p linum-mode) (linum-mode -1)) + (unless shell-enable-smart-eshell + ;; we don't want auto-jump to prompt when smart eshell is enabled. + ;; Idea: maybe we could make auto-jump smarter and jump only if + ;; point is not on a prompt line + (add-hook 'evil-insert-state-entry-hook + 'spacemacs//eshell-auto-end nil t) + (add-hook 'evil-hybrid-state-entry-hook + 'spacemacs//eshell-auto-end nil t)) + (when (configuration-layer/package-usedp 'semantic) + (semantic-mode -1)) + ;; Caution! this will erase buffer's content at C-l + (define-key eshell-mode-map (kbd "C-l") 'eshell/clear) + (define-key eshell-mode-map (kbd "C-d") 'eshell-delchar-or-maybe-eof)) + +;; This is an eshell alias +(defun eshell/clear () + (interactive) + (let ((inhibit-read-only t)) + (erase-buffer)) + (eshell-send-input)) + +(defun spacemacs/helm-eshell-history () + "Correctly revert to insert state after selection." + (interactive) + (helm-eshell-history) + (evil-insert-state)) + +(defun spacemacs/helm-shell-history () + "Correctly revert to insert state after selection." + (interactive) + (helm-comint-input-ring) + (evil-insert-state)) + +(defun spacemacs/init-helm-eshell () + "Initialize helm-eshell." + ;; this is buggy for now + ;; (define-key eshell-mode-map (kbd "") 'helm-esh-pcomplete) + (spacemacs/set-leader-keys-for-major-mode 'eshell-mode + "H" 'spacemacs/helm-eshell-history) + (define-key eshell-mode-map + (kbd "M-l") 'spacemacs/helm-eshell-history)) + +(defun multiterm (_) + "Wrapper to be able to call multi-term from shell-pop" + (interactive) + (multi-term)) + +(defun term-send-tab () + "Send tab in term mode." + (interactive) + (term-send-raw-string "\t")) diff --git a/layers/+tools/shell/img/shell.png b/layers/+tools/shell/img/shell.png new file mode 100644 index 0000000..8eb758a Binary files /dev/null and b/layers/+tools/shell/img/shell.png differ diff --git a/layers/+tools/shell/packages.el b/layers/+tools/shell/packages.el new file mode 100644 index 0000000..825f846 --- /dev/null +++ b/layers/+tools/shell/packages.el @@ -0,0 +1,260 @@ +;;; packages.el --- shell packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq shell-packages + '( + (comint :location built-in) + company + esh-help + (eshell :location built-in) + eshell-prompt-extras + eshell-z + helm + magit + multi-term + org + projectile + (shell :location built-in) + shell-pop + (term :location built-in) + xterm-color + vi-tilde-fringe + )) + +(defun shell/init-comint () + (setq comint-prompt-read-only t) + (add-hook 'comint-mode-hook 'spacemacs/disable-hl-line-mode)) + +(defun shell/pre-init-company () + ;; support in eshell + (spacemacs|use-package-add-hook eshell + :post-init + (progn + (push 'company-capf company-backends-eshell-mode) + (spacemacs|add-company-hook eshell-mode) + (add-hook 'eshell-directory-change-hook + 'spacemacs//toggle-shell-auto-completion-based-on-path) + ;; The default frontend screws everything up in short windows like + ;; terminal often are + (add-hook 'eshell-mode-hook + 'spacemacs//eshell-switch-company-frontend)))) + +(defun shell/init-esh-help () + (use-package esh-help + :defer t + :init (add-hook 'eshell-mode-hook 'eldoc-mode) + :config (setup-esh-help-eldoc))) + +(defun shell/init-eshell () + (use-package eshell + :defer t + :init + (progn + (spacemacs/register-repl 'eshell 'eshell) + (setq eshell-cmpl-cycle-completions nil + ;; auto truncate after 20k lines + eshell-buffer-maximum-lines 20000 + ;; history size + eshell-history-size 350 + ;; no duplicates in history + eshell-hist-ignoredups t + ;; buffer shorthand -> echo foo > #'buffer + eshell-buffer-shorthand t + ;; my prompt is easy enough to see + eshell-highlight-prompt nil + ;; treat 'echo' like shell echo + eshell-plain-echo-behavior t + ;; cache directory + eshell-directory-name (concat spacemacs-cache-directory "eshell/")) + + (when shell-protect-eshell-prompt + (add-hook 'eshell-after-prompt-hook 'spacemacs//protect-eshell-prompt)) + + (autoload 'eshell-delchar-or-maybe-eof "em-rebind") + + (add-hook 'eshell-mode-hook 'spacemacs//init-eshell) + (add-hook 'eshell-mode-hook 'spacemacs/disable-hl-line-mode)) + :config + (progn + (require 'esh-opt) + + ;; quick commands + (defalias 'eshell/e 'find-file-other-window) + (defalias 'eshell/d 'dired) + (setenv "PAGER" "cat") + + ;; support `em-smart' + (when shell-enable-smart-eshell + (require 'em-smart) + (setq eshell-where-to-jump 'begin + eshell-review-quick-commands nil + eshell-smart-space-goes-to-end t) + (add-hook 'eshell-mode-hook 'eshell-smart-initialize)) + + ;; Visual commands + (require 'em-term) + (mapc (lambda (x) (push x eshell-visual-commands)) + '("el" "elinks" "htop" "less" "ssh" "tmux" "top")) + + ;; automatically truncate buffer after output + (when (boundp 'eshell-output-filter-functions) + (push 'eshell-truncate-buffer eshell-output-filter-functions)) + + ;; These don't work well in normal state + ;; due to evil/emacs cursor incompatibility + (evil-define-key 'insert eshell-mode-map + (kbd "C-k") 'eshell-previous-matching-input-from-input + (kbd "C-j") 'eshell-next-matching-input-from-input)))) + +(defun shell/init-eshell-prompt-extras () + (use-package eshell-prompt-extras + :commands epe-theme-lambda + :init + (setq eshell-highlight-prompt nil + eshell-prompt-function 'epe-theme-lambda))) + +(defun shell/init-eshell-z () + (use-package eshell-z + :defer t + :init + (with-eval-after-load 'eshell + (require 'eshell-z)))) + +(defun shell/pre-init-helm () + (spacemacs|use-package-add-hook helm + :post-init + (progn + ;; eshell + (add-hook 'eshell-mode-hook 'spacemacs/init-helm-eshell) + ;;shell + (spacemacs/set-leader-keys-for-major-mode 'shell-mode + "H" 'spacemacs/helm-shell-history)))) + +(defun shell/pre-init-magit () + (spacemacs|use-package-add-hook magit + :post-init + (defalias 's 'magit-status))) + +(defun shell/init-multi-term () + (use-package multi-term + :defer t + :init + (progn + (spacemacs/register-repl 'multi-term 'multi-term)) + :config + (progn + (add-to-list 'term-bind-key-alist '("" . term-send-tab)) + ;; multi-term commands to create terminals and move through them. + (spacemacs/set-leader-keys-for-major-mode 'term-mode + "c" 'multi-term + "p" 'multi-term-prev + "n" 'multi-term-next)))) + +(defun shell/pre-init-org () + (spacemacs|use-package-add-hook org + :post-config (add-to-list 'org-babel-load-languages '(shell . t)))) + +(defun shell/post-init-projectile () + (spacemacs/set-leader-keys + "p'" 'spacemacs/projectile-shell-pop + "p$t" 'projectile-multi-term-in-root)) + +(defun shell/init-shell () + (spacemacs/register-repl 'shell 'shell) + (defun shell-comint-input-sender-hook () + "Check certain shell commands. + Executes the appropriate behavior for certain commands." + (setq comint-input-sender + (lambda (proc command) + (cond + ;; Check for clear command and execute it. + ((string-match "^[ \t]*clear[ \t]*$" command) + (comint-send-string proc "\n") + (erase-buffer)) + ;; Check for man command and execute it. + ((string-match "^[ \t]*man[ \t]*" command) + (comint-send-string proc "\n") + (setq command (replace-regexp-in-string + "^[ \t]*man[ \t]*" "" command)) + (setq command (replace-regexp-in-string + "[ \t]+$" "" command)) + (funcall 'man command)) + ;; Send other commands to the default handler. + (t (comint-simple-send proc command)))))) + (add-hook 'shell-mode-hook 'shell-comint-input-sender-hook) + (add-hook 'shell-mode-hook 'spacemacs/disable-hl-line-mode)) + +(defun shell/init-shell-pop () + (use-package shell-pop + :defer t + :init + (progn + (setq shell-pop-window-position shell-default-position + shell-pop-window-size shell-default-height + shell-pop-term-shell shell-default-term-shell + shell-pop-full-span shell-default-full-span) + (make-shell-pop-command eshell) + (make-shell-pop-command shell) + (make-shell-pop-command term shell-pop-term-shell) + (make-shell-pop-command multiterm) + (make-shell-pop-command ansi-term shell-pop-term-shell) + + (add-hook 'term-mode-hook 'ansi-term-handle-close) + (add-hook 'term-mode-hook (lambda () (linum-mode -1))) + + (spacemacs/set-leader-keys + "'" 'spacemacs/default-pop-shell + "ase" 'spacemacs/shell-pop-eshell + "asi" 'spacemacs/shell-pop-shell + "asm" 'spacemacs/shell-pop-multiterm + "ast" 'spacemacs/shell-pop-ansi-term + "asT" 'spacemacs/shell-pop-term)))) + +(defun shell/init-term () + (spacemacs/register-repl 'term 'term) + (spacemacs/register-repl 'term 'ansi-term) + (defun term-send-tab () + "Send tab in term mode." + (interactive) + (term-send-raw-string "\t")) + ;; hack to fix pasting issue, the paste transient-state won't + ;; work in term + (evil-define-key 'normal term-raw-map "p" 'term-paste) + (evil-define-key 'insert term-raw-map (kbd "C-c C-d") 'term-send-eof) + (evil-define-key 'insert term-raw-map (kbd "C-c C-z") 'term-stop-subjob) + (evil-define-key 'insert term-raw-map (kbd "") 'term-send-tab) + + (when (eq dotspacemacs-editing-style 'vim) + (evil-define-key 'insert term-raw-map + (kbd "C-k") 'term-send-up + (kbd "C-j") 'term-send-down)) + (evil-define-key 'normal term-raw-map + (kbd "C-k") 'term-send-up + (kbd "C-j") 'term-send-down) + + (add-hook 'term-mode-hook 'spacemacs/disable-hl-line-mode)) + +(defun shell/init-xterm-color () + (use-package xterm-color + :init + (progn + ;; Comint and Shell + (add-hook 'comint-preoutput-filter-functions 'xterm-color-filter) + (setq comint-output-filter-functions + (remove 'ansi-color-process-output comint-output-filter-functions)) + (add-hook 'eshell-mode-hook 'spacemacs/init-eshell-xterm-color)))) + +(defun shell/post-init-vi-tilde-fringe () + (spacemacs/add-to-hooks 'spacemacs/disable-vi-tilde-fringe + '(comint-mode-hook + eshell-mode-hook + shell-mode-hook + term-mode-hook))) diff --git a/layers/+tools/speed-reading/README.org b/layers/+tools/speed-reading/README.org new file mode 100644 index 0000000..847a3fd --- /dev/null +++ b/layers/+tools/speed-reading/README.org @@ -0,0 +1,26 @@ +#+TITLE: Speed Reading layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + +* Description +A speed reading mode for Emacs. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =speed-reading= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key bindings + +| Key Binding | Description | +|-------------+---------------| +| ~SPC a R~ | Start Spray | +| ~SPC~ | Pause Spray | +| ~h~ | Backward word | +| ~l~ | Forward word | +| ~f~ | Faster speed | +| ~s~ | Slower speed | +| ~q~ | Quit Spray | diff --git a/layers/+tools/speed-reading/packages.el b/layers/+tools/speed-reading/packages.el new file mode 100644 index 0000000..1fe646b --- /dev/null +++ b/layers/+tools/speed-reading/packages.el @@ -0,0 +1,43 @@ +;;; packages.el --- speed-reading Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq speed-reading-packages + '( + spray + which-key + )) + +(defun speed-reading/init-spray () + (use-package spray + :commands spray-mode + :init + (progn + (defun speed-reading/start-spray () + "Start spray speed reading on current buffer at current point." + (interactive) + (evil-insert-state) + (spray-mode t) + (internal-show-cursor (selected-window) nil)) + (spacemacs/set-leader-keys "aR" 'speed-reading/start-spray) + + (defadvice spray-quit (after speed-reading//quit-spray activate) + "Correctly quit spray." + (internal-show-cursor (selected-window) t) + (evil-normal-state))) + :config + (progn + (define-key spray-mode-map (kbd "h") 'spray-backward-word) + (define-key spray-mode-map (kbd "l") 'spray-forward-word) + (define-key spray-mode-map (kbd "q") 'spray-quit)))) + +(defun speed-reading/post-init-which-key () + (push '("\\`speed-reading/\\(.+\\)\\'" . "\\1") + which-key-description-replacement-alist)) diff --git a/layers/+tools/systemd/README.org b/layers/+tools/systemd/README.org new file mode 100644 index 0000000..09768a7 --- /dev/null +++ b/layers/+tools/systemd/README.org @@ -0,0 +1,24 @@ +#+TITLE: systemd layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + +* Description +This layer provides syntax highlighting for systemd files and completion through +=company= if the =auto-completion= layer is used. + +* Install +To use this contribution add it to your =~/.spacemacs= + +#+begin_src emacs-lisp + (setq-default dotspacemacs-configuration-layers '(systemd)) +#+end_src + +* Key bindings + +| Key Binding | Description | +|-------------+--------------------------------------------------------------------------| +| ~SPC m h d~ | Systemd open the directives documentation | +| ~SPC m h o~ | Systemd open documentation (if a =\=Documentation= directive is provided | diff --git a/layers/+tools/systemd/packages.el b/layers/+tools/systemd/packages.el new file mode 100644 index 0000000..e6e8784 --- /dev/null +++ b/layers/+tools/systemd/packages.el @@ -0,0 +1,25 @@ +;;; packages.el --- systemd layer packages file for Spacemacs. +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Fabien Dubosson +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defconst systemd-packages + '(systemd) + "The list of Lisp packages required by the systemd layer.") + +(defun systemd/init-systemd () + (use-package systemd + :defer t + :init (setq systemd-use-company-p + (configuration-layer/package-usedp 'company)) + :config (spacemacs/set-leader-keys-for-major-mode 'systemd-mode + "hd" 'systemd-doc-directives + "ho" 'systemd-doc-open))) + +;;; packages.el ends here diff --git a/layers/+tools/terraform/README.org b/layers/+tools/terraform/README.org new file mode 100644 index 0000000..1f99192 --- /dev/null +++ b/layers/+tools/terraform/README.org @@ -0,0 +1,16 @@ +#+TITLE: Terraform layer + +[[file:img/terraform.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + +* Description +This layer provides syntax support for Terraform =.tf= files using +[[https://github.com/syohex/emacs-terraform-mode][terraform-mode]]. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =terraform= to the existing =dotspacemacs-configuration-layers= list in this +file. diff --git a/layers/+tools/terraform/img/terraform.png b/layers/+tools/terraform/img/terraform.png new file mode 100644 index 0000000..6bfe0bb Binary files /dev/null and b/layers/+tools/terraform/img/terraform.png differ diff --git a/layers/+tools/terraform/packages.el b/layers/+tools/terraform/packages.el new file mode 100644 index 0000000..1ed8567 --- /dev/null +++ b/layers/+tools/terraform/packages.el @@ -0,0 +1,16 @@ +;;; packages.el --- terraform Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Brian Hicks +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq terraform-packages '(terraform-mode)) + +(defun terraform/init-terraform-mode () + (use-package terraform-mode + :defer t)) diff --git a/layers/+tools/tmux/README.org b/layers/+tools/tmux/README.org new file mode 100644 index 0000000..b14540f --- /dev/null +++ b/layers/+tools/tmux/README.org @@ -0,0 +1,9 @@ +#+TITLE: Tmux layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#what-is-this][What is this]] + +* What is this +This is an extension to support [[https://github.com/Keithbsmiley/evil-tmux-navigator][evil-tmux-navigator]]. It requires a little +configuration for tmux, so check the upstream documentation. + diff --git a/layers/+tools/tmux/local/tmux/tmux.el b/layers/+tools/tmux/local/tmux/tmux.el new file mode 100644 index 0000000..b819932 --- /dev/null +++ b/layers/+tools/tmux/local/tmux/tmux.el @@ -0,0 +1,83 @@ +;;; tmux.el --- Seamlessly navigate between Emacs and tmux + +;; Author: Keith Smiley +;; Created: April 25 2014 +;; Version: 0.1.5 +;; Keywords: tmux, evil, vi, vim + +;;; Commentary: + +;; This package is inspired by vim-tmux-navigator. +;; It allows you to navigate splits in evil mode +;; Along with tmux splits with the same commands +;; Include with: +;; +;; (require 'navigate) +;; + +;;; Code: + +(require 'evil) + +(defgroup navigate nil + "seamlessly navigate between Emacs and tmux" + :prefix "navigate-" + :group 'evil) + +; This requires windmove commands +(when (fboundp 'windmove-default-keybindings) + (windmove-default-keybindings)) + +(defun tmux-navigate (direction) + (let + ((cmd (concat "windmove-" direction))) + (condition-case nil + (funcall (intern cmd)) + (error + (tmux-command direction))))) + +(defun tmux-command (direction) + (shell-command-to-string + (concat "tmux select-pane -" + (tmux-direction direction)))) + +(defun tmux-direction (direction) + (upcase + (substring direction 0 1))) + +(defun tmux-nav-left () + (interactive) + (tmux-navigate "left")) + +(defun tmux-nav-right () + (interactive) + (tmux-navigate "right")) + +(defun tmux-nav-up () + (interactive) + (tmux-navigate "up")) + +(defun tmux-nav-down () + (interactive) + (tmux-navigate "down")) + +(define-key evil-normal-state-map (kbd "C-h") #'tmux-nav-left) +(define-key evil-normal-state-map (kbd "C-j") #'tmux-nav-down) +(define-key evil-normal-state-map (kbd "C-k") #'tmux-nav-up) +(define-key evil-normal-state-map (kbd "C-l") #'tmux-nav-right) +(define-key evil-motion-state-map (kbd "C-h") #'tmux-nav-left) +(define-key evil-motion-state-map (kbd "C-j") #'tmux-nav-down) +(define-key evil-motion-state-map (kbd "C-k") #'tmux-nav-up) +(define-key evil-motion-state-map (kbd "C-l") #'tmux-nav-right) + +;; Modify `evil-evilified-state-map-original' because `evil-evilified-state-map' +;; is reset to this value each time the evilify macro is run. +(when (boundp 'evil-evilified-state-map-original) + (define-key evil-evilified-state-map-original (kbd "C-h") #'tmux-nav-left) + (define-key evil-evilified-state-map-original (kbd "C-j") #'tmux-nav-down) + (define-key evil-evilified-state-map-original (kbd "C-k") #'tmux-nav-up) + (define-key evil-evilified-state-map-original (kbd "C-l") #'tmux-nav-right)) + +(provide 'tmux) + +;;; tmux.el ends here diff --git a/layers/+tools/tmux/packages.el b/layers/+tools/tmux/packages.el new file mode 100644 index 0000000..cc2f7f3 --- /dev/null +++ b/layers/+tools/tmux/packages.el @@ -0,0 +1,26 @@ +;;; packages.el --- tmux Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(setq tmux-packages + '( + golden-ratio + (tmux :location local) + )) + +(defun tmux/post-init-golden-ratio () + (with-eval-after-load 'golden-ratio + (add-to-list 'golden-ratio-extra-commands 'tmux-nav-left) + (add-to-list 'golden-ratio-extra-commands 'tmux-nav-right) + (add-to-list 'golden-ratio-extra-commands 'tmux-nav-up) + (add-to-list 'golden-ratio-extra-commands 'tmux-nav-down))) + +(defun tmux/init-tmux () + "Initialize tmux" + (use-package tmux)) diff --git a/layers/+tools/vagrant/README.org b/layers/+tools/vagrant/README.org new file mode 100644 index 0000000..c66423e --- /dev/null +++ b/layers/+tools/vagrant/README.org @@ -0,0 +1,54 @@ +#+TITLE: Vagrant layer + +[[file:img/vagrant.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features:]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#vagrant][Vagrant]] + - [[#testing][Testing]] + - [[#keybindings][Keybindings]] + +* Description + +This layer adds support for working with Vagrant using [[https://github.com/ottbot/vagrant.el][vagrant.el]] and +[[https://github.com/dougm/vagrant-tramp][vagrant-tramp]]. + +** Features: + - Manage boxes (under the ~SPC V~ prefix) + - Remote editing on Vagrant boxes via Tramp + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =vagrant= to the existing =dotspacemacs-configuration-layers= list in this +file. + +*Note:* Since vagrant files are written in =ruby= it is recommended +to install the =ruby= layer as well. + +** Vagrant +Follow the [[http://docs.vagrantup.com/v2/installation/index.html][Installing Vagrant]] and [[http://docs.vagrantup.com/v2/getting-started/index.html][Getting Started]] guides in +Vagrant's documentation. + +** Testing +If you'd like to test this layer out in a simple way (for example to +make sure you have Vagrant configured correctly) there is a [[file:Vagrantfile][Vagrantfile]] +in this directory. + +* Keybindings + +| Key Binding | Description | +|-------------+------------------------------------------------------------------------------------------------| +| ~SPC V D~ | destroy a box | +| ~SPC V e~ | edit the =Vagrantfile= | +| ~SPC V H~ | halt (shut down) a box | +| ~SPC V p~ | (re)provision a box that is already up | +| ~SPC V r~ | resume a suspended box (you can also use =SPC V V= for this) | +| ~SPC V R~ | reload a box | +| ~SPC V s~ | view the status of running boxes in the current project | +| ~SPC V S~ | suspend a box | +| ~SPC V t~ | start a =vagrant-tramp-term= session - after start, edit files at =/vagrant:box_name:filename= | +| ~SPC V V~ | bring up a Vagrant box | diff --git a/layers/+tools/vagrant/Vagrantfile b/layers/+tools/vagrant/Vagrantfile new file mode 100644 index 0000000..245438d --- /dev/null +++ b/layers/+tools/vagrant/Vagrantfile @@ -0,0 +1,14 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# This file is provided for testing this layer - it doesn't really do +# very much! + +# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + config.vm.box = "ubuntu/trusty64" + + config.vm.provision :shell, inline: "echo provisioned" +end diff --git a/layers/+tools/vagrant/img/vagrant.png b/layers/+tools/vagrant/img/vagrant.png new file mode 100644 index 0000000..3d25444 Binary files /dev/null and b/layers/+tools/vagrant/img/vagrant.png differ diff --git a/layers/+tools/vagrant/packages.el b/layers/+tools/vagrant/packages.el new file mode 100644 index 0000000..3be9784 --- /dev/null +++ b/layers/+tools/vagrant/packages.el @@ -0,0 +1,42 @@ +;;; packages.el --- Vagrant Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Brian Hicks +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(setq vagrant-packages '(vagrant + vagrant-tramp)) + +(defun vagrant/init-vagrant () + (use-package vagrant + :defer t + :init + (progn + (spacemacs/declare-prefix "V" "vagrant") + (spacemacs/set-leader-keys + "VD" 'vagrant-destroy + "Ve" 'vagrant-edit + "VH" 'vagrant-halt + "Vp" 'vagrant-provision + "Vr" 'vagrant-resume + "VR" 'vagrant-reload + "Vs" 'vagrant-status + "VS" 'vagrant-suspend + "VV" 'vagrant-up)))) + +(defun vagrant/init-vagrant-tramp () + (use-package vagrant-tramp + :defer t + :init + (progn + (defvar spacemacs--vagrant-tramp-loaded nil) + (defadvice vagrant-tramp-term (before spacemacs//load-vagrant activate) + "Lazy load vagrant-tramp." + (unless spacemacs--vagrant-tramp-loaded + (vagrant-tramp-add-method) + (setq spacemacs--vagrant-tramp-loaded t))) + (spacemacs/set-leader-keys "Vt" 'vagrant-tramp-term)))) diff --git a/layers/+tools/ycmd/README.org b/layers/+tools/ycmd/README.org new file mode 100644 index 0000000..95d37d9 --- /dev/null +++ b/layers/+tools/ycmd/README.org @@ -0,0 +1,94 @@ +#+TITLE: YCMD layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#ycmd][YCMD]] + - [[#other-requirements][Other Requirements]] + - [[#configuration][Configuration]] + - [[#activating-ycmd-in-a-major-mode][Activating ycmd in a major mode]] + - [[#getting-the-compilation-flags][Getting the compilation flags]] + - [[#key-bindings][Key Bindings]] + +* Description + +This layer adds [[https://github.com/abingham/emacs-ycmd][emacs-ycmd]] support. + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =ycmd= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** YCMD +1) Install the =ycm= server. Installation instructions can be found [[https://github.com/Valloric/ycmd#building][here]]. +2) Set the =ycmd-server-command= variable to reflect the path to the installation: + #+BEGIN_SRC emacs-lisp + (setq ycmd-server-command '("python" "/path/to/YouCompleteMe/third_party/ycmd/ycmd")) + #+END_SRC + Note that no filename expansions are done, so =~=-paths will not work out of the box. + If you need expansions, you can use Emacs's =file-truename= like this: + #+BEGIN_SRC emacs-lisp + (setq ycmd-server-command (list "python" (file-truename "~/some/path"))) + #+END_SRC +3) By default, spacemacs configures ycmd for getting the compilation flags from either + a compile_commands.json or a .clang_complete file and get additionnal flags from a + .ycm_extra_flags file. If you do not like this behaviour, you can write your own + [[https://github.com/Valloric/YouCompleteMe/blob/master/README.md#c-family-semantic-completion][.ycm_extra_conf.py file]]. See [[#configuration][Configuration]] for more details. +4) Whitelist the file by adding the following to =.spacemacs=: + #+BEGIN_SRC emacs-lisp + ;; In this example we whitelist everything in the Develop folder + (setq ycmd-extra-conf-whitelist '("~/Develop/*")) + #+END_SRC +5) The completion is not going to work automatically until we actually force it: + #+BEGIN_SRC emacs-lisp + (setq ycmd-force-semantic-completion t) + #+END_SRC + + +** Other Requirements +This package requires the =auto-completion= layer in order to get actual +completion. The =syntax-checking= layer is required for flycheck support. + +* Configuration + +** Activating ycmd in a major mode +By default this layer only activates ycmd for =c++-mode= and =c-mode=. + +If you want ycmd support in other modes you might just want to add it for +specific languages like: + +#+BEGIN_SRC emacs-lisp +(add-hook 'c++-mode-hook 'ycmd-mode) +#+END_SRC + +** Getting the compilation flags + +Spacemacs uses its own ycmd global configuration file. If you prefer, you can +write your own [[https://github.com/Valloric/YouCompleteMe/blob/master/README.md#c-family-semantic-completion][.ycm_extra_conf.py]]. + +Spacemacs will search for a compile_command.json or fall back to a +.clang_complete file in all parent directories of the current translation unit. +Spacemacs will try to make up for missing files in the compile_commands.json +using heuristics described in global_conf.py. + +The user can provide additionnal flags by writing a .ycm_extra_flags in any +parent directory of the current translation unit. This is particularly useful +when cross-compiling. + +Example .ycm_extra_flags: + +#+BEGIN_SRC conf +# Additionnal flags for ycmd +--sysroot="/path/to/your/toolchain/libc" # if you are cross-compiling +#+END_SRC + +If your build system doesn't handle the creation of a compile_commands.json, +you can use tools such as [[https://github.com/rizsotto/Bear][Bear]] or [[https://pypi.python.org/pypi/scan-build][scan-build]] to generate it, which both work +with almost any build system. + +* Key Bindings + +Adds ~SPC m g g~ go to definition binding to =c++-mode= as well as ~SPC m g G~ +for the more imprecise but faster version. diff --git a/layers/+tools/ycmd/global_conf.py b/layers/+tools/ycmd/global_conf.py new file mode 100644 index 0000000..d348949 --- /dev/null +++ b/layers/+tools/ycmd/global_conf.py @@ -0,0 +1,283 @@ +# global_conf.py --- ycmd global configuration file for Spacemacs +# +# Copyright (c) 2012-2016 Sylvain Benner & Contributors +# +# Author: Thomas de Beauchene +# URL: https://github.com/syl20bnr/spacemacs +# +# This file is not part of GNU Emacs. +# +# License: GPLv3 +# +# This script tries to get the compilation flags for a translation unit using +# the following logic: +# +# 1) If there is a compile_commands.json in a parent directory: +# a) If the file is a header file: +# - search for the header file itself in db +# - search for a sibling source file in the same directory (i.e. a source +# file with the same name but different extension) +# - search for a source file that includes our header's path +# - search for the nearest source file in db +# +# b) If the file is a source file: +# - search for the source file itself +# - search for the nearest source file in db +# +# 2) If no compile_commands.json, search for a .clang_complete: +# - get flags from .clang_complete +# +# 3) Always try to add extra flags from a .ycm_extra_flags file in a parent +# directory. (like --sysroot="/path/to/your/toolchain/libc" if you are cross-compiling) +# +# Thanks to Jonas Devlieghere and Gabor Marton for their work on which this code is based. +# https://jonasdevlieghere.com/a-better-youcompleteme-config/ +# https://github.com/martong/ycm_extra_conf.jsondb + +import itertools +import json +import logging +import os +import os.path +import re +import ycm_core + +SOURCE_EXTENSIONS = ['.cpp', '.cxx', '.cc', '.c', '.m', '.mm', + '.CPP', '.CXX', '.CC', '.C', '.M', '.MM'] +HEADER_EXTENSIONS = ['.h', '.hxx', '.hpp', '.hh' + '.H', '.HXX', '.HPP', '.HH'] + +# This function is called by ycmd. +def FlagsForFile(filename): + logging.info("%s: Getting flags for %s" % (__file__, filename)) + root = os.path.realpath(filename) + flags = FlagsFromCompilationDatabase(root, filename) + if not flags: + flags = FlagsFromClangComplete(root, filename) + extra_flags = GetUserExtraFlags(filename) + if extra_flags: + if flags: + flags += extra_flags + else: + flags = extra_flags + if flags: + flags = [ flag for flag in flags if not flag.startswith("-m") ] # strip -m flags + logging.info("%s: Flags = [\n\t\t%s\n]" + % (os.path.basename(filename), "\n\t\t".join(flags))) + else: + flags = [] + logging.error("%s: No flags were found !" % (os.path.basename(filename))) + return { 'flags': flags, 'do_cache': True } + +def FlagsFromClangComplete(root, filename): + try: + clang_complete_path = FindNearest(root, '.clang_complete', filename) + clang_complete_flags = open(clang_complete_path, 'r').read().splitlines() + logging.info("%s: Using %s" % (os.path.basename(filename), clang_complete_path)) + return MakeRelativePathsInFlagsAbsolute(clang_complete_flags, + os.path.dirname(clang_complete_path)) + except: + return None + +def FlagsFromCompilationDatabase(root, filename): + try: + database_path = FindNearest(root, 'compile_commands.json', filename) + database = ycm_core.CompilationDatabase(os.path.dirname(database_path)) + if not database: + logging.info("%s: Compilation database file found but unable to load" + % os.path.basename(filename)) + return None + extension = os.path.splitext(filename)[1] + if extension in HEADER_EXTENSIONS: + flags = GetFlagsForHeader(database_path, database, filename) + else: + flags = GetFlagsForSourceFile(database_path, database, filename) + if not flags: + logging.info("%s: No compilation info for %s in compilation database" + % (os.path.basename(filename), filename)) + return None + return MakeRelativePathsInFlagsAbsolute(flags.compiler_flags_, + flags.compiler_working_dir_) + except Exception as e: + logging.info("%s: Could not get compilation flags from db: %s" + % (os.path.basename(filename), e)) + return None + +def GetFlagsForHeader(database_path, database, filename): + flags = FindFileInDb(database, filename) + if flags: + return flags + flags = FindSiblingFileForHeader(database, filename) + if flags: + return flags + flags = SearchForTranslationUnitWhichIncludesPath(database_path, + database, + os.path.dirname(filename), + filename) + if flags: + return flags + return FindNearestSourceFileInDb(database_path, database, filename) + +def GetFlagsForSourceFile (database_path, database, filename): + flags = FindFileInDb(database, filename) + if flags: + return flags + return FindNearestSourceFileInDb(database_path, database, filename) + +def FindNearest(path, target, filename): + candidate = os.path.join(path, target) + if(os.path.isfile(candidate) or os.path.isdir(candidate)): + logging.info("%s: Found nearest %s at %s" + % (os.path.basename(filename), target, candidate)) + return candidate + else: + parent = os.path.dirname(os.path.abspath(path)) + if(parent == path): + raise RuntimeError("could not find %s" % target) + return FindNearest(parent, target, filename) + +def FindFileInDb(database, filename): + logging.info("%s: Trying to find file in database..." + % (os.path.basename(filename))) + flags = database.GetCompilationInfoForFile(filename) + if flags.compiler_flags_: + logging.info("%s: Found file in database." + % (os.path.basename(filename))) + return flags + logging.info("%s: File not found in compilation db." + % (os.path.basename(filename))) + return None + +def FindSiblingFileForHeader(database, filename): + logging.info("%s: Trying to find a sibling source file for that header in database..." + % (os.path.basename(filename))) + basename = os.path.splitext(filename)[0] + for extension in SOURCE_EXTENSIONS: + replacement_file = basename + extension + if os.path.exists(replacement_file): + flags = database.GetCompilationInfoForFile(replacement_file) + if flags.compiler_flags_: + logging.info("%s: Found sibling source file: %s" + % (os.path.basename(filename), replacement_file)) + return flags + logging.info("%s: Did not find sibling source file." + % (os.path.basename(filename))) + return None + +def FindNearestSourceFileInDb(database_path, database, srcfile): + logging.info("%s: Trying to find nearest source file in database..." + % (srcfile)) + filename, flags = DoFindNearestSourceFileInDb(database_path, database, srcfile, None) + if flags: + logging.info("%s: Found nearest source file from %s: %s" + % (os.path.basename(srcfile), srcfile, filename)) + return flags + logging.info("%s: Could not find nearest source file from %s in compilation db." + % (srcfile, srcfile)) + return None + +# Search subdirectories recursively, then do the same recursively for parent +# directories until a file was found or we have searched the database's directory +def DoFindNearestSourceFileInDb(database_path, database, directory, skip): + for root, dirnames, filenames in os.walk(directory): + if os.path.basename(skip) in dirnames: + dirnames.remove(os.path.basename(skip)) + for filename in filenames: + if filename.endswith(tuple(SOURCE_EXTENSIONS)): + flags = database.GetCompilationInfoForFile(os.path.join(root, filename)) + if flags.compiler_flags_: + return os.path.join(root, filename), flags + if database_path == directory or os.path.dirname(directory) == directory: + return None, None + return DoFindNearestSourceFileInDb(database_path, database, os.path.dirname(directory), directory) + +def Pairwise(iterable): + "s -> (s0,s1), (s1,s2), (s2, s3), ..." + a, b = itertools.tee(iterable) + next(b, None) + return itertools.izip(a, b) + +def RemoveClosingSlash(path): + if path.endswith('/'): + path = path[:-1] + return path + +def SearchForTranslationUnitWhichIncludesPath(database_path, database, path, filename): + logging.info("%s: Trying to find a translation unit that includes our header's path..." + % (os.path.basename(filename))) + with open(database_path, 'r') as f: + jsonDb = json.load(f) + path = RemoveClosingSlash(os.path.abspath(path)) + found = [] + for translationUnit in jsonDb: + buildDir = translationUnit["directory"] + switches = translationUnit["command"].split() + for currentSwitch, nextSwitch in Pairwise(switches): + matchObj = re.match(r'(-I|-isystem)(.*)', currentSwitch) + includeDir = "" + isIncFlag = False + if currentSwitch == "-I" or currentSwitch == "-isystem": + includeDir = nextSwitch + isIncFlag = True + elif matchObj: + includeDir = matchObj.group(2) + isIncFlag = True + if not isIncFlag: + continue + includeDir = RemoveClosingSlash(os.path.abspath(os.path.join(buildDir, includeDir))) + # Check all the parent dirs in path + pathCopy = path + distance = 0 + while pathCopy != os.path.abspath(os.sep): + if includeDir == pathCopy: + found.append((distance, str(translationUnit["file"]))) + distance += 1 + pathCopy, tail = os.path.split(pathCopy) + found.sort() + if len(found) == 0: + logging.info("%s: Did not find translation unit which includes path %s" + % (os.path.basename(filename), path)) + return None + else: + result = found[0][1] + logging.info("%s: Found best source file which includes path: %s" + % (os.path.basename(filename), result)) + return database.GetCompilationInfoForFile(result) + +def GetUserExtraFlags(filename): + try: + extra_flags_file = FindNearest(os.path.dirname(filename), ".ycm_extra_flags", filename) + except: + logging.info("%s: No extra flags." + % (os.path.basename(filename))) + return None + with open(extra_flags_file, 'r') as f: + lines = f.readlines() + lines = [ line[0:line.find("#")].split() for line in lines ] + lines = list(itertools.chain.from_iterable(lines)) + logging.info("%s: Extra flags = [\n\t\t%s\n]" + % (os.path.basename(filename), "\n\t\t".join(lines))) + return lines + +def MakeRelativePathsInFlagsAbsolute(flags, working_directory): + if not working_directory: + return list(flags) + new_flags = [] + make_next_absolute = False + for flag in flags: + new_flag = flag + if make_next_absolute: + make_next_absolute = False + if not flag.startswith('/'): + new_flag = os.path.join(working_directory, flag) + for path_flag in [ '-isystem', '-I', '-iquote', '--sysroot=' ]: + if flag == path_flag: + make_next_absolute = True + break + if flag.startswith(path_flag): + path = flag[ len(path_flag): ] + new_flag = path_flag + os.path.join(working_directory, path) + break + if new_flag: + new_flags.append(new_flag) + return new_flags diff --git a/layers/+tools/ycmd/packages.el b/layers/+tools/ycmd/packages.el new file mode 100644 index 0000000..560414c --- /dev/null +++ b/layers/+tools/ycmd/packages.el @@ -0,0 +1,31 @@ +(setq ycmd-packages + '( + (company-ycmd :toggle (configuration-layer/package-usedp 'company)) + (flycheck-ycmd :toggle (configuration-layer/package-usedp 'flycheck)) + ycmd + )) + +(unless (boundp 'ycmd-server-command) + (message (concat "YCMD won't work unless you set the ycmd-server-command " + "variable to the path to a ycmd install."))) + +(defun ycmd/init-company-ycmd () + (use-package company-ycmd + :defer t + :commands company-ycmd)) + +(defun ycmd/init-flycheck-ycmd () + (use-package flycheck-ycmd + :defer t + :init (add-hook 'ycmd-mode-hook 'flycheck-ycmd-setup))) + +(defun ycmd/init-ycmd () + (use-package ycmd + :defer t + :init + (progn + (unless (boundp 'ycmd-global-config) + (setq-default ycmd-global-config + (concat (configuration-layer/get-layer-path 'ycmd) + "global_conf.py"))) + (setq-default ycmd-parse-conditions '(save mode-enabled))))) diff --git a/layers/+vim/evil-cleverparens/README.org b/layers/+vim/evil-cleverparens/README.org new file mode 100644 index 0000000..f6d0102 --- /dev/null +++ b/layers/+vim/evil-cleverparens/README.org @@ -0,0 +1,24 @@ +#+TITLE: Evil-Cleverparens layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + +* Description + +This simple layer adds the [[https://github.com/luxbock/evil-cleverparens][evil-cleverparens]] package, which overrides common +normal-mode vim commands like D, dd, c, etc. to keep parentheses balanced. See +the repository for more details. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =evil-cleverparens= to the existing =dotspacemacs-configuration-layers= list +in this file. + +Then enable it in your =user-config= function and add your desired hooks, for +example: + +#+BEGIN_SRC emacs-lisp + (spacemacs/toggle-evil-cleverparens-on) + (add-hook 'clojure-mode-hook #'evil-cleverparens-mode) +#+END_SRC diff --git a/layers/+vim/evil-cleverparens/packages.el b/layers/+vim/evil-cleverparens/packages.el new file mode 100644 index 0000000..fec9f2d --- /dev/null +++ b/layers/+vim/evil-cleverparens/packages.el @@ -0,0 +1,24 @@ +;;; packages.el --- evil-cleverparens Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq evil-cleverparens-packages + '(evil-cleverparens)) + +(defun evil-cleverparens/init-evil-cleverparens () + (use-package evil-cleverparens + :defer t + :diminish evil-cleverparens-mode + :init + (progn + (setq evil-cleverparens-use-regular-insert t) + (spacemacs|add-toggle evil-cleverparens + :mode evil-cleverparens-mode + :documentation "Enable evil-cleverparens.")))) diff --git a/layers/+vim/evil-commentary/README.org b/layers/+vim/evil-commentary/README.org new file mode 100644 index 0000000..35b2716 --- /dev/null +++ b/layers/+vim/evil-commentary/README.org @@ -0,0 +1,32 @@ +#+TITLE: Evil-commentary layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + +* Description +This layer replaces [[https://github.com/redguardtoo/evil-nerd-commenter][evil-nerd-commenter]] with [[https://github.com/linktohack/evil-commentary][evil-commentary]] for those +who prefer the behaviour of [[https://github.com/tpope/vim-commentary][vim-commentary]]. + +- Use ~gcc~ to comment out a line (takes a count), +- ~gc~ to comment out the target of a motion (for example, +- ~gcap~ to comment out a paragraph), ~gc~ in visual + mode to comment out the selection. + +For more details see the [[https://github.com/linktohack/evil-commentary][evil-commentary]] repository. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =evil-commentary= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key bindings + +| Key Binding | Description | +|-------------+-------------------------------| +| ~SPC ;~ | comment operator | +| ~gcc~ | comment current line | +| ~gcap~ | comment paragraphs | +| ~gc SPC y~ | comment up to a line with avy | +| ~gy~ | comment and yank | diff --git a/layers/+vim/evil-commentary/packages.el b/layers/+vim/evil-commentary/packages.el new file mode 100644 index 0000000..ededb1a --- /dev/null +++ b/layers/+vim/evil-commentary/packages.el @@ -0,0 +1,23 @@ +;;; packages.el --- evil-commentary Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq evil-commentary-packages + '(evil-commentary + (evil-nerd-commenter :excluded t) + )) + +(defun evil-commentary/init-evil-commentary () + (use-package evil-commentary + :diminish evil-commentary-mode + :init + (progn + (evil-commentary-mode) + (spacemacs/set-leader-keys ";" 'evil-commentary)))) diff --git a/layers/+vim/evil-snipe/README.org b/layers/+vim/evil-snipe/README.org new file mode 100644 index 0000000..a99af8c --- /dev/null +++ b/layers/+vim/evil-snipe/README.org @@ -0,0 +1,99 @@ +#+TITLE: Evil-snipe layer + +[[file:img/Cat_With_Rifle.jpg]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#improved-f-and-t-search-behavior][Improved f and t search behavior]] + - [[#two-character-search-with-s][Two-character search with s]] + - [[#more-scopes][More scopes]] + - [[#symbol-groups][Symbol groups]] + - [[#key-bindings][Key bindings]] + +* Description +The package [[https://github.com/hlissner/evil-snipe][evil-snipe]] +- enables more efficient searches with ~f~ / ~F~ / ~t~ / ~T~. +- adds a new, more precise search with ~s/S~ + +Evil-snipe allows you to search more quickly and precisely in the buffer. It +does so by improving on the built in ~f~ / ~F~ / ~t~ / ~T~ searches and adding another +search command, namely ~s~ / ~S~. + +=evil-snipe= changes ~s/S~ behavior in order to search forward/backwards in the +buffer with two chars. + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =evil-snipe= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** Improved f and t search behavior +With evil-snipe you can define your own search scope for ~f~ and ~t~ searches +which means that you won't have to jump to the correct line before searching +with ~f~ / ~t~ / ~F~ / ~T~. And after you have found a match, you can just press +~f~ or ~t~ again afterwards to continue the search. No need to use ~;~ / ~​,​~. + +This alternate behavior is disabled by default, to enable it set the +layer variable =evil-snipe-enable-alternate-f-and-t-behaviors= to =t=: + +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers + '((evil-snipe :variables evil-snipe-enable-alternate-f-and-t-behaviors t))) +#+END_SRC + +** Two-character search with s +With the ~s~/~S~ keys you can do a simple search like ~f~/~t~, but instead of +searching for one character, you search for two. This makes the search a lot +more precise than regular ~f~/~t~ searches. While you can search forward or +backwards in the buffer with ~/~ and ~?~, ~s~ / ~S~ are much easier to reach, +don't require you to press enter and they are precise enough for many common +purposes. + +** More scopes +Evil-snipe also adds several scope options for searches (set =evil-snipe-scope= +and =evil-snipe-repeat-scope= to one of these, the default value is =buffer=): + +| Value | Description | +|---------------+--------------------------------------------------------------------------| +| buffer | search in the rest of the buffer after the cursor (=vim-sneak= behavior) | +| line | search in the current line after the cursor (=vim-seek= behavior) | +| visible | search in the rest of the visible buffer only | +| whole-line | same as =line=, but highlight matches on either side of cursor | +| whole-buffer | same as =buffer=, but highlight *all* matches in buffer | +| whole-visible | same as 'visible, but highlight *all* visible matches in buffer | + +If you do not want to replace the regular ~f~ / ~F~ / ~t~ / ~T~ behavior, just +remove this line from =evil-snipe/packages.el=: +=(evil-snipe-replace-evil)= + +** Symbol groups +With symbol groups you can let a character stand for a regex, for example a +group of characters. By adding a pair of =(CHAR REGEX)= to the list +=evil-snipe-aliases= you can search for a regex very simply: + +- Here we set the ~[~ character to mean =all characters [({= *in all modes* so a + search with ~sa[~ would find ~a[~, ~a{~ or ~a(~. + +#+BEGIN_SRC emacs-lisp + ;; Alias [ and ] to all types of brackets + (push '(?\[ "[[{(]") evil-snipe-aliases) + (push '(?\] "[]})]") evil-snipe-aliases) +#+END_SRC + +- Here we set the char ~:~ to mean =a regex matching python function + definitions= (but only in python-mode), so by searching with ~f:fff~ you can + quickly cycle through all function definitions in a buffer! + +#+BEGIN_SRC emacs-lisp + ;; For python style functions + (add-hook 'python-mode-hook + (lambda () + (make-variable-buffer-local 'evil-snipe-aliases) + (push '(?: "def .+:") evil-snipe-aliases))) +#+END_SRC + +* TODO Key bindings + diff --git a/layers/+vim/evil-snipe/config.el b/layers/+vim/evil-snipe/config.el new file mode 100644 index 0000000..837744c --- /dev/null +++ b/layers/+vim/evil-snipe/config.el @@ -0,0 +1,15 @@ +;;; config.el --- evil-snipe Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(defvar evil-snipe-enable-alternate-f-and-t-behaviors nil + "if non nil f/F/t/T behaviors are replaced by evil-snipe behavior.") diff --git a/layers/+vim/evil-snipe/img/Cat_With_Rifle.jpg b/layers/+vim/evil-snipe/img/Cat_With_Rifle.jpg new file mode 100644 index 0000000..185a84b Binary files /dev/null and b/layers/+vim/evil-snipe/img/Cat_With_Rifle.jpg differ diff --git a/layers/+vim/evil-snipe/packages.el b/layers/+vim/evil-snipe/packages.el new file mode 100644 index 0000000..9926840 --- /dev/null +++ b/layers/+vim/evil-snipe/packages.el @@ -0,0 +1,37 @@ +(setq evil-snipe-packages + '( + evil-snipe + magit + ranger + )) + +(defun evil-snipe/init-evil-snipe () + (use-package evil-snipe + :diminish evil-snipe-local-mode + :init + (setq evil-snipe-scope 'whole-buffer + evil-snipe-enable-highlight t + evil-snipe-enable-incremental-highlight t + evil-snipe-auto-disable-substitute t + evil-snipe-show-prompt nil + evil-snipe-smart-case t) + :config + (progn + (if evil-snipe-enable-alternate-f-and-t-behaviors + (progn + (setq evil-snipe-repeat-scope 'whole-buffer) + (evil-snipe-override-mode 1)) + (evil-snipe-mode 1))))) + +(defun evil-snipe/post-init-magit () + (if evil-snipe-enable-alternate-f-and-t-behaviors + (progn + (add-hook 'magit-mode-hook 'turn-off-evil-snipe-override-mode) + (add-hook 'git-rebase-mode-hook 'turn-off-evil-snipe-override-mode)) + (add-hook 'magit-mode-hook 'turn-off-evil-snipe-mode) + (add-hook 'git-rebase-mode-hook 'turn-off-evil-snipe-mode))) + +(defun evil-snipe/post-init-ranger () + (if evil-snipe-enable-alternate-f-and-t-behaviors + (add-hook 'ranger-mode-hook 'turn-off-evil-snipe-override-mode) + (add-hook 'ranger-mode-hook 'turn-off-evil-snipe-mode))) diff --git a/layers/+vim/vim-empty-lines/README.org b/layers/+vim/vim-empty-lines/README.org new file mode 100644 index 0000000..12434c1 --- /dev/null +++ b/layers/+vim/vim-empty-lines/README.org @@ -0,0 +1,22 @@ +#+TITLE: Vim-empty-lines layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + +* Description + +This layer is a drop-in replacement for the =vi-tilde-fringe= mode, for those +who desire behaviour closer to =vim='s. + +It has better compatibility with retina displays, as it uses a text overlay +using your font, rather than a pixel-art tilde. The empty line indicators are +overlaid in within the buffer as in =vim=, and not in the fringe. The indicator +behaviour with trailing empty lines matches =vim='s behaviour. + +For details, see the [[https://github.com/jmickelin/vim-empty-lines-mode][vim-empty-lines-mode]] repository. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =vim-empty-lines= to the existing =dotspacemacs-configuration-layers= list in this +file. diff --git a/layers/+vim/vim-empty-lines/local/vim-empty-lines-mode/vim-empty-lines-mode.el b/layers/+vim/vim-empty-lines/local/vim-empty-lines-mode/vim-empty-lines-mode.el new file mode 100644 index 0000000..1ce08ba --- /dev/null +++ b/layers/+vim/vim-empty-lines/local/vim-empty-lines-mode/vim-empty-lines-mode.el @@ -0,0 +1,287 @@ +;;; vim-empty-lines-mode.el --- Vim-like empty line indicator at end of files. + +;; Copyright (C) 2015 Jonne Mickelin + +;; Author: Jonne Mickelin +;; Created: 06 Jan 2015 +;; Version: 0.1 +;; Keywords: emulations +;; URL: https://github.com/jmickelin/vim-empty-lines-mode +;; Package-Requires: ((emacs "23")) + +;; 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 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 this program. If not, see . + +;;; Commentary: + +;; This mode emulates the way that vim indicates the end of a file, +;; that is by putting a "tilde" character (~) on any empty line that +;; follows the end of file. + +;; Emacs provides a similar functionality that inserts a bitmap in the +;; fringe on the extraneous lines. By customizing +;; `indicate-empty-lines' and `fringe-indicator-alist' it is possible +;; to nearly emulate the vim behaviour. + +;; However, there is a slight difference in what the two editors +;; consider to be "empty lines". + +;; A line in vim can be considered to contain the newline character +;; that ended the previous line, as well as the other visible +;; characters. Equivalently, a line is empty only if it contains no +;; text and the previous line has no trailing whitespace. + +;; Example: + +;; foo <- not empty +;; \nbar <- not empty +;; \n <- not empty +;; ~ <- empty +;; ~ <- empty +;; +;; foo <- not empty +;; \nbar <- not empty +;; ~ <- empty +;; ~ <- empty + +;; A line in emacs, on the other hand, will contain the newline +;; character that breaks it. Thus a line is empty even if the previous +;; line has a trailing linebreak. + +;; Example: + +;; foo\n <- not empty +;; bar\n <- not empty +;; ~ <- empty +;; ~ <- empty +;; ; +;; foo\n <- not empty +;; bar <- not empty +;; ~ <- empty +;; ~ <- empty + +;; Note that Emacs displays the two cases identically! + +;; There is currently (as of Emacs 24.4) no way to implement the +;; vim-like behaviour for `indicate-empty-lines' short of modifying +;; the Emacs core. + +;; This module emulates the vim-like behaviour using a different +;; approach, namely by inserting at the end of the buffer a read-only +;; overlay containing the indicators for the empty lines. This has the +;; added advantage that it's trivial to customize the indicator to an +;; arbitrary string, and customize its text properties. + +;; To enable `vim-empty-lines-mode' in a buffer, run +;; (vim-empty-lines-mode) + +;; To enable it globally, run +;; (global-vim-empty-lines-mode) + +;; The string that indicates an empty line can be customized, e.g. +;; (setq vim-empty-lines-indicator "**********************") + +;; The face that is used to display the indicators is `vim-empty-lines-face'. + +;;; Code: + +(defgroup vim-empty-lines-mode + nil + "Vim-like empty line indicators." + :group 'emulations + :prefix "vim-empty-lines") + +(defface vim-empty-lines-face + '((t (:inherit font-lock-comment-face))) + "Face for empty lines in `vim-empty-lines-mode'." + :group 'vim-empty-lines-mode) + +(defcustom vim-empty-lines-indicator "~" + "String to display on lines following end-of-buffer in `vim-empty-lines-mode'. + +Must not contain '\\n'." + :group 'vim-empty-lines-mode) + +(defvar vim-empty-lines-overlay nil + "Overlay that displays the empty line indicators.") +(put 'vim-empty-lines-overlay 'permanent-local t) + +(defun vim-empty-lines-create-overlay () + (setq-local vim-empty-lines-overlay (make-overlay (point-max) + (point-max) + nil + t t)) + (overlay-put vim-empty-lines-overlay 'window t)) + +(defun vim-empty-lines-count-screen-lines (beg end &optional max) + "Return the number of screen lines in the region. + +Taken from `count-screen-lines' and quite stripped down. +Unlike `count-screen-lines', calls `vertical-motion' with MAX as the +argument for efficiencies. It is too expensive calling `vertical-motion' +with `buffer-size' if the buffer is large." + (let (count-final-newline + window) + (if (= beg end) + 0 + (save-excursion + (save-restriction + (widen) + (narrow-to-region (min beg end) + (if (and (not count-final-newline) + (= ?\n (char-before (max beg end)))) + (1- (max beg end)) + (max beg end))) + (goto-char (point-min)) + (1+ (vertical-motion (or max (buffer-size)) ; XXX: changed + window))))))) + +(defun vim-empty-lines-nlines-after-buffer-end (window &optional window-start) + (with-current-buffer (window-buffer window) + (if (and window-start ;; chance to optimize for some cases. + (or (and (window-end) (= (point-max) (window-end))) + (not (pos-visible-in-window-p (point-max) window)))) + 0 + (vim-empty-lines-nlines-after-buffer-end-aux window)))) + +(defun vim-empty-lines-nlines-after-buffer-end-aux (window) + (save-selected-window + (with-selected-window window + (with-current-buffer (window-buffer) + (let ((screen-height (- (window-height) + 1 ;; mode-line + (if header-line-format 1 0)))) + (- screen-height + (1- (vim-empty-lines-count-screen-lines + (window-start) (point-max) screen-height)))))))) + +(defun vim-empty-lines-update-overlay (&optional window window-start) + (let ((w (or window + (let ((w (selected-window))) + (and (window-valid-p w) w))))) + ;; `w' could be nil but it's ok for `window-height', `window-start' etc. + (when (overlayp vim-empty-lines-overlay) + (vim-empty-lines-update-overlay-aux + (apply 'max + (vim-empty-lines-nlines-after-buffer-end w window-start) + (mapcar 'vim-empty-lines-nlines-after-buffer-end + (remq w (get-buffer-window-list nil nil t))))) + (move-overlay vim-empty-lines-overlay (point-max) (point-max))))) + +(defun vim-empty-lines-update-overlay-aux (nlines-after-buffer-end) + (when (> nlines-after-buffer-end 1) + (save-excursion + (let ((indicators + (apply 'concat + (make-list nlines-after-buffer-end + (concat "\n" vim-empty-lines-indicator))))) + (overlay-put vim-empty-lines-overlay + 'after-string + (concat (propertize " " + ;; Forbid movement past + ;; the beginning of the + ;; after-string. + 'cursor nlines-after-buffer-end) + (propertize indicators + 'face 'vim-empty-lines-face))))))) + +(defun vim-empty-lines-update-overlay-windows () + (with-selected-frame (selected-frame) + (save-selected-window + (mapc (lambda (w) + (with-selected-window w + (vim-empty-lines-update-overlay w))) + (window-list (selected-frame) -1))))) + +(defun vim-empty-lines-hide-overlay () + (when (overlayp vim-empty-lines-overlay) + (let ((ov vim-empty-lines-overlay)) + (overlay-put ov 'invisible nil) + (overlay-put ov 'display nil) + (overlay-put ov 'after-string nil)))) + +(defvar vim-empty-lines-initialize-p nil) + +(defun vim-empty-lines-initialize-maybe () + "Setup some advices to emacs primitives for workarounds" + (unless vim-empty-lines-initialize-p + (setq vim-empty-lines-initialize-p t) + + ;; A kludge to bug#19553 + ;; fixed in b544ab561fcb575790c963a2eda51524fa366409 + ;; XXX: The fix is in the emacs-24 branch only at this time. + (unless (and (version< emacs-version "25") + (version< "24.4.51" emacs-version)) + (eval-when-compile + (defmacro vim-empty-lines-advice-add-overlay-handling (&rest functions) + `(progn + ,@(mapcar + (lambda (function) + `(defadvice ,function (around vim-empty-lines activate) + (if (not (overlayp vim-empty-lines-overlay)) + ad-do-it + (let ((inhibit-redisplay t) ;;Hope not to break anything + (p (overlay-start vim-empty-lines-overlay))) + (delete-overlay vim-empty-lines-overlay) + (unwind-protect ad-do-it + (move-overlay vim-empty-lines-overlay p p)))))) + functions)))) + + (vim-empty-lines-advice-add-overlay-handling vertical-motion + move-to-window-line)))) + +;;;###autoload +(define-minor-mode vim-empty-lines-mode + "Display `vim-empty-lines-indicator' on visible lines after the end of the buffer. + +This differs from `indicate-empty-lines' in the way that it deals +with trailing newlines." + :lighter " ~" + :global nil + (if vim-empty-lines-mode + (progn + (unless (overlayp vim-empty-lines-overlay) + (vim-empty-lines-create-overlay)) + (vim-empty-lines-initialize-maybe) + (make-local-variable 'vim-empty-lines-overlay) + (vim-empty-lines-create-overlay) + (vim-empty-lines-update-overlay) + (add-hook 'post-command-hook 'vim-empty-lines-update-overlay t) + (add-hook 'window-scroll-functions 'vim-empty-lines-update-overlay t) + (add-hook 'window-configuration-change-hook + 'vim-empty-lines-update-overlay-windows t)) + (remove-hook 'post-command-hook 'vim-empty-lines-update-overlay t) + (remove-hook 'window-scroll-functions 'vim-empty-lines-update-overlay t) + (remove-hook 'window-configuration-change-hook + 'vim-empty-lines-update-overlay-windows t) + (when (overlayp vim-empty-lines-overlay) + (delete-overlay vim-empty-lines-overlay) + (setq vim-empty-lines-overlay nil)))) + +;;;###autoload +(define-global-minor-mode global-vim-empty-lines-mode + vim-empty-lines-mode + (lambda () + (unless (or (minibufferp) + ;; Is there really no built-in function for detecting + ;; the echo area? + (string-match-p "\\*Echo Area [0-9]+\\*" (buffer-name))) + (vim-empty-lines-mode +1))) + :group 'vim-empty-lines-mode + :require 'vim-empty-lines-mode) + +(provide 'vim-empty-lines-mode) + +;;; vim-empty-lines-mode.el ends here diff --git a/layers/+vim/vim-empty-lines/packages.el b/layers/+vim/vim-empty-lines/packages.el new file mode 100644 index 0000000..252dc6f --- /dev/null +++ b/layers/+vim/vim-empty-lines/packages.el @@ -0,0 +1,34 @@ +(setq vim-empty-lines-packages + '( + (vim-empty-lines-mode :location local) + (vi-tilde-fringe :excluded t) + )) + +(defun vim-empty-lines/init-vim-empty-lines-mode () + (use-package vim-empty-lines-mode + :diminish vim-empty-lines-mode + :init + (spacemacs/add-to-hooks (lambda () (vim-empty-lines-mode -1)) + '(comint-mode-hook + eshell-mode-hook + eww-mode-hook + shell-mode-hook + term-mode-hook)) + :config + (progn + (global-vim-empty-lines-mode) + (spacemacs|add-toggle vim-empty-lines-mode + :mode global-vim-empty-lines-mode + :documentation + "Display an overlay of ~ on empty lines." + :evil-leader "t~") + ;; Don't enable it where it is detrimental. + (dolist (x (list spacemacs-buffer-name + "*Messages*")) + (with-current-buffer x (vim-empty-lines-mode -1))) + (add-hook 'which-key-init-buffer-hook (lambda () (vim-empty-lines-mode -1))) + ;; after a major mode is loaded, check if the buffer is read only + ;; if so, disable vim-empty-lines-mode + (add-hook 'after-change-major-mode-hook (lambda () + (when buffer-read-only + (vim-empty-lines-mode -1))))))) diff --git a/layers/+vim/vim-powerline/README.org b/layers/+vim/vim-powerline/README.org new file mode 100644 index 0000000..bd6b1c5 --- /dev/null +++ b/layers/+vim/vim-powerline/README.org @@ -0,0 +1,13 @@ +#+TITLE: vim-powerline layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + +* Description +A powerline theme modeled after the vim powerline theme. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =vim-powerline= to the existing =dotspacemacs-configuration-layers= list in this +file. diff --git a/layers/+vim/vim-powerline/local/vim-powerline/vim-colors.el b/layers/+vim/vim-powerline/local/vim-powerline/vim-colors.el new file mode 100644 index 0000000..dd25693 --- /dev/null +++ b/layers/+vim/vim-powerline/local/vim-powerline/vim-colors.el @@ -0,0 +1,188 @@ +;; The colors in this file are from the original vim-powerline +;; repository at https://github.com/Lokaltog/vim-powerline/blob/develop/autoload/Powerline/Colorschemes/default.vim + +(defun powerline--expand-alist (alist) + (cl-loop for (keys . vals) in alist append + (mapcar #'(lambda (key) (cons key vals)) keys))) + +(defun powerline--build-face (fg &optional bg bold) + `((t (:foreground ,fg + :background ,bg + :bold ,bold + :overline ,(when (null powerline-default-separator) bg) + :underline nil + :box ,(when (eq powerline-default-separator 'utf-8) bg))))) + +(defun powerline--gen-facedef (feature mode args) + (let* ((name (format "powerline-%s-%s" feature mode)) + (doc (format "Powerline face %s" name))) + `(defface ,(intern name) + (quote ,(apply 'powerline--build-face args)) + ,doc))) + +(defun powerline--generate-facedefs (alist) + (cl-loop for (feature . modes) in alist append + (cl-loop for (mode . args) in modes collect + (powerline--gen-facedef feature mode args)))) + +;; Color definitions +(setf powerline-vim-colors-alist + (let ((black "#000000") ; 16 + (white "#FFFFFF") ; 231 + + (darkestgreen "#005F00") ; 22 + (darkgreen "#008700") ; 28 + (mediumgreen "#5faf00") ; 70 + (brightgreen "#afd700") ; 148 + + (darkestcyan "#005f5f") ; 23 + (mediumcyan "#87d7ff") ; 117 + + (darkestblue "#005f87") ; 24 + (darkblue "#0087af") ; 31 + + (darkestred "#5f0000") ; 52 + (darkred "#870000") ; 88 + (mediumred "#af0000") ; 124 + (brightred "#d70000") ; 160 + (brightestred "#ff0000") ; 196 + + (darkestpurple "#5f00af") ; 55 + (mediumpurple "#875fd7") ; 98 + (brightpurple "#d7d7ff") ; 189 + + (brightorange "#ff8700") ; 208 + (brightestorange "#ffaf00") ; 214 + + (gray0 "#121212") ; 233 + (gray1 "#262626") ; 235 + (gray2 "#303030") ; 236 + (gray3 "#4e4e4e") ; 239 + (gray4 "#585858") ; 240 + (gray5 "#626262") ; 241 + (gray6 "#808080") ; 244 + (gray7 "#8a8a8a") ; 245 + (gray8 "#9e9e9e") ; 247 + (gray9 "#bcbcbc") ; 250 + (gray10 "#d0d0d0")) ; 252 + + (powerline--expand-alist + `((("SPLIT") + (normal ,white ,gray2) + (inactive ,white ,gray0) + (insert ,white ,darkestblue)) + + (("state_indicator") + (normal ,darkestgreen ,brightgreen t) + ;;(inactive ,gray6 ,gray2 t) + (insert ,darkestcyan ,white t) + (visual ,darkred ,brightorange t) + (replace ,white ,brightred t) + (select ,white ,gray5 t) + (motion ,brightpurple ,mediumpurple t) + (emacs ,darkestcyan ,white t) + (iedit ,darkred ,brightestred t) + (lisp ,brightpurple ,mediumpurple t)) + + (("branch" "scrollpercent" "raw" "filesize") + (normal ,gray9 ,gray4) + (inactive ,gray4 ,gray1) + (insert ,mediumcyan ,darkblue)) + + (("fileinfo" "filename") + (normal ,white ,gray4 t) + (inactive ,gray7 ,gray1 t) + (insert ,white ,darkblue t)) + + (("fileinfo.filepath") + (normal ,gray10) + (inactive ,gray5) + (insert ,mediumcyan)) + + (("static_str") + (normal ,white ,gray4) + (inactive ,gray7 ,gray1) + (insert ,white ,darkblue)) + + (("fileinfo.flags") + (normal ,brightestred nil t) + (inactive ,darkred) + (insert ,brightestred nil t)) + + (("currenttag" "fullcurrenttag" "fileformat" "fileencoding" + "pwd" "filetype" "rvm.string" "rvm.statusline" + "virtualenv.statusline" "charcode" "currhigroup") + (normal ,gray8 ,gray2) + (inactive ,gray3 ,gray0) + (insert ,mediumcyan ,darkestblue)) + + (("lineinfo") + (normal ,gray2 ,gray10 t) + (inactive ,gray7 ,gray1 t) + (insert ,darkestcyan ,mediumcyan t)) + + (("errors") + (normal ,brightestorange ,gray2 t) + (insert ,brightestorange ,darkestblue t)) + + (("lineinfo.line.tot") + (normal ,gray6) + (inactive ,gray5) + (insert ,darkestcyan)) + + (("paste_indicator" "ws_marker") + (normal ,white ,brightred t)) + + (("gundo.static_str.name" "command_t.static_str.name") + (normal ,white ,mediumred t) + (inactive ,brightred ,darkestred t)) + + (("gundo.static_str.buffer" "command_t.raw.line") + (normal ,white ,darkred) + (inactive ,brightred ,darkestred)) + + (("gundo.SPLIT" "command_t.SPLIT") + (normal ,white ,darkred) + (inactive ,white ,darkestred)) + + (("lustyexplorer.static_str.name" + "minibufexplorer.static_str.name" + "nerdtree.raw.name" "tagbar.static_str.name") + (normal ,white ,mediumgreen t) + (inactive ,mediumgreen ,darkestgreen t)) + + (("lustyexplorer.static_str.buffer" + "tagbar.static_str.buffer") + (normal ,brightgreen ,darkgreen) + (inactive ,mediumgreen ,darkestgreen)) + + (("lustyexplorer.SPLIT" "minibufexplorer.SPLIT" + "nerdtree.SPLIT" "tagbar.SPLIT") + (normal ,white ,darkgreen) + (inactive ,white ,darkestgreen)) + + (("ctrlp.focus" "ctrlp.byfname") + (normal ,brightpurple ,darkestpurple)) + + (("ctrlp.prev" "ctrlp.next" "ctrlp.pwd") + (normal ,white ,mediumpurple)) + + (("ctrlp.item") + (normal ,darkestpurple ,white t)) + + (("ctrlp.marked") + (normal ,brightestred ,darkestpurple t)) + + (("ctrlp.count") + (normal ,darkestpurple ,white)) + + (("ctrlp.SPLIT") + (normal ,white ,darkestpurple)))))) + +(provide 'vim-colors) +;; Local Variables: +;; no-byte-compile: t +;; eval: (when (fboundp 'rainbow-mode) (rainbow-mode 1)) +;; indent-tabs-mode: nil +;; End: +;;; vim-colors.el ends here diff --git a/layers/+vim/vim-powerline/local/vim-powerline/vim-powerline-theme.el b/layers/+vim/vim-powerline/local/vim-powerline/vim-powerline-theme.el new file mode 100644 index 0000000..57f5baa --- /dev/null +++ b/layers/+vim/vim-powerline/local/vim-powerline/vim-powerline-theme.el @@ -0,0 +1,176 @@ +;;; powerline-themes.el --- Themes for Powerline + +;; Copyright (C) 2012-2013 Donald Ephraim Curtis +;; Copyright (C) 2013 Jason Milkins +;; Copyright (C) 2012 Nicolas Rougier + +;; Author: Donald Ephraim Curtis +;; URL: http://github.com/milkypostman/powerline/ +;; Version: 2.0 +;; Keywords: mode-line + +;;; Commentary: +;; +;; Themes for Powerline. +;; Included themes: default, center, center-evil, vim, and nano. +;; + +;;; Code: + +(require 'cl-lib) + +(defface powerline-active3 '((t (:background "#afd700" + :foreground "#008700" + :inherit mode-line))) + "Powerline face 3." + :group 'powerline) + +(defface powerline-inactive3 '((t (:foreground "grey90" :background "grey30" :inherit mode-line))) + "Powerline face 3." + :group 'powerline) + +(defun check-in-list (list elems) + (catch 'tag + (dolist (elem elems) + (if (member elem list) + (throw 'tag elem))))) + +;; Get a face for the current input mode and +;; desired feature. Defaults to "powerline-FEATURE-normal" +(defun pl/get-vim-face (face) + "Find whether or not FACE is a valid face, +and if not, try to get the corresponding +'-normal' face " + (let* ((face (replace-regexp-in-string "iedit-insert" "iedit" face)) + (split-face-name nil) (concat-face-name nil) ; some variables we'll use later on + (report-wrong-prefix ; Our error reporter. Because we don't want to return nil. + (lambda () (let ((prefix (subseq (or split-face-name (split-string face "-")) 0 2))) + (error "There's no vim face with the prefix: %s" + (mapconcat 'identity prefix "-")))))) + + (cond ((facep face) ; If our face is a FACE (even if it's not a powerline face) + (intern face)) ; just intern the string and send it back + + ;; Otherwise. + ;; Are we a list of only three items? + ;; Is the first item a string that is 'powerline'? + ;; Is the last element not 'normal'? (If it was valid, it would have already passed) + ((and (setf split-face-name (split-string face "-")) + (string-equal (cl-first split-face-name) "powerline") + (not (string-equal (cl-third split-face-name) "normal"))) + + ;; If we passed all the tests above, then we try to create a valid + ;; powerline-face symbol + (progn + (setf (cl-third split-face-name) "normal") + + ;; Re-build our string from the split pieces + (setf concat-face-name (mapconcat 'identity split-face-name "-")) + + ;; And do one final check to make sure it's a face + ;; before sending it off + ;; (message "Concatenated name: %s" concat-face-name) + (if (facep concat-face-name) + (intern concat-face-name) + (report-wrong-prefix)))) + + ;; Always fallthrough to the error + (t (report-wrong-prefix))))) + + +(defmacro pl/vim-face (name state) + `(pl/get-vim-face (format "powerline-%s-%s" ,name ,state))) + +(require 'vim-colors) +(defun powerline-vimish-theme () + "Setup the default mode-line." + ;; Populate our faces + (mapcar 'eval (powerline--generate-facedefs powerline-vim-colors-alist)) + (set-face-attribute 'mode-line-inactive nil + :background (face-background (pl/vim-face "SPLIT" "inactive")) :underline nil + :overline nil :box nil) + (interactive) + (setq-default mode-line-format + '("%e" + (:eval + (let* ((active (powerline-selected-window-active)) + (harddiv-left (intern (format "powerline-%s-%s" + (powerline-current-separator) + (car powerline-default-separator-dir)))) + (harddiv-right (intern (format "powerline-%s-%s" + (powerline-current-separator) + (cdr powerline-default-separator-dir)))) + (softdiv-left (cl-case powerline-default-separator + ((utf-8 arrow) "") + ((bar nil) "|") + (brace "}") + (t ">"))) + (softdiv-right (cl-case powerline-default-separator + ((utf-8 arrow) "") + ((bar nil) "|") + (brace "{") + (t "<"))) + (editor-state (cond ((and active (boundp 'evil-mode) evil-mode) + (symbol-name evil-state)) + (active "active") + (t "inactive"))) + (state-indicator-face (pl/vim-face "state_indicator" editor-state)) + (vc-face (pl/vim-face "branch" editor-state)) + (fileinfo-face (pl/vim-face "fileinfo" editor-state)) + (split-face (pl/vim-face "SPLIT" editor-state)) + + (fileformat-face (pl/vim-face "fileformat" editor-state)) + (fileencoding-face (pl/vim-face "fileencoding" editor-state)) + (filetype-face (pl/vim-face "filetype" editor-state)) + + (scrollpercent-face (pl/vim-face "scrollpercent" editor-state)) + (lineinfo-face (pl/vim-face "lineinfo" editor-state)) + + (input (split-string (symbol-name buffer-file-coding-system) "-")) + (platform (check-in-list input '("mac" "unix" "dos"))) + (encoding (mapconcat 'identity (delete platform input) "-")) + + ;; Left hand side + (lhs (list + (powerline-raw (format " %s " (upcase editor-state)) state-indicator-face) + (funcall harddiv-left state-indicator-face vc-face) + (when (and (buffer-file-name (current-buffer)) vc-mode) + (concat + (powerline-raw (downcase (format-mode-line '(vc-mode vc-mode))) vc-face 'r) + (powerline-raw softdiv-left vc-face))) + (powerline-buffer-id fileinfo-face 'l) + (powerline-raw "%*" fileinfo-face 'lr) + (powerline-narrow fileinfo-face 'l) + (funcall harddiv-left fileinfo-face split-face))) + + ;; Right Hand Side + (rhs (list + (powerline-raw global-mode-string split-face 'r) + (funcall harddiv-right split-face fileformat-face) + (concat + (when (not (null platform)) + (concat (powerline-raw platform fileformat-face 'r) + (powerline-raw softdiv-right fileformat-face))) + (powerline-raw encoding fileencoding-face 'lr) + (powerline-raw softdiv-right fileencoding-face)) + (powerline-major-mode filetype-face 'lr) + (funcall harddiv-right filetype-face scrollpercent-face) + (powerline-raw "%p" scrollpercent-face 'lr) + (funcall harddiv-right scrollpercent-face lineinfo-face) + (powerline-raw "%l" lineinfo-face 'l) + (powerline-raw ":" lineinfo-face 'lr) + (powerline-raw "%c" lineinfo-face 'r)))) + + (when active + (set-face-attribute 'mode-line nil :underline nil :overline nil :box nil)) + (if (and (null powerline-default-separator) + (null (face-attribute 'powerline-SPLIT-normal :overline))) + nil + nil) + (concat (powerline-render lhs) + (powerline-fill split-face (powerline-width rhs)) + (powerline-render rhs))))))) + +(provide 'vim-powerline-theme) + +;;; powerline-themes.el ends here diff --git a/layers/+vim/vim-powerline/packages.el b/layers/+vim/vim-powerline/packages.el new file mode 100644 index 0000000..0a8d29e --- /dev/null +++ b/layers/+vim/vim-powerline/packages.el @@ -0,0 +1,43 @@ +(setq vim-powerline-packages + '( + powerline + (vim-powerline :location local) + )) + +(defun vim-powerline/init-powerline ()) + +(defun vim-powerline/init-vim-powerline () + (require 'powerline) + (if (display-graphic-p) + (setq powerline-default-separator 'arrow) + (setq powerline-default-separator 'utf-8)) + + (defun powerline-raw (str &optional face pad) + "Render STR as mode-line data using FACE and optionally +PAD import on left (l) or right (r) or left-right (lr)." + (when str + (let* ((rendered-str (format-mode-line str)) + (padded-str (concat + (when (and (> (length rendered-str) 0) + (or (eq pad 'l) (eq pad 'lr))) " ") + (if (listp str) rendered-str str) + (when (and (> (length rendered-str) 0) + (or (eq pad 'r) (eq pad 'lr))) " ")))) + + (if face + (pl/add-text-property padded-str 'face face) + padded-str)))) + + (require 'vim-powerline-theme) + (powerline-vimish-theme) + + (defun spacemacs//set-vimish-powerline-for-startup-buffers () + "Set the powerline for buffers created when Emacs starts." + (dolist (buffer '("*Messages*" "*spacemacs*" "*Compile-Log*")) + (when (get-buffer buffer) + (with-current-buffer buffer + (setq-local mode-line-format (default-value 'mode-line-format)) + (powerline-set-selected-window) + (powerline-reset))))) + (add-hook 'emacs-startup-hook + 'spacemacs//set-vimish-powerline-for-startup-buffers)) diff --git a/layers/+vim/vinegar/README.org b/layers/+vim/vinegar/README.org new file mode 100644 index 0000000..25939ca --- /dev/null +++ b/layers/+vim/vinegar/README.org @@ -0,0 +1,52 @@ +#+TITLE: Vinegar layer + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#mouse-bindings][Mouse bindings]] + - [[#key-bindings][Key bindings]] + +* Description +This layer is a port contribution layer for vim-vinegar for emacs. + +A port of tpope's +[[https://github.com/tpope/vim-vinegar][vinegar.vim]], simplifying =dired= +with a limited number of details and exposing the ~-~ command in all +buffers to enter dired. + +** Features +- navigation up folders with ~-~ key +- simplify dired buffer to show only file names +- better evil/vim bindings for navigation within dired buffer +- keep only one active dired buffer +- Use dired-k extension to show time / vcs related information in + single bar +- right mouse click moves up directory if in blank space or shows context menu + +** Mouse bindings + +| Mouse Binding | Description | +|---------------+-----------------------------------------------| +| ~mouse-1~ | (Dired) Open selected file | +| ~mouse-2~ | (Dired) Open clicked file in other-window | +| ~mouse-3~ | (Dired) Open context popup or go up directory | + +** Key bindings + +| Key Binding | Description | +|-------------+----------------------------------------------------| +| ~-~ | Navigate to parent directory in dired | +| ~0~ | (Dired) Move to the beginning of the file in dired | +| ~=~ | (Dired) Diff between selected files | +| ~C-j~ | (Dired) Move to next subdirectory | +| ~C-k~ | (Dired) Move to previous sbdirectory | +| ~I~ | (Dired) Toggle showing dotfiles | +| ~~~ | (Dired) Navigate to home directory | +| ~f~ | (Dired) Helm find file | +| ~J~ | (Dired) Goto file | +| ~C-f~ | (Dired) dired-find | +| ~H~ | (Dired) Show dired history | +| ~T~ | (Dired) Move down in dired tree | +| ~K~ | (Dired) Kill marked lines (hide, do not delete) | +| ~r~ | (Dired) Redisplay buffer | + diff --git a/layers/+vim/vinegar/config.el b/layers/+vim/vinegar/config.el new file mode 100644 index 0000000..0e87cd7 --- /dev/null +++ b/layers/+vim/vinegar/config.el @@ -0,0 +1,15 @@ +;;; config.el --- Vinegar Layer Configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; Variables + +(defvar vinegar-reuse-dired-buffer nil + "If non-nil, reuses one dired buffer for navigation.") diff --git a/layers/+vim/vinegar/funcs.el b/layers/+vim/vinegar/funcs.el new file mode 100644 index 0000000..7d72d40 --- /dev/null +++ b/layers/+vim/vinegar/funcs.el @@ -0,0 +1,139 @@ +;; funcs.el file for vinegar contribution layer + +(defun vinegar/dotfiles-toggle () + "Show/hide dot-files" + (interactive) + (when (equal major-mode 'dired-mode) + (if (or (not (boundp 'dired-dotfiles-show-p)) dired-dotfiles-show-p) ; if currently showing + (progn + (set (make-local-variable 'dired-dotfiles-show-p) nil) + (message "h") + (dired-mark-files-regexp "^\\\.") + (dired-do-kill-lines)) + (progn (revert-buffer) ; otherwise just revert to re-show + (set (make-local-variable 'dired-dotfiles-show-p) t))))) + +(defun vinegar/back-to-top () + "Move to first file" + (interactive) + (beginning-of-buffer) + (dired-next-line 1)) + +(defun vinegar/jump-to-bottom () + "Move to last file" + (interactive) + (end-of-buffer) + (dired-next-line -1)) + +(defun vinegar/move-up () + "Move to previous file" + (interactive) + (dired-previous-line 1) + (if (bobp) + (dired-next-line 1))) + +(defun vinegar/move-down () + "Move to next file" + (interactive) + (dired-next-line 1) + (if (eobp) + (dired-next-line -1))) + +(defun vinegar/up-directory (&optional other-window) + "Run Dired on parent directory of current directory." + (interactive "P") + (let* ((dir (dired-current-directory)) + (orig (current-buffer)) + (up (file-name-directory (directory-file-name dir)))) + (or (dired-goto-file (directory-file-name dir)) + ;; Only try dired-goto-subdir if buffer has more than one dir. + (and (cdr dired-subdir-alist) + (dired-goto-subdir up)) + (progn + (kill-buffer orig) + (dired up) + (dired-goto-file dir))))) + +(defun vinegar/dired-diff () + "Ediff marked files in dired or selected files in separate window" + (interactive) + (let* ((marked-files (dired-get-marked-files nil nil)) + (other-win (get-window-with-predicate + (lambda (window) + (with-current-buffer (window-buffer window) + (and (not (eq window (selected-window))) + (eq major-mode 'dired-mode)))))) + (other-marked-files (and other-win + (with-current-buffer (window-buffer other-win) + (dired-get-marked-files nil))))) + (cond ((= (length marked-files) 2) + (ediff-files (nth 0 marked-files) + (nth 1 marked-files))) + ((= (length marked-files) 3) + (ediff-files3 (nth 0 marked-files) + (nth 1 marked-files) + (nth 2 marked-files) + )) + ((and (= (length marked-files) 1) + (= (length other-marked-files) 1)) + (ediff-files (nth 0 marked-files) + (nth 0 other-marked-files))) + ((= (length marked-files) 1) + (dired-diff)) + (t (error "mark exactly 2 files, at least 1 locally"))))) + + +(defun vinegar/dired-setup () + "Setup custom dired settings for vinegar" + (setq dired-omit-verbose nil) + (make-local-variable 'dired-hide-symlink-targets) + (setq dired-hide-details-hide-symlink-targets nil) + + ;; hide details by default + (dired-hide-details-mode t) + ;; omit the .. in dired + (dired-omit-mode t) + + ;; allow selection with mouse + (make-local-variable 'mouse-1-click-follows-link) + (setq mouse-1-click-follows-link nil) + + (local-set-key (kbd "") 'vinegar/dired-mouse-click) + (local-set-key (kbd "") 'vinegar/up-directory) + (local-set-key (kbd "") nil) + ) + +(defun vinegar/dired-mouse-click (event) + "In Dired, visit the file or directory name you click on." + (interactive "e") + (let (window pos file) + (save-excursion + (setq window (posn-window (event-end event)) + pos (posn-point (event-end event))) + (if (not (windowp window)) + (error "No file chosen")) + (set-buffer (window-buffer window)) + (goto-char pos) + (setq file (dired-get-file-for-visit))) + (find-alternate-file file))) + +(defun vinegar/dired-mouse-click-3 (event) + "In Dired, show context menu or go up a directory." + (interactive "e") + (let (window pos file) + (save-excursion + (setq window (posn-window (event-end event)) + pos (posn-point (event-end event))) + (if (not (windowp window)) + (error "No file chosen")) + (set-buffer (window-buffer window)) + (goto-char pos) + (condition-case-unless-debug ex + (progn + (setq file (dired-get-file-for-visit)) + (dired-find-file-other-window)) + ('error + (vinegar/up-directory) + )) + ))) +;; ) diff --git a/layers/+vim/vinegar/keybindings.el b/layers/+vim/vinegar/keybindings.el new file mode 100644 index 0000000..b9aaf4a --- /dev/null +++ b/layers/+vim/vinegar/keybindings.el @@ -0,0 +1,3 @@ +(define-key evil-normal-state-map (kbd "-") 'dired-jump) + +(add-hook 'dired-mode-hook 'vinegar/dired-setup) diff --git a/layers/+vim/vinegar/packages.el b/layers/+vim/vinegar/packages.el new file mode 100644 index 0000000..2916d6d --- /dev/null +++ b/layers/+vim/vinegar/packages.el @@ -0,0 +1,68 @@ +;;; packages.el --- vinegar Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq vinegar-packages + '( + diff-hl + ;; dired+ + (dired :location built-in) + )) + +(defun vinegar/init-dired+ () + (use-package dired+ + :defer t + :init + (progn + (setq diredp-hide-details-initially-flag t) + (setq diredp-hide-details-propagate-flag t) + ;; use single buffer for all dired navigation + ;; disable font themeing from dired+ + (setq font-lock-maximum-decoration (quote ((dired-mode . 1) (t . t)))) + (toggle-diredp-find-file-reuse-dir 1) + ))) + +(defun vinegar/post-init-diff-hl () + (use-package diff-hl + :defer t + :init + (progn + (add-hook 'dired-mode-hook 'diff-hl-dired-mode) + ))) + +(defun vinegar/post-init-dired () + (use-package dired + :defer t + :config + (evilified-state-evilify dired-mode dired-mode-map + "j" 'vinegar/move-down + "k" 'vinegar/move-up + "-" 'vinegar/up-directory + "0" 'dired-back-to-start-of-files + "=" 'vinegar/dired-diff + (kbd "C-j") 'dired-next-subdir + (kbd "C-k") 'dired-prev-subdir + "I" 'vinegar/dotfiles-toggle + (kbd "~") '(lambda ()(interactive) (find-alternate-file "~/")) + (kbd "RET") (if vinegar-reuse-dired-buffer + 'dired-find-alternate-file + 'dired-find-file) + "f" (if (configuration-layer/layer-usedp 'ivy) + 'counsel-find-file + 'helm-find-files) + "J" 'dired-goto-file + (kbd "C-f") 'find-name-dired + "H" 'diredp-dired-recent-dirs + "T" 'dired-tree-down + "K" 'dired-do-kill-lines + "r" 'revert-buffer + (kbd "C-r") 'dired-do-redisplay + "gg" 'vinegar/back-to-top + "G" 'vinegar/jump-to-bottom))) diff --git a/layers/+web-services/elfeed/README.org b/layers/+web-services/elfeed/README.org new file mode 100644 index 0000000..2601399 --- /dev/null +++ b/layers/+web-services/elfeed/README.org @@ -0,0 +1,132 @@ +#+TITLE: Elfeed layer + +[[file:img/elfeed.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#setup-feeds][Setup feeds]] + - [[#with-org][With Org]] + - [[#manually][Manually]] + - [[#server][Server]] + - [[#key-bindings][Key Bindings]] + - [[#troubleshooting][Troubleshooting]] + - [[#database-empty-at-first-start][Database empty at first start]] + - [[#queue-timeout-exceeded][Queue timeout exceeded]] + +* Description +This layer enables [[https://github.com/skeeto/elfeed][Elfeed]], a web feeds client which supports both Atom and RSS +feeds. It'll optionally enable supporting packages, such as =elfeed-web= and +=elfeed-org=. + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =elfeed= to the existing =dotspacemacs-configuration-layers= list in this +file. + +By default, =elfeed= stores its database under =~/.elfeed=. + +** Setup feeds +*** With Org +It is recommended to manage your feeds list and tags via org files, this is +possible thanks to [[https://github.com/remyhonig/elfeed-org][elfeed-org]] package. To define a list of org files: + +#+BEGIN_SRC emacs-lisp +(elfeed :variables rmh-elfeed-org-files (list "~/.emacs.d/private/elfeed1.org" + "~/.emacs.d/private/elfeed2.org")) +#+END_SRC + +Checkout [[https://github.com/remyhonig/elfeed-org][elfeed-org]] documentation to see the format of that file. + +Here is an example of such a file (note the usage of org tags to tag your feeds) + +#+BEGIN_SRC org + * Blogs :elfeed: + ** entry-title: \(linux\|linus\|ubuntu\|kde\|gnome\) :linux: + ** http://git-annex.branchable.com/design/assistant/blog/index.rss :mustread: + ** http://feeds.feedburner.com/InformationIsBeautiful + ** [[http://orgmode.org][Org Mode Links supported as well]] + ** Software Development :dev: + *** Emacs :emacs:mustread: + **** http://www.terminally-incoherent.com/blog/feed + **** http://nullprogram.com/feed + **** entry-title: \(emacs\|org-mode\) + **** http://planet.emacsen.org/atom.xml + *** Web Development :web: + **** http://planet.phpunit.de/atom.xml + **** http://feeds.feedburner.com/symfony/blog + **** http://feeds.feedburner.com/qooxdoo/blog/content + *** Eclipse :eclipse: + **** http://blog.eclipse-tips.com/feeds/posts/default?alt=rss + **** http://ed-merks.blogspot.com/feeds/posts/default + **** http://feeds.feedburner.com/eclipselive + **** http://www.fosslc.org/drupal/rss.xml :video: + #+END_SRC + +*** Manually +To explicitly setup the list of feeds, set the value of =elfeed-feeds= variable +in your =.spacemacs= file. + +#+BEGIN_SRC emacs-lisp +(elfeed :variables + elfeed-feeds '(("http://nullprogram.com/feed/" blog emacs) + "http://www.50ply.com/atom.xml" ; no autotagging + ("http://nedroid.com/feed/" webcomic))) +#+END_SRC + +Check documentation for =elfeed-feeds= for more information about this variable +(~SPC h d v elfeed-feeds RET~). + +** Server +Elfeed comes with a simple [[https://github.com/skeeto/elfeed#web-interface][web interface]] to browse its database. You can manually +start it by calling =elfeed-web-start= or by setting =elfeed-enable-web-interface= +to =t= which will start the web automatically when Emacs starts. + +#+BEGIN_SRC emacs-lisp +(elfeed :variables elfeed-enable-web-interface t) +#+END_SRC + +By default web interface is available on [[http://localhost:8080/elfeed/][localhost:8080/elfeed]]. You can change +the default port by changing the value of =httpd-port=. + +* Key Bindings + +| Key Binding | Description | +|-------------+--------------| +| ~SPC a f~ | start elfeed | + +Use =SPC ?= to discover major-mode key bindings. + +| Key Binding | Description | +|-------------+---------------------------------------------------| +| ~c~ | compact feed db | +| ~gr~ | update all the feeds | +| ~gR~ | force refresh view of the feed listing | +| ~gu~ | unjam elfeed if it is slow due to slow connection | +| ~o~ | load OPML | +| ~q~ | quit main window, or item view buffer. | +| ~w~ | start web server | +| ~W~ | stop web server | + +In =elfeed-show= mode, you can use the following bindings: + +| Key Binding | Description | +|-------------+------------------| +| ~q~ | quit show window | +| ~C-j~ | Next entry | +| ~C-k~ | Previous entry | + +* Troubleshooting +** Database empty at first start +Be sure that you added some feeds first then load your feeds with ~gr~ +in evilified buffer. Or ~M-x elfeed-update~. + +** Queue timeout exceeded +If you are getting "Queue timeout exceeded" errors, try increasing +the value of =url-queue-timeout=. + +#+BEGIN_SRC emacs-lisp +(elfeed :variables url-queue-timeout 30) +#+END_SRC diff --git a/layers/+web-services/elfeed/config.el b/layers/+web-services/elfeed/config.el new file mode 100644 index 0000000..6c12f3d --- /dev/null +++ b/layers/+web-services/elfeed/config.el @@ -0,0 +1,15 @@ +;;; config.el --- elfeed Layer configuration File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;;; Variables + +(defvar elfeed-enable-web-interface nil + "If non nil start a web server to consult the database in a web browser.") diff --git a/layers/+web-services/elfeed/img/elfeed.png b/layers/+web-services/elfeed/img/elfeed.png new file mode 100644 index 0000000..5d06da0 Binary files /dev/null and b/layers/+web-services/elfeed/img/elfeed.png differ diff --git a/layers/+web-services/elfeed/packages.el b/layers/+web-services/elfeed/packages.el new file mode 100644 index 0000000..5e31d5c --- /dev/null +++ b/layers/+web-services/elfeed/packages.el @@ -0,0 +1,68 @@ +;;; packages.el --- elfeed Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq elfeed-packages + '(elfeed + elfeed-goodies + elfeed-org + elfeed-web + )) + +(defun elfeed/init-elfeed () + (use-package elfeed + :defer t + :init (spacemacs/set-leader-keys "af" 'elfeed) + :config + (progn + (evilified-state-evilify-map elfeed-search-mode-map + :mode elfeed-search-mode + :eval-after-load elfeed-search + :bindings + "c" 'elfeed-db-compact + "gr" 'elfeed-update + "gR" 'elfeed-search-update--force + "gu" 'elfeed-unjam + "o" 'elfeed-load-opml + "q" 'quit-window + "w" 'elfeed-web-start + "W" 'elfeed-web-stop) + (evilified-state-evilify-map elfeed-show-mode-map + :mode elfeed-show-mode + :eval-after-load elfeed-show + :bindings + "q" 'quit-window + (kbd "C-j") 'elfeed-show-next + (kbd "C-k") 'elfeed-show-prev)))) + +(defun elfeed/init-elfeed-goodies () + (use-package elfeed-goodies + :commands elfeed-goodies/setup + :init (spacemacs|use-package-add-hook elfeed + :post-config (progn + (elfeed-goodies/setup) + (evil-define-key 'evilified elfeed-show-mode-map "o" 'elfeed-goodies/show-ace-link))))) + +(defun elfeed/init-elfeed-org () + (use-package elfeed-org + :defer t + :if (boundp 'rmh-elfeed-org-files) + :init (spacemacs|use-package-add-hook elfeed + :pre-config (elfeed-org)))) + +(defun elfeed/init-elfeed-web () + (use-package elfeed-web + :defer t + :commands elfeed-web-stop + :init (when elfeed-enable-web-interface + ;; TODO check if the port is already in use + ;; hack to force elfeed feature to be required before elfeed-search + (require 'elfeed) + (elfeed-web-start)))) diff --git a/layers/+web-services/evernote/README.org b/layers/+web-services/evernote/README.org new file mode 100644 index 0000000..3ca9d21 --- /dev/null +++ b/layers/+web-services/evernote/README.org @@ -0,0 +1,57 @@ +#+TITLE: Evernote layer + +[[file:img/evernote.png]] with [[file:img/geeknote.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#layer][Layer]] + - [[#geeknote][geeknote]] + - [[#geeknoteel][geeknote.el]] + - [[#key-bindings][Key Bindings]] + +* Description +This layer groups together packages to work with [[https://evernote.com/][Evernote]]. + +It uses the non official Evernote command line tool [[http://www.geeknote.me][geeknote]] which allows users +to write notes in markdown, and sync them. + +[[https://github.com/avendael/emacs-geeknote][geeknote.el]] is a wrapper for some of the most used =geeknote= commands. By +default, =geeknote.el= doesn't have key bindings defined. This contribution +layer provides key bindings for all of geeknote.el's exposed features. + +* Install +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =evernote= to the existing =dotspacemacs-configuration-layers= list in this +file. + +** geeknote +The command =geeknote= is expected to be present in your =$PATH=. To +obtain this utility, please refer to the official geeknote +[[http://www.geeknote.me/documentation/][documentation]]. + +** geeknote.el +=geeknote.el= relies on having a correctly setup geeknote editor. To set +this up, run the following command in your terminal after successfully +installing =geeknote=: + +#+BEGIN_SRC sh + $ geeknote settings --editor "emacsclient" +#+END_SRC + +If you would prefer to customize the geeknote command to be used such as +specifying the path to the geeknote python script, please refer to the +=geeknote.el= [[https://github.com/avendael/emacs-geeknote][documentation]]. For more information about setting up =$PATH=, +check out the corresponding section in the FAQ (~SPC h SPC $PATH RET~). + +* Key Bindings + +| Key Binding | Description | +|-------------+-------------------------------------| +| ~SPC a e c~ | create a new note | +| ~SPC a e e~ | edit an existing note | +| ~SPC a e f~ | find a note using a keyword | +| ~SPC a e s~ | show an existing note | +| ~SPC a e r~ | remove an existing note | +| ~SPC a e m~ | move a note to a different notebook | diff --git a/layers/+web-services/evernote/img/evernote.png b/layers/+web-services/evernote/img/evernote.png new file mode 100644 index 0000000..f365d7a Binary files /dev/null and b/layers/+web-services/evernote/img/evernote.png differ diff --git a/layers/+web-services/evernote/img/geeknote.png b/layers/+web-services/evernote/img/geeknote.png new file mode 100644 index 0000000..18900b8 Binary files /dev/null and b/layers/+web-services/evernote/img/geeknote.png differ diff --git a/layers/+web-services/evernote/packages.el b/layers/+web-services/evernote/packages.el new file mode 100644 index 0000000..84e8f60 --- /dev/null +++ b/layers/+web-services/evernote/packages.el @@ -0,0 +1,34 @@ +;;; packages.el --- Evernote Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(setq evernote-packages + '( + geeknote + )) + +(defun evernote/init-geeknote () + "Initializes geeknote and adds keybindings for its exposed functionalities." + (use-package geeknote + :commands (geeknote-create + geeknote-edit + geeknote-find + geeknote-show + geeknote-remove + geeknote-move) + :init + (progn + (spacemacs/declare-prefix "ae" "applications-evernote") + (spacemacs/set-leader-keys + "aec" 'geeknote-create + "aee" 'geeknote-edit + "aef" 'geeknote-find + "aes" 'geeknote-show + "aer" 'geeknote-remove + "aem" 'geeknote-move)))) diff --git a/layers/+web-services/search-engine/README.org b/layers/+web-services/search-engine/README.org new file mode 100644 index 0000000..3cfc64b --- /dev/null +++ b/layers/+web-services/search-engine/README.org @@ -0,0 +1,68 @@ +#+TITLE: Search Engine layer + +[[file:img/searchengine.jpg]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#supported-search-engines][Supported search engines]] + - [[#install][Install]] + - [[#key-bindings][Key Bindings]] + - [[#customize-it][Customize it!]] + +* Description + +This layer adds support for the [[https://github.com/hrs/engine-mode/engine-mode.el][Search Engine]] package. + +** Supported search engines + +- Amazon +- Duck Duck Go +- Google +- Google Images +- GitHub +- Google Maps +- Twitter +- Project Gutemberg +- Youtube +- Stack Overflow +- Spacemacs Issues +- Wikipedia +- Wolfram Alpha + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =search-engine= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key Bindings + +| Evil | Holy | Command | +|-----------+---------+-------------------------------------------| +| ~SPC a /~ | ~C-c /~ | Summon a Helm buffer to select any engine | + +* Customize it! + +If you'd rather have emacs use chrome, or firefox or any other thing (=eww=) you +can have that customization. For example for google chrome you can put this in +your =dotspacemacs/user-config=: + +#+BEGIN_SRC emacs-lisp + (setq browse-url-browser-function 'browse-url-generic + engine/browser-function 'browse-url-generic + browse-url-generic-program "google-chrome") +#+END_SRC + +Also if you want more search engines, just push them (do this in +=dotspacemacs/user-config=) + +#+BEGIN_SRC emacs-lisp +(push '(custom1 + :name "Custom Search Engine 1" + :url "http://www.domain.com/s/stuff_sutff_remember_to_replace_search_candidate_with_%s") + search-engine-alist) +#+END_SRC + +If you'd rather not use helm but would want a specific search engine, remember +the function generated is always =engine/search-(the name of the search engine +lower-case and hyphen instead-of-spaces-for-separation)= so you can bind that to +any key binding you want. diff --git a/layers/+web-services/search-engine/funcs.el b/layers/+web-services/search-engine/funcs.el new file mode 100644 index 0000000..6830bb4 --- /dev/null +++ b/layers/+web-services/search-engine/funcs.el @@ -0,0 +1,44 @@ +;;; funcs.el --- search-engine Layer functions File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(defun spacemacs//search-engine-source (engines) + "return a source for helm selection" + `((name . "Search Engines") + (candidates . ,(mapcar (lambda (engine) + (cons (plist-get (cdr engine) :name) + (intern (format "engine/search-%S" + (car engine))))) + engines)) + (action . (lambda (candidate) (call-interactively candidate))))) + +(defun spacemacs/helm-search-engine-select () + "Set search engine to use with helm." + (interactive) + (helm :sources (list (spacemacs//search-engine-source + search-engine-alist)))) + +(defun spacemacs/ivy-search-engine-select () + "Set search engine to use with ivy." + (interactive) + (ivy-read "Search Engines: " + (mapcar (lambda (engine) + (cons (plist-get (cdr engine) :name) + (intern (format "engine/search-%S" + (car engine))))) + search-engine-alist) + :action (lambda (candidate) (call-interactively (cdr candidate))))) + +(defun spacemacs/search-engine-select () + "Set search engine to use." + (interactive) + (if (configuration-layer/layer-usedp 'ivy) + (call-interactively 'spacemacs/ivy-search-engine-select) + (call-interactively 'spacemacs/helm-search-engine-select))) diff --git a/layers/+web-services/search-engine/img/searchengine.jpg b/layers/+web-services/search-engine/img/searchengine.jpg new file mode 100644 index 0000000..3a4b01d Binary files /dev/null and b/layers/+web-services/search-engine/img/searchengine.jpg differ diff --git a/layers/+web-services/search-engine/packages.el b/layers/+web-services/search-engine/packages.el new file mode 100644 index 0000000..f6c622e --- /dev/null +++ b/layers/+web-services/search-engine/packages.el @@ -0,0 +1,82 @@ +;;; packages.el --- search-engine Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; List of all packages to install and/or initialize. Built-in packages +;; which require an initialization must be listed explicitly in the list. +(setq search-engine-packages + '( + engine-mode + )) + +(defun search-engine/init-engine-mode () + (use-package engine-mode + :commands (defengine spacemacs/search-engine-select) + :defines search-engine-alist + :init + (progn + (spacemacs/set-leader-keys + "a/" 'spacemacs/search-engine-select) + (setq search-engine-alist + '((amazon + :name "Amazon" + :url "http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%%3Daps&field-keywords=%s") + (bing + :name "Bing" + :url "http://www.bing.com/search?q=%s") + (duck-duck-go + :name "Duck Duck Go" + :url "https://duckduckgo.com/?q=%s") + (google + :name "Google" + :url "http://www.google.com/search?ie=utf-8&oe=utf-8&q=%s") + (google-images + :name "Google Images" + :url "http://www.google.com/images?hl=en&source=hp&biw=1440&bih=795&gbv=2&aq=f&aqi=&aql=&oq=&q=%s") + (github + :name "Github" + :url "https://github.com/search?ref=simplesearch&q=%s") + (google-maps + :name "Google Maps" + :url "http://maps.google.com/maps?q=%s") + (twitter + :name "Twitter" + :url "https://twitter.com/search?q=%s") + (project-gutenberg + :name "Project Gutenberg" + :url "http://www.gutenberg.org/ebooks/search.html/?format=html&default_prefix=all&sort_order=&query=%s") + (youtube + :name "YouTube" + :url "http://www.youtube.com/results?aq=f&oq=&search_query=%s") + (stack-overflow + :name "Stack Overflow" + :url "https://stackoverflow.com/search?q=%s") + (spacemacs-issues + :name "Spacemacs Issues" + :url "https://github.com/syl20bnr/spacemacs/issues?utf8=%%E2%%9C%%93&q=is%%3Aissue+is%%3Aopen+%s") + (spacemacs-pullrequests + :name "Spacemacs Pull Requests" + :url "https://github.com/syl20bnr/spacemacs/pulls?utf8=%%E2%%9C%%93&q=is%%3Aissue+is%%3Aopen+%s") + (wikipedia + :name "Wikipedia" + :url "http://www.wikipedia.org/search-redirect.php?language=en&go=Go&search=%s") + (wolfram-alpha + :name "Wolfram Alpha" + :url "http://www.wolframalpha.com/input/?i=%s"))) + (dolist (engine search-engine-alist) + (let ((func (intern (format "engine/search-%S" (car engine))))) + (autoload func "engine-mode" nil 'interactive)))) + :config + (progn + (engine-mode t) + (dolist (engine search-engine-alist) + (let* ((cur-engine (car engine)) + (engine-url (plist-get (cdr engine) :url))) + (eval `(defengine ,cur-engine ,engine-url))))))) diff --git a/layers/+web-services/spotify/README.org b/layers/+web-services/spotify/README.org new file mode 100644 index 0000000..7d152bb --- /dev/null +++ b/layers/+web-services/spotify/README.org @@ -0,0 +1,27 @@ +#+TITLE: Spotify layer + +[[file:img/spotify.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#key-bindings][Key bindings]] + +* Description + +This layer adds key bindings for controlling Spotify from inside Emacs. + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =spotify= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Key bindings + +| Key Binding | Description | +|---------------+--------------------------| +| ~SPC a m s p~ | Play or pause Spotify | +| ~SPC a m s n~ | Go to the next track | +| ~SPC a m s N~ | Go to the previous track | +| ~SPC a m s g~ | Search for a new track | +| ~SPC a m s Q~ | Quit Spotify | diff --git a/layers/+web-services/spotify/img/spotify.png b/layers/+web-services/spotify/img/spotify.png new file mode 100644 index 0000000..39c3175 Binary files /dev/null and b/layers/+web-services/spotify/img/spotify.png differ diff --git a/layers/+web-services/spotify/packages.el b/layers/+web-services/spotify/packages.el new file mode 100644 index 0000000..a85be8f --- /dev/null +++ b/layers/+web-services/spotify/packages.el @@ -0,0 +1,34 @@ +;;; packages.el --- spotify Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Brian Hicks +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +(setq spotify-packages + '( + spotify + (helm-spotify :toggle (configuration-layer/package-usedp 'helm)) + )) + +(defun spotify/init-spotify () + (use-package spotify + :defer t + :init + (progn + (spacemacs/declare-prefix "am" "music") + (spacemacs/declare-prefix "ams" "Spotify") + (spacemacs/set-leader-keys + "amsp" 'spotify-playpause + "amsn" 'spotify-next + "amsN" 'spotify-previous + "amsQ" 'spotify-quit)))) + +(defun spotify/init-helm-spotify () + (use-package helm-spotify + :defer t + :init (spacemacs/set-leader-keys "amsg" 'helm-spotify))) diff --git a/layers/+web-services/twitter/README.org b/layers/+web-services/twitter/README.org new file mode 100644 index 0000000..502eea0 --- /dev/null +++ b/layers/+web-services/twitter/README.org @@ -0,0 +1,80 @@ +#+TITLE: Twitter contribution layer for Spacemacs + +[[file:img/twitter.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#features][Features]] + - [[#install][Install]] + - [[#configuration][Configuration]] + - [[#key-bindings][Key Bindings]] + +* Description +This layer adds Twitter support to Spacemacs via the package [[https://github.com/hayamiz/twittering-mode][twittering-mode]]. + +* Features +- Activities on Twitter + - Viewing various timelines + - Home timeline + - Replies + - User's timeline + - Public timeline + - Favorites timeline + - Retweets timeline + - Merged timeline + - Timeline without tweets satisfying a condition + - Posting tweets + - Direct message + - ReTweet + - Hash tag + - Signature + - Following and removing users + - Marking tweets as favorites +- HTTP Proxy support +- Secure connection via HTTPS (cURL, GNU Wget, OpenSSL or GnuTLS is required) + +* Install +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =twitter= to the existing =dotspacemacs-configuration-layers= list in this +file. + +* Configuration +Exhaustive configuration documentation can be found on the README page of the +package [[https://github.com/hayamiz/twittering-mode][here]]. + +You can authenticate easily via a PIN number, or you can use GnuPG by setting +the variable =twittering-use-master-password= to =t= in the =user-config= +function of your dotfile. + +* Key Bindings + +| Key Binding | Description | +|-------------+------------------------------------------| +| ~?~ | Open/Quit transient state | +| ~/~ | Search | +| ~a~ | Toggle auto-refresh | +| ~b~ | Heart | +| ~B~ | Unheart | +| ~d~ | Direct message to user around point | +| ~e~ | Edit tweet | +| ~f~ | Follow user around point | +| ~F~ | Unfollow user around point | +| ~g~ | First tweet | +| ~G~ | Last tweet | +| ~i~ | View user profile around point | +| ~I~ | toggle user icons | +| ~q~ | Quit transient state | +| ~Q~ | Quit twittering mode | +| ~j~ | Next tweet | +| ~J~ | Next tweet of same user around point | +| ~k~ | Previous tweet | +| ~K~ | Previous tweet of same user around point | +| ~n~ | New tweet | +| ~o~ | Open URL | +| ~r~ | Retweet (native) | +| ~R~ | Retweet (organic) | +| ~t~ | View tweet replies | +| ~u~ | Update timeline | +| ~X~ | Delete tweet | +| ~y~ | Copy tweet URI | +| ~Y~ | Copy tweet content | diff --git a/layers/+web-services/twitter/img/twitter.png b/layers/+web-services/twitter/img/twitter.png new file mode 100644 index 0000000..8741acb Binary files /dev/null and b/layers/+web-services/twitter/img/twitter.png differ diff --git a/layers/+web-services/twitter/packages.el b/layers/+web-services/twitter/packages.el new file mode 100644 index 0000000..928a033 --- /dev/null +++ b/layers/+web-services/twitter/packages.el @@ -0,0 +1,114 @@ +;;; packages.el --- twitter Layer packages File for Spacemacs +;; +;; Copyright (c) 2012-2014 Sylvain Benner +;; Copyright (c) 2014-2015 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; List of all packages to install and/or initialize. Built-in packages +;; which require an initialization must be listed explicitly in the list. +(setq twitter-packages '(twittering-mode)) + +(defun twitter/init-twittering-mode () + (use-package twittering-mode + :defer t + :init + (progn + (spacemacs/set-leader-keys "at" 'twit) + (setq twittering-initial-timeline-spec-string '(":home") + twittering-icon-mode t + twittering-use-icon-storage 1 + twittering-enable-unread-status-notifier t + twittering-display-remaining t + twittering-edit-skeleton 'inherit-any + twittering-url-show-status nil + twittering-timeline-header "" + twittering-timeline-footer "" + twitter-images-directory (concat spacemacs-cache-directory "twitter") + twittering-status-format "%i %S, %RT{%FACE[bold]{%S}} %@ %FACE[shadow]{%p%f%L%r}\n%FOLD[ ]{%T}\n") + (unless (file-exists-p twitter-images-directory) + (make-directory twitter-images-directory)) + + ) + :config + (progn + ;; twittering mode overwrite the leader key + (define-key twittering-mode-map (kbd "SPC") spacemacs-default-map) + ;; redefine better defaults + (let ((map twittering-mode-map)) + (define-key map "?" 'spacemacs/twittering-mode-transient-state/body) + (define-key map "/" 'twittering-search) + (define-key map "a" 'twittering-toggle-activate-buffer) + (define-key map "b" 'twittering-favorite) + (define-key map "B" 'twittering-unfavorite) + (define-key map "d" 'twittering-direct-message) + (define-key map "e" 'twittering-edit-mode) + (define-key map "f" 'twittering-follow) + (define-key map "F" 'twittering-unfollow) + (define-key map "g" 'beginning-of-buffer) + (define-key map "G" 'end-of-buffer) + (define-key map "i" 'twittering-view-user-page) + (define-key map "Q" 'twittering-kill-buffer) + (define-key map "I" 'twittering-icon-mode) + (define-key map "j" 'twittering-goto-next-status) + (define-key map "J" 'twittering-goto-next-status-of-user) + (define-key map "k" 'twittering-goto-previous-status) + (define-key map "K" 'twittering-goto-previous-status-of-user) + (define-key map "n" 'twittering-update-status-interactive) + (define-key map "o" 'twittering-click) + (define-key map "r" 'twittering-native-retweet) + (define-key map "R" 'twittering-organic-retweet) + (define-key map "t" 'twittering-toggle-or-retrieve-replied-statuses) + (define-key map "u" 'twittering-current-timeline) + (define-key map "X" 'twittering-delete-status) + (define-key map "y" 'twittering-push-uri-onto-kill-ring) + (define-key map "Y" 'twittering-push-tweet-onto-kill-ring)) + ;; associated transient state + (spacemacs|define-transient-state twittering-mode + :title "Twittering Mode Transient State" + :doc " + Tweets^^^^^^ User^^^^ Other^^ + ──────^^^^^^────────────────────────────────── ────^^^^─────────────── ─────^^─────────────────── + [_j_/_k_] down/up [_r_] retweet [_d_]^^ direct message [_a_] toggle auto-refresh + [_RET_]^^ open or reply [_R_] retweet & edit [_f_]^^ follow [_q_] quit + [_b_]^^ heart [_n_] post new tweet [_F_]^^ unfollow [_Q_] quit twitter + [_B_]^^ unheart [_t_] show thread [_i_]^^ profile [_u_] update + [_e_]^^ edit mode [_X_] delete tweet [_J_/_K_] down/up [_/_] search + [_g_]^^ first [_y_] yank url ^^^^ [_I_] toggle images + [_G_]^^ last [_Y_] yank tweet + [_o_]^^ open url" + :bindings + ("?" nil :exit t) + ("RET" twittering-enter :exit t) + ("/" twittering-search :exit t) + ("a" twittering-toggle-activate-buffer) + ("b" twittering-favorite) + ("B" twittering-unfavorite) + ("d" twittering-direct-message :exit t) + ("e" twittering-edit-mode :exit t) + ("f" twittering-follow) + ("F" twittering-unfollow) + ("g" beginning-of-buffer) + ("G" end-of-buffer) + ("i" twittering-view-user-page) + ("q" nil :exit t) + ("Q" twittering-kill-buffer :exit t) + ("I" twittering-icon-mode) + ("j" twittering-goto-next-status) + ("J" twittering-goto-next-status-of-user) + ("k" twittering-goto-previous-status) + ("K" twittering-goto-previous-status-of-user) + ("n" twittering-update-status-interactive :exit t) + ("o" twittering-click :exit t) + ("r" twittering-native-retweet :exit t) + ("R" twittering-organic-retweet :exit t) + ("t" twittering-toggle-or-retrieve-replied-statuses :exit t) + ("u" twittering-current-timeline) + ("X" twittering-delete-status) + ("y" twittering-push-uri-onto-kill-ring) + ("Y" twittering-push-tweet-onto-kill-ring))))) diff --git a/layers/+web-services/wakatime/README.org b/layers/+web-services/wakatime/README.org new file mode 100644 index 0000000..f6099e0 --- /dev/null +++ b/layers/+web-services/wakatime/README.org @@ -0,0 +1,74 @@ +#+TITLE: Wakatime layer + +[[file:img/wakatime.png]] + +* Table of Contents :TOC_4_gh:noexport: + - [[#description][Description]] + - [[#install][Install]] + - [[#wakatime-program][Wakatime Program]] + - [[#layer][Layer]] + - [[#api-keys][API Keys]] + - [[#note-to-venv-workon-users][Note to =venv-workon= users:]] + +* Description +This layer adds support for Wakatime. + +WakaTime was built to solve time tracking for programmers. +Since we work inside a text editor, why should we have to start and stop a +timer? WakaTime uses open-source text editor plugins to automatically track the +time you spend programming so you never have to manually track it again! + +P.S. wakati means time in Swahili + +* Install +** Wakatime Program +You can follow wakatime installation instructions here +https://github.com/wakatime/wakatime-mode. + +In short it's just: +#+BEGIN_SRC sh +pip install wakatime +#+END_SRC + +And for some linux users +#+BEGIN_SRC sh +sudo pip install wakatime +#+END_SRC + +** Layer +To use this configuration layer, add it to your =~/.spacemacs=. You will need to +add =wakatime= to the existing =dotspacemacs-configuration-layers= list in this +file. + +Example: +#+BEGIN_SRC emacs-lisp + (setq-default dotspacemacs-configuration-layers + '( + ;; ... + (wakatime :variables + wakatime-api-key "your-api-key" + ;; use the actual wakatime path + wakatime-cli-path "/usr/bin/wakatime") + ;; ... + )) +#+END_SRC + +** API Keys +After this go to your wakatime account and have your API key handy +https://wakatime.com/settings/account?apikey=true . + +Restart emacs and it will prompt you for the location of the wakatime installer +(just put in whatever =which wakatime= gives you in the terminal e.g. +=/usr/bin/wakatime= for example) and that's it. + +*** Note to =venv-workon= users: + +Right now wakatime uses =python= as python bin executable, so if you use +=venv-workon= because you have python projects which need to have a virtual +env., then wakatime, which is installed system-wide will have trouble locating +wakatime files, so it's best to define by yourself the python path where +wakatime can always find it's stuff, via this variable: + +#+BEGIN_SRC emacs-lisp +(setq wakatime-python-bin "/path/to/python") +#+END_SRC diff --git a/layers/+web-services/wakatime/img/wakatime.png b/layers/+web-services/wakatime/img/wakatime.png new file mode 100644 index 0000000..aeabc26 Binary files /dev/null and b/layers/+web-services/wakatime/img/wakatime.png differ diff --git a/layers/+web-services/wakatime/packages.el b/layers/+web-services/wakatime/packages.el new file mode 100644 index 0000000..09fd975 --- /dev/null +++ b/layers/+web-services/wakatime/packages.el @@ -0,0 +1,13 @@ +(setq wakatime-packages '(wakatime-mode)) + +(defun wakatime/init-wakatime-mode () + (use-package wakatime-mode + :defer t + :init + (add-hook 'prog-mode-hook 'wakatime-mode) + :config + (defun spacemacs/wakatime-dashboard () + (interactive) + (browse-url "https://wakatime.com/dashboard")) + (spacemacs/set-leader-keys + "aW" 'spacemacs/wakatime-dashboard))) diff --git a/layers/LAYERS.org b/layers/LAYERS.org new file mode 100644 index 0000000..6f00cda --- /dev/null +++ b/layers/LAYERS.org @@ -0,0 +1,205 @@ +#+TITLE: Configuration layers +#+HTML_HEAD_EXTRA: + +* Table of Contents :TOC_4_org:noexport: + - [[Chat][Chat]] + - [[Checkers][Checkers]] + - [[Completion][Completion]] + - [[Distributions][Distributions]] + - [[Emacs][Emacs]] + - [[E-mail][E-mail]] + - [[Frameworks][Frameworks]] + - [[Fun][Fun]] + - [[International support][International support]] + - [[Programming and markup languages][Programming and markup languages]] + - [[Misc][Misc]] + - [[Operating systems][Operating systems]] + - [[Pair programming][Pair programming]] + - [[Source control][Source control]] + - [[Spacemacs distribution layers][Spacemacs distribution layers]] + - [[Tags][Tags]] + - [[Themes][Themes]] + - [[Tools][Tools]] + - [[Vim][Vim]] + - [[Web services][Web services]] + +* Chat +- [[file:+chat/erc/README.org][erc]] +- [[file:+chat/jabber/README.org][jabber]] +- [[file:+chat/rcirc/README.org][rcirc]] +- [[file:+chat/slack/README.org][slack]] + +* Checkers +- [[file:+checkers/spell-checking/README.org][spell-checking]] +- [[file:+checkers/syntax-checking/README.org][syntax-checking]] + +* Completion +- [[file:+completion/auto-completion/README.org][auto-completion]] +- [[file:+completion/helm/README.org][helm]] +- [[file:+completion/ivy/README.org][ivy]] + +* Distributions +- [[file:+distributions/spacemacs/README.org][spacemacs]] +- [[file:+distributions/spacemacs-base/README.org][spacemacs-base]] +- [[file:+distributions/spacemacs-bootstrap/README.org][spacemacs-bootstrap]] + +* Emacs +- [[file:+emacs/better-defaults/README.org][better-defaults]] +- [[file:+emacs/ibuffer/README.org][ibuffer]] +- [[file:+emacs/org/README.org][org]] +- [[file:+emacs/semantic/README.org][semantic]] +- [[file:+emacs/smex/README.org][smex]] +- [[file:+emacs/typography/README.org][typography]] + +* E-mail +- [[file:+email/gnus/README.org][gnus]] +- [[file:+email/mu4e/README.org][mu4e]] + +* Frameworks +- [[file:+frameworks/django/README.org][django]] +- [[file:+frameworks/react/README.org][react]] +- [[file:+frameworks/ruby-on-rails/README.org][ruby-on-rails]] + +* Fun +- [[file:+fun/emoji/README.org][emoji]] +- [[file:+fun/games/README.org][games]] +- [[file:+fun/selectric/README.org][selectric]] +- [[file:+fun/xkcd/README.org][xkcd]] + +* International support +- [[file:+intl/chinese/README.org][chinese]] +- [[file:+intl/keyboard-layout/README.org][keyboard-layout]] + +* Programming and markup languages +- [[file:+lang/agda/README.org][agda]] +- [[file:+lang/asciidoc/README.org][asciidoc]] +- [[file:+lang/asm/README.org][asm]] +- [[file:+lang/autohotkey/README.org][autohotkey]] +- [[file:+lang/bibtex/README.org][bibtex]] +- [[file:+lang/c-c++/README.org][c-c++]] +- [[file:+lang/clojure/README.org][clojure]] +- [[file:+lang/common-lisp/README.org][common-lisp]] +- [[file:+lang/csharp/README.org][csharp]] +- [[file:+lang/csv/README.org][csv]] +- [[file:+lang/d/README.org][d]] +- [[file:+lang/elixir/README.org][elixir]] +- [[file:+lang/elm/README.org][elm]] +- [[file:+lang/emacs-lisp/README.org][emacs-lisp]] +- [[file:+lang/erlang/README.org][erlang]] +- [[file:+lang/ess/README.org][ess]] +- [[file:+lang/extra-langs/README.org][extra-langs]] +- [[file:+lang/faust/README.org][faust]] +- [[file:+lang/fsharp/README.org][fsharp]] +- [[file:+lang/go/README.org][go]] +- [[file:+lang/graphviz/README.org][graphviz]] +- [[file:+lang/haskell/README.org][haskell]] +- [[file:+lang/html/README.org][html]] +- [[file:+lang/idris/README.org][idris]] +- [[file:+lang/ipython-notebook/README.org][ipython-notebook]] +- [[file:+lang/java/README.org][java]] +- [[file:+lang/javascript/README.org][javascript]] +- [[file:+lang/latex/README.org][latex]] +- [[file:+lang/lua/README.org][lua]] +- [[file:+lang/markdown/README.org][markdown]] +- [[file:+lang/nim/README.org][nim]] +- [[file:+lang/ocaml/README.org][ocaml]] +- [[file:+lang/octave/README.org][octave]] +- [[file:+lang/php/README.org][php]] +- [[file:+lang/plantuml/README.org][plantuml]] +- [[file:+lang/purescript/README.org][purescript]] +- [[file:+lang/python/README.org][python]] +- [[file:+lang/racket/README.org][racket]] +- [[file:+lang/ruby/README.org][ruby]] +- [[file:+lang/rust/README.org][rust]] +- [[file:+lang/scala/README.org][scala]] +- [[file:+lang/scheme/README.org][scheme]] +- [[file:+lang/shaders/README.org][shaders]] +- [[file:+lang/shell-scripts/README.org][shell-scripts]] +- [[file:+lang/sml/README.org][sml]] +- [[file:+lang/sql/README.org][sql]] +- [[file:+lang/swift/README.org][swift]] +- [[file:+lang/typescript/README.org][typescript]] +- [[file:+lang/vimscript/README.org][vimscript]] +- [[file:+lang/windows-scripts/README.org][windows-scripts]] +- [[file:+lang/yaml/README.org][yaml]] + +* Misc +- [[file:+misc/nlinum/README.org][nlinum]] + +* Operating systems +- [[file:+os/nixos/README.org][nixos]] +- [[file:+os/osx/README.org][osx]] + +* Pair programming +- [[file:+pair-programming/floobits/README.org][floobits]] + +* Source control +- [[file:+source-control/git/README.org][git]] +- [[file:+source-control/github/README.org][github]] +- [[file:+source-control/perforce/README.org][perforce]] +- [[file:+source-control/version-control/README.org][version-control]] + +* Spacemacs distribution layers +- [[file:+spacemacs/spacemacs-completion/README.org][spacemacs-completion]] +- [[file:+spacemacs/spacemacs-editing/README.org][spacemacs-editing]] +- [[file:+spacemacs/spacemacs-editing-visual/README.org][spacemacs-editing-visual]] +- [[file:+spacemacs/spacemacs-evil/README.org][spacemacs-evil]] +- [[file:+spacemacs/spacemacs-language/README.org][spacemacs-language]] +- [[file:+spacemacs/spacemacs-layouts/README.org][spacemacs-layouts]] +- [[file:+spacemacs/spacemacs-misc/README.org][spacemacs-misc]] +- [[file:+spacemacs/spacemacs-org/README.org][spacemacs-org]] +- [[file:+spacemacs/spacemacs-ui/README.org][spacemacs-ui]] +- [[file:+spacemacs/spacemacs-ui-visual/README.org][spacemacs-ui-visual]] + +* Tags +- [[file:+tags/cscope/README.org][cscope]] +- [[file:+tags/gtags/README.org][gtags]] + +* Themes +- [[file:+themes/colors/README.org][colors]] +- [[file:+themes/themes-megapack/README.org][themes-megapack]] +- [[file:+themes/theming/README.org][theming]] + +* Tools +- [[file:+tools/ansible/README.org][ansible]] +- [[file:+tools/cfengine/README.org][cfengine]] +- [[file:+tools/chrome/README.org][chrome]] +- [[file:+tools/command-log/README.org][command-log]] +- [[file:+tools/dash/README.org][dash]] +- [[file:+tools/deft/README.org][deft]] +- [[file:+tools/docker/README.org][docker]] +- [[file:+tools/fasd/README.org][fasd]] +- [[file:+tools/finance/README.org][finance]] +- [[file:+tools/geolocation/README.org][geolocation]] +- [[file:+tools/imenu-list/README.org][imenu-list]] +- [[file:+tools/nginx/README.org][nginx]] +- [[file:+tools/pandoc/README.org][pandoc]] +- [[file:+tools/pdf-tools/README.org][pdf-tools]] +- [[file:+tools/prodigy/README.org][prodigy]] +- [[file:+tools/puppet/README.org][puppet]] +- [[file:+tools/ranger/README.org][ranger]] +- [[file:+tools/restclient/README.org][restclient]] +- [[file:+tools/salt/README.org][salt]] +- [[file:+tools/shell/README.org][shell]] +- [[file:+tools/speed-reading/README.org][speed-reading]] +- [[file:+tools/systemd/README.org][systemd]] +- [[file:+tools/terraform/README.org][terraform]] +- [[file:+tools/tmux/README.org][tmux]] +- [[file:+tools/vagrant/README.org][vagrant]] +- [[file:+tools/ycmd/README.org][ycmd]] + +* Vim +- [[file:+vim/evil-cleverparens/README.org][evil-cleverparens]] +- [[file:+vim/evil-commentary/README.org][evil-commentary]] +- [[file:+vim/evil-snipe/README.org][evil-snipe]] +- [[file:+vim/vim-empty-lines/README.org][vim-empty-lines]] +- [[file:+vim/vim-powerline/README.org][vim-powerline]] +- [[file:+vim/vinegar/README.org][vinegar]] + +* Web services +- [[file:+web-services/elfeed/README.org][elfeed]] +- [[file:+web-services/evernote/README.org][evernote]] +- [[file:+web-services/search-engine/README.org][search-engine]] +- [[file:+web-services/spotify/README.org][spotify]] +- [[file:+web-services/twitter/README.org][twitter]] +- [[file:+web-services/wakatime/README.org][wakatime]] diff --git a/layers/auto-layer.el b/layers/auto-layer.el new file mode 100644 index 0000000..ab60d67 --- /dev/null +++ b/layers/auto-layer.el @@ -0,0 +1,123 @@ +;;; auto-layer.el --- auto-mode-alist entries for layer installation +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 + +;; TODO comments placeholder means the utility function to insert form has failed + +;; agda + +(configuration-layer/lazy-install 'ansible :extensions '("\\(\\.jinja2\\'\\|\\.j2\\'\\)" jinja2-mode)) + +(configuration-layer/lazy-install 'asciidoc :extensions '("\\(\\.adoc?$\\)" adoc-mode)) + +(configuration-layer/lazy-install 'autohotkey :extensions '("\\(\\.ahk\\'\\|\\.ahk$\\)" ahk-mode)) + +(configuration-layer/lazy-install 'clojure :extensions '("\\(\\.\\(clj\\|dtm\\|edn\\)\\'\\|\\(?:build\\|profile\\)\\.boot\\'\\|\\.boot\\'\\)" clojure-mode)) +(configuration-layer/lazy-install 'clojure :extensions '("\\(\\.cljs\\)" clojurescript-mode)) +(configuration-layer/lazy-install 'clojure :extensions '("\\(\\.cljc\\)" clojurec-mode)) +(configuration-layer/lazy-install 'clojure :extensions '("\\(\\.cljx\\)" clojurex-mode)) + +;; common-lisp + +;; csharp + +(configuration-layer/lazy-install 'csv :extensions '("\\(\\.[Cc][Ss][Vv]\\'\\)" csv-mode)) + +(configuration-layer/lazy-install 'd :extensions '("\\(\\.d[i]?\\'\\)" d-mode)) + +(configuration-layer/lazy-install 'elixir :extensions '("\\.\\(ex\\|exs\\|elixir\\)\\'" elixir-mode)) + +(configuration-layer/lazy-install 'elm :extensions '("\\(\\.elm\\'\\)" elm-mode)) + +(configuration-layer/lazy-install 'erlang :extensions '("\\(\\.erl$\\|\\.app\\.src$\\|\\.escript\\|\\.hrl$\\|\\.xrl$\\|\\.yrl\\|/ebin/.+\\.app\\|\\.erl\\'\\|\\.hrl\\'\\)" erlang-mode)) + +;; ess + +(configuration-layer/lazy-install 'finance :extensions '("\\(\\.\\(ledger\\|ldg\\)\\'\\)" ledger-mode)) + +(configuration-layer/lazy-install 'fsharp :extensions '("\\(\\.fs[iylx]?$\\)" fsharp-mode)) + +(configuration-layer/lazy-install 'go :extensions '("\\(\\.go\\'\\)" go-mode)) + +(configuration-layer/lazy-install 'graphviz :extensions '("\\(\\.dot\\'\\|\\.gv\\'\\|\\.diag\\'\\|\\.blockdiag\\'\\|\\.nwdiag\\'\\|\\.rackdiag\\'\\)" graphviz-dot-mode)) + +(configuration-layer/lazy-install 'haskell :extensions '("\\(\\.cmm\\'\\)" cmm-mode)) +(configuration-layer/lazy-install 'haskell :extensions '("\\(\\.[gh]s\\'\\|\\.hsc\\'\\)" haskell-mode)) + +(configuration-layer/lazy-install 'html :extensions '("\\(\\.css\\'\\)" css-mode)) +(configuration-layer/lazy-install 'html :extensions '("\\(\\.haml\\'\\)" haml-mode)) +(configuration-layer/lazy-install 'html :extensions '("\\(\\.jade\\'\\)" jade-mode)) +(configuration-layer/lazy-install 'html :extensions '("\\(\\.less\\'\\)" less-css-mode)) +(configuration-layer/lazy-install 'html :extensions '("\\(\\.sass\\'\\)" sass-mode)) +(configuration-layer/lazy-install 'html :extensions '("\\(\\.scss\\'\\)" scss-mode)) +(configuration-layer/lazy-install 'html :extensions '("\\(\\.slim\\'\\)" slim-mode)) +(configuration-layer/lazy-install 'html :extensions '("\\(\\.phtml\\'\\|\\.tpl\\.php\\'\\|\\.twig\\'\\|\\.html\\'\\|\\.htm\\'\\|\\.[gj]sp\\'\\|\\.as[cp]x?\\'\\|\\.eex\\'\\|\\.erb\\'\\|\\.mustache\\'\\|\\.handlebars\\'\\|\\.hbs\\'\\|\\.eco\\'\\|\\.ejs\\'\\|\\.djhtml\\'\\)" web-mode)) + +(configuration-layer/lazy-install 'idris :extensions '("\\(\\.idr$\\|\\.lidr$\\)" idris-mode)) + +;; java + +(configuration-layer/lazy-install 'javascript :extensions '("\\(\\.coffee\\'\\|\\.iced\\'\\|Cakefile\\'\\|\\.cson\\'\\)" coffee-mode)) +(configuration-layer/lazy-install 'javascript :extensions '("\\(\\.js\\'\\)" js2-mode)) +(configuration-layer/lazy-install 'javascript :extensions '("\\(\\.json$\\)" json-mode)) + +;; latex + +(configuration-layer/lazy-install 'lua :extensions '("\\(\\.lua$\\|\\.lua\\'\\)" lua-mode)) + +(configuration-layer/lazy-install 'nginx :extensions '("\\(nginx\\.conf\\'\\|/nginx/.+\\.conf\\'\\)" nginx-mode)) + +(configuration-layer/lazy-install 'octave :extensions '("\\(\\.m\\'\\)" octave-mode)) + +(configuration-layer/lazy-install 'markdown :extensions '("\\(\\.markdown\\'\\|\\.md\\'\\|\\.m[k]d\\)" markdown-mode)) + +(configuration-layer/lazy-install 'ocaml :extensions '("\\(\\.ml[ip]?\\'\\|\\.eliomi?\\'\\)" tuareg-mode)) + +(configuration-layer/lazy-install 'php :extensions '("\\(\\.amk\\'\\|/Amkfile\\'\\|\\.phtml\\'\\|\\.php[s345t]?\\'\\|[^/]\\.\\(module\\|test\\|install\\|profile\\|tpl\\.php\\|theme\\|inc\\)\\'\\|\\.php\\'\\)" php-mode)) + +(configuration-layer/lazy-install 'purescript :extensions '("\\(\\.purs\\'\\)" purescript-mode)) + +(configuration-layer/lazy-install 'python :extensions '("\\(\\.pyx\\'\\|\\.pxd\\'\\|\\.pxi\\'\\)" cython-mode)) +(configuration-layer/lazy-install 'python :extensions '("\\(\\.hy\\'\\)" hy-mode)) +(configuration-layer/lazy-install 'python :extensions '("\\(\\.pip\\'\\|requirements\\(?:.\\|\n\\)*\\.txt\\'\\)" pip-requirements-mode)) +(configuration-layer/lazy-install 'python :extensions '("\\(\\.py\\'\\)" python-mode)) + +(configuration-layer/lazy-install 'racket :extensions '("\\(\\.rkt[dl]?\\'\\)" racket-mode)) + +;; TODO check how to support for the layer variable `restclient-use-org' +(configuration-layer/lazy-install 'restclient :extensions '("\\(\\.http\\'\\)" restclient-mode)) + +(configuration-layer/lazy-install 'ruby + :extensions '("\\(\\(?:\\.rb\\|ru\\|rake\\|thor\\|jbuilder\\|gemspec\\|podspec\\|/\\(?:Gem\\|Rake\\|Cap\\|Thor\\|Vagrant\\|Guard\\|Pod\\)file\\)\\'\\|Puppetfile\\)" ruby-mode)) + +(configuration-layer/lazy-install 'rust :extensions '("\\(\\.rs\\'\\)" rust-mode)) +(configuration-layer/lazy-install 'rust :extensions '("\\(\\.toml$\\)" toml-mode)) + +;; scala + +;; scheme + +(configuration-layer/lazy-install 'sml :extensions '("\\(\\.s\\(ml\\|ig\\)\\'\\|\\.\\(sml\\|sig\\)\\'\\)" sml-mode)) + +(configuration-layer/lazy-install 'sql :extensions '("\\(\\.sql\\'\\)" sql-mode)) + +(configuration-layer/lazy-install 'swift :extensions '("\\(\\.swift\\'\\)" swift-mode)) + +(configuration-layer/lazy-install 'shell-scripts :extensions '("\\(\\.fish\\'\\|/fish_funced\\..*\\'\\)" fish-mode)) + +(configuration-layer/lazy-install 'typescript :extensions '("\\(\\.ts$\\)" typescript-mode)) + +(configuration-layer/lazy-install 'vimscript :extensions '("\\(\\.vim\\'\\|[._]?g?vimrc\\'\\|\\.exrc\\'\\|_vimrc\\'\\|\\.vim[rc]?\\'\\)" vimrc-mode)) +(configuration-layer/lazy-install 'vimscript :extensions '("\\(_vimperatorrc\\'\\|_pentadactylrc\\'\\|\\.penta\\'\\|vimperatorrc\\'\\|\\.vimp\\'\\|pentadactylrc\\'\\)" dactyl-mode)) + +(configuration-layer/lazy-install 'windows-scripts :extensions '("\\(\\.bat$\\)" dos-mode)) +(configuration-layer/lazy-install 'windows-scripts :extensions '("\\(\\.ps[dm]?1\\'\\|\\.ps1$\\)" powershell-mode)) + +(configuration-layer/lazy-install 'yaml :extensions '("\\(\\.e?ya?ml$\\|\\.\\(yml\\|yaml\\)\\'\\|Procfile\\'\\)" yaml-mode)) diff --git a/news/news01.org b/news/news01.org new file mode 100644 index 0000000..ea2d2cb --- /dev/null +++ b/news/news01.org @@ -0,0 +1,515 @@ +#+TITLE: Newsletter #01: About the 0.200 release + +* Newsletter #01: About the 0.200 release :TOC_4_gh:noexport: + - [[#introduction][Introduction]] + - [[#breaking-changes][Breaking changes]] + - [[#support-for-emacs-243-has-been-dropped][Support for Emacs 24.3 has been dropped]] + - [[#some-modifications-in-the-layer-format][Some modifications in the layer format]] + - [[#controlling-downloaded-packages][Controlling downloaded packages]] + - [[#key-bindings][Key bindings]] + - [[#whats-new-][What's new ?]] + - [[#startup-improvments][Startup improvments]] + - [[#improved-composability][Improved composability]] + - [[#improved-stability][Improved stability]] + - [[#lazy-installation-of-layers][Lazy installation of layers]] + - [[#a-better-hybrid-editing-style][A better hybrid editing style]] + - [[#support-for-ivy][Support for Ivy]] + - [[#better-transient-states][Better transient-states]] + - [[#more-debugging-tools][More debugging tools]] + - [[#new-keyboard-layouts][New keyboard layouts]] + - [[#directory-and-file-local-variables][Directory and file local variables]] + - [[#more-useful-abstraction][More useful abstraction]] + - [[#new-welcome-screen][New welcome screen]] + - [[#about-spacemacs-update-notifications][About Spacemacs update notifications]] + - [[#a-new-community-document][A new community document]] + - [[#the-spacemacs-shop][The Spacemacs shop]] + - [[#whats-next-][What's next ?]] + - [[#even-more-stability][Even more stability]] + - [[#more-consistent-window-behaviour][More consistent window behaviour]] + - [[#new-layers][New layers]] + - [[#a-few-thanks][A few thanks]] + +* Introduction +0.200 is a huge release with more than 1700 commits since the last major version +released in January 2016. Actually it is so big that we jumped directly from +version 0.105 to version 0.200, so don't panic if you think you missed all the +versions since 0.105 :-) + +This first newsletter describes with details the main changes introduced in the +new version and gives some explanation about the various choices made during the +last months. + +The (boring) complete list of changes can be found in the file =CHANGELOG.org= +at the root of the Git repository. + +Let's start with the hottest section: breaking changes! + +* Breaking changes +Before starting with the breaking changes let me begin with a few words about +the motivation behind those changes. Spacemacs moves at an incredible pace +thanks to a big and active community, the project already counts more than 400 +contributors! With such a high number of contributors lots of new ideas are +proposed to constantly evolve and improve the project, some of them make a lot +of sense and we give them priority over backward compatibility, this is +especially true with key bindings. In this release quite a few changes have been +made to the key bindings, some of them are deep changes and anyone using the +develop branch had to adapt to them at some point, the result seems to worth it. + +** Support for Emacs 24.3 has been dropped +The packages ecosystem moves even faster than Spacemacs and a lot of packages +are now incompatible with the version 24.3 of Emacs which has been released +in 2013. Supporting this version in Spacemacs is more and more work for +maintainers so we decided to drop all the 24.3 related code in Spacemacs +effectively raising the minimum Emacs version required to 24.4. We believe that +users are able to switch to a newer version of Emacs, if you need help in this +process you can try the [[https://gitter.im/syl20bnr/spacemacs][Gitter chat]], I'm sure you'll find solutions there. + +** Some modifications in the layer format +We renamed =extensions= directories in layers to =local= and the file +=extensions.el= is now ignored, their contents must be moved to the file +=packages.el= and their package declarations must now set the keyword +=:location= to =local=. + +_Before:_ + +#+BEGIN_SRC emacs-lisp +;; in extensions.el +(setq python-post-extensions + '( + nose + pylookup + python-compile + py-yapf + )) +#+END_SRC + +_After:_ + +#+BEGIN_SRC emacs-lisp +;; in packages.el +(setq python-packages + '( + ;; skipping packages before... + (nose :location local) + (pylookup :location local) + ;; skipping packages after... + )) +#+END_SRC + +The variables =-excluded-packages= are now ignored, they have been +replaced by the =:excluded= keyword in =-packages= variables. + +_Before:_ + +#+BEGIN_SRC emacs-lisp +(setq vim-empty-lines-packages + '( + (vim-empty-lines-mode :location local) + )) + +(setq vim-empty-lines-excluded-packages + '(vi-tilde-fringe)) +#+END_SRC + +_After:_ + +#+BEGIN_SRC emacs-lisp +(setq vim-empty-lines-packages + '( + (vim-empty-lines-mode :location local) + (vi-tilde-fringe :excluded t) + )) +#+END_SRC + +A new file called =layers.el= is in charge of layers dependency, i.e. when a +layer needs to declare additional layers. Previously this was done in the +=config.el= file, to avoid errors you'll have to move the calls to the functions +=configuration-layer/declare-layer= and =configuration-layer/declare-layers= to +a dedicated =layers.el= file. An example can be found in the +[[https://github.com/syl20bnr/spacemacs/blob/564cbc40eda936985325c9b79088fbcb39d9a69d/layers/%2Bdistributions/spacemacs/layers.el][spacemacs distribution layer]]. + +** Controlling downloaded packages +The method to install all packages supported by Spacemacs has been improved. The +old way was to set the variable =dotspacemacs-configuration-layers= to the value +=all=. This method had several major drawbacks like forcing all layers to be +marked as =used= and it triggered various bad side effects. We removed the +support for the value =all=. + +A new variable =dotspacemacs-install-packages= is now dedicated to control what +packages are downloaded by Spacemacs. Three behaviours are supported: +- =used-only= (default) will download only the used packages +- =used-but-keep-unused= will download only the used packages but won't uninstall + them if they become unused +- =all= will download _all_ the supported packages by Spacemacs. + +** Key bindings +Here is the scary section, the one feared by most users :-) Let be honest, there +is a rather big amount of changes for users jumping from master 0.105 to 0.200. + +First of all the most visible change is for ~SPC SPC~ which triggers now ~M-x~ +instead of =avy= to jump to a character. The ~SPC~ key in Spacemacs is a central +key as it acts as the leader key for _all_ the key bindings, it made sense to +give the same sense of "root" key to the sequence ~SPC SPC~, so now ~SPC SPC~ is +the central sequence to execute _any_ interactive function in Emacs. + +Where is the =avy= command then ? We reorganised from the ground up the prefix +~SPC j~ for all jump commands. In the conventions a doubled key is often used +for the default command under a given prefix, for instance ~SPC b b~ is for +buffer selection, ~SPC f f~ for file selection etc... The "jump to character" +command of =avy= is then under ~SPC j j~. Here is a detailed list of the new +~SPC j~ prefix: +- =avy= commands are now behind the prefix ~SPC j~ for =jump=: + - ~SPC j j~ to jump to a character in the buffer (works as an evil motion) + - ~SPC j l~ to jump to a line with avy (works as an evil motion) + - ~SPC j w~ to jump to a word in the current buffer (works as an evil motion) +- the following key bindings have been moved: + - ~SPC j j~ to split a line has been moved to ~SPC j n~ (mnemonic is New line) + - ~SPC j h~ and ~SPC j l~ have been moved to ~SPC j 0~ and ~SPC j $~ + respectively. + - ~SPC J~ to split a string or sexp has been moved to ~SPC j s~ + +A lot of other handy commands are under this prefix, I let you discover them with +the =which key= menus. + +Closing, deleting or killing things ? This can be a tough call to distinguish +them and we can find such confusion in the Spacemacs key bindings, for instance +we close a window but we delete a buffer and we can also kill a buffer. Whereas +it can make sense for a lot of users, there are still users finding this +confusing. So we decided to simplify the notion of "closing/deleting" things +under the ~d~ key for =delete=. We moved ~SPC w c~ and ~SPC w C~ to ~SPC w d~ +and ~SPC w D~. + +More generally we tried to map prefixes ~SPC b~ and ~SPC w~ to the same actions +and bring a convention with =avy= commands with the capital letter to manipulate +windows and buffers. The result is detailed here: +- ~SPC b k~ has been removed. +- ~SPC b C-k~ (kill buffer matching regexp) is now ~SPC b C-d~ +- ~SPC b m~ (buffer move) has been removed because the functionality + is available via ~SPC w~ with ~SPC w h/j/k/l~, ~SPC w H/J/K/L~ and + ~SPC w M~. +- ~SPC b K~ (kill other buffers) is now ~SPC b m~ to map with ~SPC w m~ + (maximize buffer/window which effectively delete other windows). +- ~SPC b D~ now kills a buffer using =ace-window=. +- Buffer actions don't delete the windows by default, use the universal + prefix argument to do so, for instance ~SPC u SPC b d~ and ~SPC u SPC b D~ + will delete the buffer and also the window. Another example is + ~SPC u SPC b m~ to maximize a buffer. + +=Helm= has a new friend in this release, it is called =ivy= and it has more and +more adopters. Since we have now a new package capable of doing =helm= commands +we decided to remove all =helm= related command from the prefix ~SPC h~. ~SPC h~ +is now exclusively for _help_ commands and the following =helm= commands has +been moved: +- ~SPC h b~ for =helm-filetered-bookmarks~is now ~SPC f b~ +- ~SPC h l~ for =helm-resume= is now ~SPC r l~ +- ~SPC h L~ for =helm-locate-library= is now ~SPC f e l~ + +The =git= related commands have been drastically simplified to leverage the +=magit= dispatch menu. Instead of replicating all the =magit= dispatch keys +under the ~SPC g~ prefix we now only define the key binding ~SPC g m~ to display +the =magit= dispatch menu. We get several benefits by doing so: first we free up +a lot of valuable keys under ~SPC g~, second we have now more consistent key +bindings since we always use the =magit= dispatch menu. Previously we have some +actions bound to different keys between ~SPC g~ and the =magit= dispatch menu +accessible under ~?~. The new available keys allowed us to move some key +bindings directly under ~SPC g~ like =git-link= which is now under ~SPC g l~, +it makes more sense to have it under ~SPC g l~ since it is agnostic of the +hosting platform (i.e. it works with =GitHub=, =GitLab= etc...). + +Spacemacs layouts now restrict the scope of the buffer list opened with +~SPC b b~. Use ~SPC b B~ to list all the buffers of all the layouts. Also +~1,2,...,9,0~ keys now select a layout and close the layout menu, use +~C-1,C-2,...,C-9,C-0~ to switch to a layout and keep the menu opened. + +To conclude this section about key binding changes and breaking changes the +=micro-states= in Spacemacs are dead, say hi to the =transient-states=. We took +advantage of the =micro-states= refactoring to change the name to a more +accurate new name =transient-states=, indeed these states leverage the notion +of transient maps in Emacs. The refactoring replaces the custom back-end by +=hydra= a powerful and very popular package to define transient maps. In effect +the macro =spacemacs|define-micro-state= is deprecated and is replaced by the +new =hydra= powered macro =spacemacs|define-transient-state=. + +* What's new ? +** Startup improvments +The layer system has been rewritten to index packages information, the startup +time of Spacemacs should be reduced by 20~25%. Also this refactoring will better +scale as we add new layers and packages to the distribution. + +** Improved composability +The =spacemacs= distribution layer has been split into several layers under +the =spacemacs= directory. The user can now very easily customize her Spacemacs +experience by choosing the =spacemacs-base= distribution and using only the +=spacemacs= layers she wants. + +An exhaustive list of all the =spacemacs= layers: +- spacemacs-completion +- spacemacs-editing +- spacemacs-editing-visual +- spacemacs-evil +- spacemacs-language +- spacemacs-layouts +- spacemacs-misc +- spacemacs-org +- spacemacs-ui +- spacemacs-ui-visual + +For people wanting an even more bare Emacs experience try the distribution +layer =spacemacs-bootstrap= which installs only essential packages like +=use-package=, =which-key=, etc... + +Also it is easier to select or exclude a sub-list of packages in a layer with +the new keyword =:packages=. For instance here is an example to select only the +packages =fill-column-indicator= and =golden-ratio= in the layer +=spacemacs-ui-visual=: + +#+BEGIN_SRC emacs-lisp +(setq dotspacemacs-configuration-layers + (spacemacs-ui-visual :packages fill-column-indicator golden-ratio)) +#+END_SRC + +Another example to select all the packages except =fancy-battery=: + +#+BEGIN_SRC emacs-lisp +(setq dotspacemacs-configuration-layers + (spacemacs-ui-visual :packages (not fancy-battery)) +#+END_SRC + +** Improved stability +This is one of the Achilles' heel of Spacemacs. We rely on bleeding edge version +of packages from =melpa= repository to install a fresh version of Spacemacs. If +the repository is down then no sugar, try again later. + +With 0.200 we introduce [[https://github.com/syl20bnr/spacemacs-elpa-mirror][mirrors]] for all =elpa= repositories used by Spacemacs. +If one of them is down then Spacemacs falls back on the mirror hosted on GitHub. +Obviously the fall-back repository should not be used as a primary repository +and should only be used when official =elpa= repositories are down. + +It is also possible to freeze packages by adding their name to the new variable +=dotspacemacs-frozen-packages=. Frozen packages cannot be updated or rollbacked. +This is useful if a package upstream needs a fix, the package can be frozen +until the fix is released. + +Packages can be stored in different =elpa= directories, the most useful setting +is maybe to define a different directory per Emacs version. You can do it by +setting the new variable =dotspacemacs-elpa-subdirectory= to the value +=emacs-version=. By default the value of this variable is =nil= which means that +all packages are installed in the same =elpa= directory. + +** Lazy installation of layers +A feature borrowed to [[https://github.com/bbatsov/prelude][Prelude]] distribution and adapted to the layers, it +allows to install a layer and all its packages when opening a new file with a +supported extension. + +For instance, when opening an Elixir file with extension =.ex= Spacemacs will +ask to install the =elixir= layer if it is not already used. The =elixir= layer +is automatically added to the dotfile so it won't be uninstalled after a +restart. + +By default this feature is _disabled_, you have to opt-in for it by setting +the variable =dotspacemacs-enable-lazy-installation= to one of the following +values: +- =unused= to lazy install only layers not listed in + =dotspacemacs-configuration-layers= +- =all= to lazy install any layer supporting lazy installation (i.e. even the + used layers won't be installed at startup until you open a file with a + supported extension). + +** A better hybrid editing style +The Hybrid state wanders between the Emacs style and the Evil style, three +new variables allow to fine tune the Hybrid style experience: +- =hybrid-mode-enable-evilified-state=, if non nil then buffers are evilified, +- =hybrid-mode-enable-hjkl-bindings=, if non nil navigation on ~hjkl~ keys is + enabled (for instance in =helm= or =ivy= buffers), +- =hybrid-mode-default-state=, the default state when opening a new buffer, + by default it is =normal=. + +To define these new variables use the =:variables= keyword. For example: + +#+BEGIN_SRC emacs-lisp +(setq dotspacemacs-editing-style '(hybrid :variables + hybrid-mode-enable-evilified-state t + hybrid-mode-enable-hjkl-bindings t + hybrid-mode-default-state 'normal)) +#+END_SRC + +** Support for Ivy +The community has made a wonderful work to bring [[https://github.com/abo-abo/swiper][ivy]] support to Spacemacs. + +Want to switch from =helm= to =ivy= ? This is as simple as adding the =ivy= +layer to your dotfile and reloading it with ~SPC f e R~! + +The level of feature of the =ivy= layer is pretty on par with the =helm= layer, +this is a fantastic work and it demonstrates all the power of a community-driven +configuration. I'm really excited by this new feature and how it is so easy to +enjoy it. Nice work guys! + +** Better transient-states +=Transient-states= replace the =micro-states=. They are powered by [[https://github.com/abo-abo/hydra][hydra]] +making =hydra= part of the bootstrap packages (pillars of the distribution). +=Hydra= is now 100% supported in Spacemacs and does not require hacks to +work correctly. + +We tried to get consistent =transient-states= in all the layers by keeping +the same documentation strings format everywhere. + +** More debugging tools +Emacs comes with lots of tools to help the user to debug their configuration. +Spacemacs adds several concepts which can make harder for a user to debug +his configuration, especially the layer system. + +In this new release we are eager to introduce new easy way to debug your +configuration: +- press ~SPC q d~ to restart Emacs in debug mode with command line parameter + =--debug-init= fed in for you +- press ~SPC q D~ to restart Emacs with a selected list of packages to load, + in this mode Spacemacs is completely disabled so you get the perfect way + to test wether a bug comes from Spacemacs configuration or not +- press ~SPC h I~ to open an org buffer with an issue template, fill it then + press ~C-c C-c~ to submit it with your default internet browser. + +Along with these new key bindings, new Spacemacs specific command line +parameters are available to help you change the scope of an issue investigation: +- =--no-layer= deactivates all the layers _except_ the distribution layer +- =--distribution x= allows to change temporarily the distribution to =x=. + +This is a good time to remind you about the other useful Spacemacs specific +command line parameters: +- =--profile== will display profiling information on startup +- =--timed-requires= will display the time taken by each =require= commands +- =--adv-timers n= will display any load time greater than =n=. + +** New keyboard layouts +A new layer =keyboard-layout= aims to provide the tools to define more easily +new keyboard layouts. This release ships with support for =bépo= and =dvorak= +layouts. + +Be sure to follow the =README.org= of the =keyboard-layout= layer for more +information about layout definition. + +** Directory and file local variables +[[https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html][Per-directory and file local variables]] are a standard feature of Emacs, we try +to leverage them starting with 0.200. Some layers support several tools to do +the same thing, for instance in the =ruby= layer both =rspec= and =ruby-test= +are supported to run tests; the =haskell= layer supports several completion +back-ends like =intero= and =ghci=. Those tools or back-ends are project +specific so providing only a global value for them is not enough. With 0.200 +these layers become compatible with directory local variables so the test engine +for =ruby= or the completion back-end for =haskell= can be setup differently for +different directories (i.e. projects). + +Supporting directory and file local variable dynamically greatly improves the +flexibility of Spacemacs and make it an even better choice to handle various +types of projects. We don´t support multiple options for the sake of supporting +them but for a more robust solution capable to deal easily with your day-to-day +requirements. + +** More useful abstraction +We have even more abstraction of useful concepts in 0.200 like jumping to the +definition of a symbol or opening a REPL. + +Like text searching tools, there is now the concept of jump handlers, each mode +can set a list of jump handlers and Spacemacs will try them in order to get you +to a symbol definition. This new abstraction alows to merge the different +jumping tools under the same key binding, for instance =dumb-jump=, =tags= +etc... + +All supported REPLs are now registered in a list and you can run any registered +REPL with ~SPC a '~. + +** New welcome screen +The contents of the welcome screen are now centered, there is also a nice new +footer. +The contents are recentered when the window is resized, to disable this +behaviour set the variable =dotspacemacs-startup-buffer-responsive= to =nil=. + +Sizes of lists in the welcome screen can be customized independently for each +list with the variable =dotspacemacs-startup-list=, for instance the following +value will display a maximum of 5 items for the recent files list and a maximum +of 7 items for the projects list: + +#+BEGIN_SRC emacs-lisp +(setq dotspacemacs-startup-lists '((recents . 5) + (projects . 7))) +#+END_SRC + +There are two new lists of items which can be displayed on the welcome screen: +- agenda +- todos + +** About Spacemacs update notifications +In previous versions Spacemacs checked for a new version at every startup of +Emacs and every 6 hours. It was [[https://github.com/syl20bnr/spacemacs/issues/6692][stressing the GitHub infrastructure]] enough to +make GitHub throttle down the traffic for the repository. + +In this version we changed the notification frequency and took several measures +to reduce the =git= commands monitored by GitHub: +- reduce number of required git commands per check from 3 to 1 +- remove recurrent version check every 6 hours, i.e. the check happens only + at startup +- rate limit the checks to once per day +- change default value of variable =dotspacemacs-check-for-update= to =nil= +- make function =spacemacs/check-for-new-version= interactive so checking + for a new version can be done on demand. + +If you want automatic check of new version you have now to opt-in by setting +=dotspacemacs-check-for-update= to =t=. + +** A new community document +At the root of the project directory the new file =COMMUNITY.org= describes +the values of the project and the moderation rules. There is also an exhaustive +list of the moderation actions taken by collaborators. + +** The Spacemacs shop +You can now show your support for Spacemacs by buying tee-shirts and goodies +in the new [[https://shop.spreadshirt.com/spacemacs-shop][Spacemacs shop]]! + +There is a limited number of models for women but all the men tee-shirts +will be available for women as well in the coming weeks! + +* What's next ? +** Even more stability +=Elpa= mirrors are a good start but it does not fix the bleeding edge packages +issue, especially when installing a fresh version of Spacemacs. + +For 0.201 we plan to introduce stable snapshots of =elpa= repositories, a new +installation of Spacemacs will always install packages from this stable source. +Users will then be able to manually trigger an upgrade of packages if they +want the bleeding edge versions but they will always be able to rollback to the +previous stable state if required. + +** More consistent window behaviour +One of the main focus for 0.201 will be to integrate [[https://github.com/bmag/emacs-purpose][emacs-purpose]]. It is a +package to display buffer in the same windows. The current pull request is very +popular and I'm sure you'll like what it will bring to the Spacemacs experience. + +** New layers +Pull requests with new layers are low on the priority list because reviewing +them is more time consuming. For 0.201 I'll focus on all the pull requests with +new layers in order to speed up the merge so you can expect more new layers for +0.201 than 0.200. + +* A few thanks +This first newsletter is a great opportunity to thanks the Emacs community and +more specifically: + +- =Justin Burkett= (aka [[https://github.com/justbur][justbur]]) and =Fabien Dubosson= (aka [[https://github.com/StreakyCobra][StreakyCobra]]) + who were collaborators during several months. This version would not be so + awesome without their dedicated involvement. We wish them all the success in + their future projects. + +- =Boris= (aka [[https://github.com/d12frosted][d12frosted]]) who joined =TheBB= and myself as collaborator. + +- Of course the unique =Eivind Fonn= (aka [[https://github.com/TheBB][TheBB]]) without his constant support + Spacemacs could not be successful and I think I would have burn-out a long + time ago. + +- All the package maintainers, especially =Oleh Krehel= (aka [[https://github.com/abo-abo][abo-abo]]) for the + great help with =ivy= and obviously =Frank Fischer= (aka [[https://bitbucket.org/lyro/][lyro]]) the author + of =evil=. + +- In no specific order: =Diego Berrocal= (aka [[https://github.com/CestDiego][CestDiego]]), [[https://github.com/bmag][bmag]], [[https://github.com/NJBS][NJBS]], + =Eugene Yaremenko= (aka [[https://github.com/JAremko][JAremko]]), [[https://github.com/travisbhartwell][Travis B. Hartwell]], =Tristan Hume= + (aka [[https://github.com/trishume][trishume]]) + +- All the Spacemacs community, you are the heart of Spacemacs! diff --git a/private/README.md b/private/README.md new file mode 100644 index 0000000..f6aaf99 --- /dev/null +++ b/private/README.md @@ -0,0 +1,21 @@ +# Private directory + +The content of this directory is ignored by Git. This is the default place +where to store your private configuration layers. + +To create a new configuration layer: + + SPC SPC configuration-layer/create-layer RET + +Then enter the name of your configuration in the prompt. + +A directory named after the created configuration layer will be created here +along with template files within it (packages.el and extensions.el, more info +on the meaning of those files can be found in the [documentation][conf_layers]). + +Each created file has further guidance written in them. + +Once the configuration is done, restart Emacs to load, install and configure +your layer. + +[conf_layers]: https://github.com/syl20bnr/spacemacs/blob/master/doc/DOCUMENTATION.org#extensions-and-packages diff --git a/private/local/README.md b/private/local/README.md new file mode 100644 index 0000000..0377f7b --- /dev/null +++ b/private/local/README.md @@ -0,0 +1,6 @@ +# Private directory for local packages + +The content of this directory is ignored by Git. + +This is the place to store the local packages that you define in +the `dotspacemacs-additional-packages` variable of your dotfile. diff --git a/private/snippets/README.md b/private/snippets/README.md new file mode 100644 index 0000000..ac70b84 --- /dev/null +++ b/private/snippets/README.md @@ -0,0 +1,6 @@ +# Private directory for Yasnippets snippets + +The content of this directory is ignored by Git. This is the default place +where to store your private yasnippets. + +This path will be loaded automatically and used whenever Yasnippets loads. diff --git a/spacemacs.mk b/spacemacs.mk new file mode 100644 index 0000000..a9b5993 --- /dev/null +++ b/spacemacs.mk @@ -0,0 +1,41 @@ +## Makefile --- Spacemacs master makefile +## +## Copyright (c) 2012-2016 Sylvain Benner & Contributors +## +## Author: Sylvain Benner +## URL: https://github.com/syl20bnr/spacemacs +## +## This file is not part of GNU Emacs. +## +## License: GPLv3 + +EMACS_DIR = $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) +TEST_NAME = `basename $(TEST_DIR) | tr a-z A-Z` + +all: test + +test: unit_tests func_tests + +ifneq ($(strip $(UNIT_TEST_FILES)),) +unit_tests: + @echo "=================================================================" + @echo "UNIT TESTS FOR $(TEST_NAME)" + @echo "=================================================================" + @emacs -batch -l ert \ + $(addprefix -l $(EMACS_DIR)/, $(LOAD_FILES)) \ + $(addprefix -l $(TEST_DIR)/, $(UNIT_TEST_FILES)) \ + -f ert-run-tests-batch-and-exit +endif + +ifneq ($(strip $(FUNC_TEST_FILES)),) +func_tests: + @echo "=================================================================" + @echo "FUNCTIONAL TESTS FOR $(TEST_NAME)" + @echo "=================================================================" + @emacs -batch -l ert \ + $(addprefix -l $(EMACS_DIR)/, $(LOAD_FILES)) \ + $(addprefix -l $(TEST_DIR)/, $(FUNC_TEST_FILES)) \ + -f ert-run-tests-batch-and-exit +endif + +.PHONY: test unit_tests func_tests diff --git a/tests/core/Makefile b/tests/core/Makefile new file mode 100644 index 0000000..b3d0dff --- /dev/null +++ b/tests/core/Makefile @@ -0,0 +1,24 @@ +## Makefile --- Spacemacs Core +## +## Copyright (c) 2012-2016 Sylvain Benner & Contributors +## +## Author: Sylvain Benner +## URL: https://github.com/syl20bnr/spacemacs +## +## This file is not part of GNU Emacs. +## +## License: GPLv3 + +TEST_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) + +LOAD_FILES = core/core-load-paths.el +UNIT_TEST_FILES = \ + core-configuration-layer-utest.el \ + core-funcs-utest.el +FUNC_TEST_FILES = \ + core-spacemacs-ftest.el \ + core-spacemacs-buffer-ftest.el \ + core-configuration-layer-ftest.el \ + core-release-management-ftest.el + +include ../../spacemacs.mk diff --git a/tests/core/core-configuration-layer-ftest.el b/tests/core/core-configuration-layer-ftest.el new file mode 100644 index 0000000..1f34585 --- /dev/null +++ b/tests/core/core-configuration-layer-ftest.el @@ -0,0 +1,36 @@ +;;; core-configuration-layer-ftest.el --- Spacemacs Functional Test File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(require 'core-configuration-layer) + +;; --------------------------------------------------------------------------- +;; configuration-layer//declare-used-layers +;; --------------------------------------------------------------------------- + +(ert-deftest test-declare-layers--bootstrap-layer-always-first () + (let ((dotspacemacs-distribution 'spacemacs) + (dotspacemacs-configuration-layers '(emacs-lisp + (git :variables foo 'bar))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024))) + (configuration-layer/discover-layers) + (configuration-layer//declare-used-layers dotspacemacs-configuration-layers) + (should (eq 'spacemacs-bootstrap + (first configuration-layer--used-layers))))) + +(ert-deftest test-declare-layers--distribution-layer-is-second () + (let ((dotspacemacs-distribution 'spacemacs-base) + (dotspacemacs-configuration-layers '(emacs-lisp + (git :variables foo 'bar))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024))) + (configuration-layer/discover-layers) + (configuration-layer//declare-used-layers dotspacemacs-configuration-layers) + (should (eq 'spacemacs-base (second configuration-layer--used-layers))))) diff --git a/tests/core/core-configuration-layer-utest.el b/tests/core/core-configuration-layer-utest.el new file mode 100644 index 0000000..2f451c8 --- /dev/null +++ b/tests/core/core-configuration-layer-utest.el @@ -0,0 +1,2194 @@ +;;; core-configuration-layer-utest.el --- Spacemacs Unit Test File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(require 'mocker) +(require 'core-command-line) +(require 'core-configuration-layer) + +(defun helper--set-layers (layers &optional usedp) + "Set the layer variables given a list of LAYERS objects." + (dolist (layer layers) + (configuration-layer//add-layer layer usedp))) + +(defun helper--set-packages (packages &optional usedp) + "Set the package variables given a list of PACKAGES objects." + (dolist (pkg packages) + (configuration-layer//add-package pkg usedp))) + +;; --------------------------------------------------------------------------- +;; class cfgl-layer +;; --------------------------------------------------------------------------- + +;; method: cfgl-layer-owned-packages + +(ert-deftest test-cfgl-layer-owned-packages--owns-packages () + (let ((layer1 (cfgl-layer "layer1" + :name 'layer1 + :packages '(pkg1 pkg2 pkg3 pkg4))) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (helper--set-packages + (list (cfgl-package "pkg1" :name 'pkg1 :owners '(layer2)) + (cfgl-package "pkg2" :name 'pkg2 :owners '(layer1)) + (cfgl-package "pkg3" :name 'pkg3 :owners '(layer1)) + (cfgl-package "pkg4" :name 'pkg4 :owners '(layer2))) t) + (should (equal (list (cfgl-package "pkg2" :name 'pkg2 :owners '(layer1)) + (cfgl-package "pkg3" :name 'pkg3 :owners '(layer1))) + (cfgl-layer-owned-packages layer1))))) + +(ert-deftest test-cfgl-layer-owned-packages--nil-layer-returns-nil () + (should (null (cfgl-layer-owned-packages nil)))) + +;; method: cfgl-layer-get-packages + +(ert-deftest test-cfgl-layer-get-packages--all-packages-selected-default () + (let ((layer (cfgl-layer "layer" + :name 'layer + :packages '((pkg1 :location local) + pkg2 + (pkg3 :location built-in))))) + (should (equal '((pkg1 :location local) pkg2 (pkg3 :location built-in)) + (cfgl-layer-get-packages layer))))) + +(ert-deftest test-cfgl-layer-get-packages--all-packages-selected-explicitly () + (let ((layer (cfgl-layer "layer" + :name 'layer + :packages '((pkg1 :location local) + pkg2 + (pkg3 :location built-in)) + :selected-packages 'all))) + (should (equal '((pkg1 :location local) pkg2 (pkg3 :location built-in)) + (cfgl-layer-get-packages layer))))) + +(ert-deftest test-cfgl-layer-get-packages--selected-packages () + (let ((layer (cfgl-layer "layer" + :name 'layer + :packages '((pkg1 :location local) + pkg2 + (pkg3 :location built-in)) + :selected-packages '(pkg1 pkg2)))) + (should (equal '((pkg1 :location local) pkg2) + (cfgl-layer-get-packages layer))))) + +(ert-deftest test-cfgl-layer-get-packages--selected-packages-ignore-unknown () + (let ((layer (cfgl-layer "layer" + :name 'layer + :packages '((pkg1 :location local) + pkg2 + (pkg3 :location built-in)) + :selected-packages '(pkg1 pkg2 pkg-unknown)))) + (should (equal '((pkg1 :location local) pkg2) + (cfgl-layer-get-packages layer))))) + +(ert-deftest test-cfgl-layer-get-packages--nil-packages-return-nil () + (let ((layer (cfgl-layer "layer" + :name 'layer + :packages '()))) + (should (null (cfgl-layer-get-packages layer))))) + +(ert-deftest test-cfgl-layer-get-packages--nil-packages-with-unknown-selected-packages-return-nil () + (let ((layer (cfgl-layer "layer" + :name 'layer + :packages '() + :selected-packages '(pkg-unknown)))) + (should (null (cfgl-layer-get-packages layer))))) + +;; --------------------------------------------------------------------------- +;; class cfgl-package +;; --------------------------------------------------------------------------- + +;; method: cfgl-package-enabledp + +(ert-deftest test-cfgl-package-enabledp--default-toggle-eval-non-nil () + (let ((pkg (cfgl-package "testpkg" :name 'testpkg))) + (should (cfgl-package-enabledp pkg)))) + +(ert-deftest test-cfgl-package-enabledp--symbol-toggle-eval-non-nil-example () + (let ((pkg (cfgl-package "testpkg" :name 'testpkg :toggle 'package-toggle)) + (package-toggle t)) + (should (cfgl-package-enabledp pkg)))) + +(ert-deftest test-cfgl-package-enabledp--symbol-toggle-eval-nil-example () + (let ((pkg (cfgl-package "testpkg" :name 'testpkg :toggle 'package-toggle)) + (package-toggle nil)) + (should (null (cfgl-package-enabledp pkg))))) + +(ert-deftest test-cfgl-package-enabledp--list-toggle-eval-non-nil-example () + (let ((pkg (cfgl-package "testpkg" + :name 'testpkg + :toggle '(memq package-toggle '(foo bar)))) + (package-toggle 'foo)) + (should (cfgl-package-enabledp pkg)))) + +(ert-deftest test-cfgl-package-enabledp--list-toggle-eval-nil-example () + (let ((pkg (cfgl-package "testpkg" + :name 'testpkg + :toggle '(memq package-toggle '(foo bar)))) + (package-toggle 'other)) + (should (null (cfgl-package-enabledp pkg))))) + +;; method: cfgl-package-get-safe-owner + +(ert-deftest test-cfgl-package-get-safe-owner--return-car () + (let ((pkg (cfgl-package "testpkg" :name 'testpkg :owners '(layer1 layer2))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024))) + (helper--set-layers `(,(cfgl-layer "layer1" :name 'layer1) + ,(cfgl-layer "layer2" :name 'layer2)) t) + (should (eq 'layer1 (cfgl-package-get-safe-owner pkg))))) + +(ert-deftest test-cfgl-package-get-safe-owner--return-cadr () + (let ((pkg (cfgl-package "testpkg" :name 'testpkg :owners '(layer1 layer2))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024))) + ;; layer1 is not used so it cannot be the owner + (helper--set-layers `(,(cfgl-layer "layer1" :name 'layer1))) + (helper--set-layers `(,(cfgl-layer "layer2" :name 'layer2)) t) + (should (eq 'layer2 (cfgl-package-get-safe-owner pkg))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer//resolve-package-archives +;; --------------------------------------------------------------------------- + +(ert-deftest test-resolve-package-archives--simple-https () + (let ((input '(("melpa" . "melpa.org/packages/"))) + (dotspacemacs-elpa-https t)) + (should (equal '(("melpa" . "https://melpa.org/packages/")) + (configuration-layer//resolve-package-archives input))))) + +(ert-deftest test-resolve-package-archives--simple-http () + (let ((input '(("melpa" . "melpa.org/packages/"))) + dotspacemacs-elpa-https) + (should (equal '(("melpa" . "http://melpa.org/packages/")) + (configuration-layer//resolve-package-archives input))))) + +(ert-deftest test-resolve-package-archives--org-supports-http () + (let ((input '(("org" . "orgmode.org/elpa/"))) + dotspacemacs-elpa-https) + (should (equal '(("org" . "http://orgmode.org/elpa/")) + (configuration-layer//resolve-package-archives input))))) + +(ert-deftest test-resolve-package-archives--org-does-not-support-https () + (let ((input '(("org" . "orgmode.org/elpa/"))) + (dotspacemacs-elpa-https t)) + (should (equal '(("org" . "http://orgmode.org/elpa/")) + (configuration-layer//resolve-package-archives input))))) + +(ert-deftest test-resolve-package-archives--idempotent-when-already-http-prefix () + (let ((input '(("melpa" . "http://melpa.org/packages/"))) + (dotspacemacs-elpa-https t)) + (should (equal '(("melpa" . "http://melpa.org/packages/")) + (configuration-layer//resolve-package-archives input))))) + +(ert-deftest test-resolve-package-archives--idempotent-when-already-https-prefix () + (let ((input '(("melpa" . "https://melpa.org/packages/"))) + dotspacemacs-elpa-https) + (should (equal '(("melpa" . "https://melpa.org/packages/")) + (configuration-layer//resolve-package-archives input))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer/retrieve-package-archives +;; --------------------------------------------------------------------------- + +(ert-deftest test-retrieve-package-archives--catch-time-out-error () + (let ((package-archives '(("gnu" . "https://elpa.gnu.org/packages/"))) + (configuration-layer--package-archives-refreshed nil) + (dotspacemacs-elpa-timeout -1)) + (mocker-let + ((message (format-string &rest args) + ((:record-cls 'mocker-stub-record :output nil)))) + (configuration-layer/retrieve-package-archives)))) + +(ert-deftest test-retrieve-package-archives--catch-connection-errors () + (let ((package-archives '(("gnu" . "https://elpa.gnu.org/packages/"))) + (configuration-layer--package-archives-refreshed nil)) + (cl-letf (((symbol-function 'url-retrieve-synchronously) + (lambda (x) + (signal 'file-error '("make client process failed" + "connection refused" + :name "elpa.gnu.org" + :buffer dummy + :host "elpa.gnu.org" + :service 443 + :nowait nil)))) + ((symbol-function 'message) 'ignore)) + (configuration-layer/retrieve-package-archives)))) + +;; --------------------------------------------------------------------------- +;; configuration-layer//select-packages +;; --------------------------------------------------------------------------- + +(ert-deftest test-select-packages--all-is-default () + (let ((layer '(layer :variables var1 t var2 t)) + (packages '((pkg1 :location local) pkg2))) + (should (eq 'all (configuration-layer//select-packages layer packages))))) + +(ert-deftest test-select-packages--all-returns-all () + (let ((layer '(layer :variables var1 t var2 t :packages all)) + (packages '((pkg1 :location local) pkg2))) + (should (eq 'all (configuration-layer//select-packages layer packages))))) + +(ert-deftest test-select-packages--select-packages () + (let ((layer '(layer :variables var1 t var2 t :packages pkg1 pkg3)) + (packages '((pkg1 :location local) + pkg2 + pkg3 + (pkg4 :location built-in)))) + (should (equal '(pkg1 pkg3) + (configuration-layer//select-packages layer packages))))) + +(ert-deftest test-select-packages--unselect-packages-with-a-list () + (let ((layer '(layer :variables var1 t var2 t :packages (not pkg1 pkg3))) + (packages '((pkg1 :location local) + pkg2 + pkg3 + (pkg4 :location built-in)))) + (should (equal '(pkg2 pkg4) + (configuration-layer//select-packages layer packages))))) + +(ert-deftest test-select-packages--unselect-packages-without-a-list () + (let ((layer '(layer :variables var1 t var2 t :packages not pkg1 pkg3)) + (packages '((pkg1 :location local) + pkg2 + pkg3 + (pkg4 :location built-in)))) + (should (equal '(pkg2 pkg4) + (configuration-layer//select-packages layer packages))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer/make-layer +;; --------------------------------------------------------------------------- + +(ert-deftest test-make-layer--make-layer-from-symbol-with-a-dir () + (should (equal (cfgl-layer "layer" + :name 'layer + :dir spacemacs-start-directory) + (configuration-layer/make-layer + 'layer nil nil spacemacs-start-directory)))) + +(ert-deftest test-make-layer--make-layer-from-spec-with-a-dir () + (should (equal (cfgl-layer "layer" + :name 'layer + :dir spacemacs-start-directory) + (configuration-layer/make-layer + '(layer :name 'layer) nil nil spacemacs-start-directory)))) + +(ert-deftest test-make-layer--cannot-make-layer-without-a-directory () + (mocker-let + ((configuration-layer//warning + (msg &rest args) + ((:record-cls 'mocker-stub-record :output nil :occur 1)))) + (should (null (configuration-layer/make-layer 'layer))))) + +(ert-deftest test-make-layer--cannot-make-layer-with-a-non-existing-directory () + (mocker-let + ((configuration-layer//warning + (msg &rest args) + ((:record-cls 'mocker-stub-record :output nil :occur 1)))) + (should (null (configuration-layer/make-layer 'layer nil nil "/a/dir/"))))) + +(ert-deftest test-make-layer--make-layer-without-a-dir-requires-an-initial-obj () + (let ((layer (cfgl-layer "layer" + :name 'layer + :dir spacemacs-start-directory))) + (should (equal (cfgl-layer "layer" + :name 'layer + :dir spacemacs-start-directory) + (configuration-layer/make-layer 'layer layer))))) + +(ert-deftest test-make-layer--make-used-layer-loads-packages-file () + (let ((layer (cfgl-layer "layer" + :name 'layer + :dir spacemacs-start-directory)) + (layer-packages '(pkg1 pkg2 pkg3)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (mocker-let + ((file-exists-p (f) ((:output t :occur 2))) + (load (f) ((:output nil :occur 1)))) + (should (equal (cfgl-layer "layer" + :name 'layer + :disabled-for nil + :variables nil + :packages '(pkg1 pkg2 pkg3) + :selected-packages 'all + :dir spacemacs-start-directory) + (configuration-layer/make-layer 'layer layer 'used)))))) + +(ert-deftest test-make-layer--make-layer-force-load-packages-file-with-var () + (let ((layer (cfgl-layer "layer" + :name 'layer + :dir spacemacs-start-directory)) + (layer-packages '(pkg1 pkg2 pkg3)) + (configuration-layer--load-packages-files t) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (mocker-let + ((file-exists-p (f) ((:output t :occur 2))) + (load (f) ((:output nil :occur 1)))) + (should (equal (cfgl-layer "layer" + :name 'layer + :disabled-for nil + :variables nil + :packages '(pkg1 pkg2 pkg3) + :selected-packages 'all + :dir spacemacs-start-directory) + (configuration-layer/make-layer 'layer layer)))))) + +(ert-deftest test-make-layer--make-layer-does-not-load-packages-file-by-default () + (let ((layer (cfgl-layer "layer" + :name 'layer + :dir spacemacs-start-directory)) + (layer-packages '(pkg1)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (mocker-let + ((file-exists-p (f) ((:output t :occur 1)))) + (configuration-layer/make-layer 'layer layer)))) + +(ert-deftest test-make-layer--make-used-layer-can-set-additional-properties () + (let ((layer (cfgl-layer "layer" + :name 'layer + :dir spacemacs-start-directory)) + (layer-specs '(layer :disabled-for pkg8 pkg9 + :variables foo bar toto 1)) + (layer-packages '(pkg1 pkg2 pkg3)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (mocker-let + ((file-exists-p (f) ((:output t :occur 2))) + (load (f) ((:output nil :occur 1)))) + (should (equal (cfgl-layer "layer" + :name 'layer + :disabled-for '(pkg8 pkg9) + :variables '(foo bar toto 1) + :packages '(pkg1 pkg2 pkg3) + :selected-packages 'all + :dir spacemacs-start-directory) + (configuration-layer/make-layer layer-specs layer 'used)))))) + +(ert-deftest test-make-layer--make-not-used-layer-cannot-set-additional-properties () + (let ((layer (cfgl-layer "layer" + :name 'layer + :dir spacemacs-start-directory)) + (layer-specs '(layer :disabled-for pkg8 pkg9 + :variables foo bar toto 1)) + (layer-packages '(pkg1 pkg2 pkg3))) + (should (equal (cfgl-layer "layer" + :name 'layer + :disabled-for nil + :variables nil + :packages nil + :selected-packages 'all + :dir spacemacs-start-directory) + (configuration-layer/make-layer layer-specs layer))))) + +(ert-deftest test-make-layer--make-used-layer-can-override-additional-properties () + (let ((layer (cfgl-layer "layer" + :name 'layer + :disabled-for '(pkg10) + :variables '(titi tata tutu 1) + :dir spacemacs-start-directory)) + (layer-specs '(layer :disabled-for pkg8 pkg9 + :variables foo bar toto 1)) + (layer-packages '(pkg1 pkg2 pkg3)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (mocker-let + ((file-exists-p (f) ((:output t :occur 2))) + (load (f) ((:output nil :occur 1)))) + (should (equal (cfgl-layer "layer" + :name 'layer + :disabled-for '(pkg8 pkg9) + :variables '(foo bar toto 1) + :packages '(pkg1 pkg2 pkg3) + :selected-packages 'all + :dir spacemacs-start-directory) + (configuration-layer/make-layer layer-specs layer 'used)))))) + +(ert-deftest test-make-layer--make-not-used-layer-cannot-override-additional-properties () + (let ((layer (cfgl-layer "layer" + :name 'layer + :disabled-for '(pkg10) + :variables '(titi tata tutu 1) + :packages '(pkg1 pkg2 pkg3) + :selected-packages 'all + :dir spacemacs-start-directory)) + (layer-specs '(layer :disabled-for pkg8 pkg9 + :variables foo bar toto 1)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (should (equal (cfgl-layer "layer" + :name 'layer + :disabled-for '(pkg10) + :variables '(titi tata tutu 1) + :packages '(pkg1 pkg2 pkg3) + :selected-packages 'all + :dir spacemacs-start-directory) + (configuration-layer/make-layer layer-specs layer))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer//set-layers-variables +;; --------------------------------------------------------------------------- + +(ert-deftest test-set-layers-variables--none () + (let ((input `(,(cfgl-layer "layer" + :name 'layer + :dir "/a/path/"))) + (var 'foo)) + (configuration-layer//set-layers-variables input) + (should (eq var 'foo)))) + +(ert-deftest test-set-layers-variables--one-value () + (let ((input `(,(cfgl-layer "layer" + :name 'layer + :dir "/a/path/" + :variables '(var1 'bar))))) + (setq var1 'foo) + (configuration-layer//set-layers-variables input) + (should (eq var1 'bar)))) + +(ert-deftest test-set-layers-variables--multiple-values () + (let ((input `(,(cfgl-layer "layer" + :name 'layer + :dir "/a/path/" + :variables '(var1 'bar1 var2 'bar2 var3 'bar3))))) + (setq var1 'foo) + (setq var2 'foo) + (setq var3 'foo) + (configuration-layer//set-layers-variables input) + (should (eq var1 'bar1)) + (should (eq var2 'bar2)) + (should (eq var3 'bar3)))) + +(ert-deftest test-set-layers-variables--odd-number-of-values () + (let ((input `(,(cfgl-layer "layer" + :name 'layer + :dir "/a/path/" + :variables '(var1 'bar var2))))) + (mocker-let + ((configuration-layer//warning + (msg &rest args) + ((:record-cls 'mocker-stub-record :output nil :occur 1)))) + (setq var1 'foo) + (setq var2 'foo) + (configuration-layer//set-layers-variables input) + (should (eq var1 'bar)) + (should (eq var2 'foo))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer/make-package +;; --------------------------------------------------------------------------- + +(ert-deftest test-make-package--make-package-from-symbol () + (let* (configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (input 'testpkg) + (expected (cfgl-package "testpkg" + :name 'testpkg + :location 'elpa + :owners '(layer-make-pkg-1) + :pre-layers nil + :post-layers nil + :step nil + :excluded nil))) + (defun layer-make-pkg-1/init-testpkg nil) + (helper--set-layers + `(,(cfgl-layer "layer-make-pkg-1" :name 'layer-make-pkg-1)) t) + (should + (equal + expected + (configuration-layer/make-package input 'layer-make-pkg-1))))) + +(ert-deftest test-make-package--make-package-from-list () + (let* (configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (input '(testpkg :location local :step pre)) + (expected (cfgl-package "testpkg" + :name 'testpkg + :owners '(layer-make-pkg-2) + :location 'local + :pre-layers nil + :post-layers nil + :step 'pre + :excluded nil))) + (defun layer-make-pkg-2/init-testpkg nil) + (helper--set-layers + `(,(cfgl-layer "layer-make-pkg-2" :name 'layer-make-pkg-2)) t) + (should + (equal + expected + (configuration-layer/make-package input 'layer-make-pkg-2))))) + +(ert-deftest test-make-package--multiple-calls-invariants () + (defun layer-make-pkg-3/init-testpkg nil) + (defun layer-make-pkg-4/pre-init-testpkg nil) + (defun layer-make-pkg-5/post-init-testpkg nil) + (let* (configuration-layer--used-layers + configuration-layer--protected-packages + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (input '(testpkg :protected t)) + (expected-pkg (cfgl-package "testpkg" + :name 'testpkg + :location 'elpa + :owners '(layer-make-pkg-3) + :pre-layers '(layer-make-pkg-4) + :post-layers '(layer-make-pkg-5) + :step nil + :protected t + :excluded nil)) + (expected-protected-list '(testpkg))) + (helper--set-layers + `(,(cfgl-layer "layer-make-pkg-3" :name 'layer-make-pkg-3) + ,(cfgl-layer "layer-make-pkg-4" :name 'layer-make-pkg-4) + ,(cfgl-layer "layer-make-pkg-5" :name 'layer-make-pkg-5)) t) + (let ((obj (configuration-layer/make-package input 'layer-make-pkg-3))) + (dotimes (x 3) + (configuration-layer/make-package input 'layer-make-pkg-3 obj) + (configuration-layer/make-package input 'layer-make-pkg-4 obj) + (configuration-layer/make-package input 'layer-make-pkg-5 obj)) + (should (equal expected-pkg obj)) + (should (equal expected-protected-list + configuration-layer--protected-packages))))) + +(ert-deftest test-make-package--can-override-toggle () + (let (configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (obj (cfgl-package "testpkg" :name 'testpkg :toggle 'foo)) + (pkg '(testpkg :toggle bar)) + (expected (cfgl-package "testpkg" + :name 'testpkg + :owners '(layer-make-pkg-6) + :toggle 'bar))) + (defun layer-make-pkg-6/init-testpkg nil) + (helper--set-layers + `(,(cfgl-layer "layer-make-pkg-6" :name 'layer-make-pkg-6)) + t) + (should + (equal + expected + (configuration-layer/make-package pkg 'layer-make-pkg-6 obj))))) + +(ert-deftest test-make-package--can-override-location () + (let* (configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (obj (cfgl-package "testpkg" + :name 'testpkg + :location 'elpa)) + (pkg '(testpkg :location local)) + (expected (cfgl-package "testpkg" + :name 'testpkg + :owners '(layer-make-pkg-7) + :location 'local))) + (defun layer-make-pkg-7/init-testpkg nil) + (helper--set-layers + `(,(cfgl-layer "layer-make-pkg-7" :name 'layer-make-pkg-7)) t) + (should + (equal expected + (configuration-layer/make-package pkg 'layer-make-pkg-7 obj))))) + +(ert-deftest test-make-package--can-override-step () + (let* (configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (obj (cfgl-package "testpkg" + :name 'testpkg + :step nil)) + (pkg '(testpkg :step pre)) + (expected (cfgl-package "testpkg" + :name 'testpkg + :owners '(layer-make-pkg-8) + :step 'pre))) + (defun layer-make-pkg-8/init-testpkg nil) + (helper--set-layers + `(,(cfgl-layer "layer-make-pkg-8" :name 'layer-make-pkg-8)) t) + (should + (equal + expected + (configuration-layer/make-package pkg 'layer-make-pkg-8 obj))))) + +(ert-deftest test-make-package--cannot-override-protected () + (let* (configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (obj (cfgl-package "testpkg" + :name 'testpkg + :protected t)) + (pkg '(testpkg :protected nil)) + (expected (cfgl-package "testpkg" + :name 'testpkg + :owners '(layer-make-pkg-9) + :protected t))) + (defun layer-make-pkg-9/init-testpkg nil) + (helper--set-layers + `(,(cfgl-layer "layer-make-pkg-9" + :name 'layer-make-pkg-9)) t) + (should + (equal + expected + (configuration-layer/make-package pkg 'layer-make-pkg-9 obj))))) + +(ert-deftest test-make-package--cannot-unexclude-excluded-package () + (let* (configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (obj (cfgl-package "testpkg" + :name 'testpkg + :excluded t)) + (pkg '(testpkg :excluded nil)) + (expected (cfgl-package "testpkg" + :name 'testpkg + :excluded t))) + (helper--set-layers + `(,(cfgl-layer "layer-make-pkg-10" :name 'layer-make-pkg-10)) t) + (should + (equal expected + (configuration-layer/make-package pkg 'layer-make-pkg-10 obj))))) + +(ert-deftest test-make-package--bootstrap-package-are-protected () + (let* (configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (pkg '(testpkg :step bootstrap)) + (expected (cfgl-package "testpkg" + :name 'testpkg + :owners '(layer-make-pkg-11) + :step 'bootstrap + :protected t))) + (defun layer-make-pkg-11/init-testpkg nil) + (helper--set-layers + `(,(cfgl-layer "layer-make-pkg-11" :name 'layer-make-pkg-11)) t) + (should + (equal + expected + (configuration-layer/make-package pkg 'layer-make-pkg-11))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer//get-distant-packages +;; --------------------------------------------------------------------------- + +(defvar test-get-distant-packages--test-data + `(,(cfgl-package "pkg18" :name 'pkg18 :owners nil) + ,(cfgl-package "pkg17" :name 'pkg17 :owners nil :location 'elpa) + ,(cfgl-package "pkg16" :name 'pkg16 :owners nil :toggle nil) + ,(cfgl-package "pkg15" :name 'pkg15 :owners nil :toggle t) + ,(cfgl-package "pkg14" :name 'pkg14 :owners nil :location '(recipe)) + ,(cfgl-package "pkg13" :name 'pkg13 :owners nil :location 'built-in) + ,(cfgl-package "pkg12" :name 'pkg12 :owners nil :location 'local) + ,(cfgl-package "pkg11" :name 'pkg11 :owners nil :location 'site) + ,(cfgl-package "pkg10" :name 'pkg10 :owners nil :location "/path") + ,(cfgl-package "pkg9" :name 'pkg9 :owners '(layer)) + ,(cfgl-package "pkg8" :name 'pkg8 :owners '(layer) :location 'elpa) + ,(cfgl-package "pkg7" :name 'pkg7 :owners '(layer) :toggle nil) + ,(cfgl-package "pkg6" :name 'pkg6 :owners '(layer) :toggle t) + ,(cfgl-package "pkg5" :name 'pkg5 :owners '(layer) :location '(recipe)) + ,(cfgl-package "pkg4" :name 'pkg4 :owners '(layer) :location 'built-in) + ,(cfgl-package "pkg3" :name 'pkg3 :owners '(layer) :location 'local) + ,(cfgl-package "pkg2" :name 'pkg2 :owners '(layer) :location 'site) + ,(cfgl-package "pkg1" :name 'pkg1 :owners '(layer) :location "/path"))) + +(ert-deftest test-get-distant-packages--return-only-used-packages () + (let* ((packages (mapcar 'car (object-assoc-list + :name test-get-distant-packages--test-data))) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (helper--set-packages test-get-distant-packages--test-data t) + (should + (equal '(pkg9 pkg8 pkg6 pkg5) + (configuration-layer//get-distant-packages packages t))))) + +(ert-deftest test-get-distant-packages--return-only-unused-packages () + (let ((packages (mapcar 'car (object-assoc-list + :name test-get-distant-packages--test-data))) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (helper--set-packages test-get-distant-packages--test-data t) + (should + (equal '(pkg18 pkg17 pkg16 pkg15 pkg14 pkg9 pkg8 pkg7 pkg6 pkg5) + (configuration-layer//get-distant-packages packages nil))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer/make-packages-from-layers +;; --------------------------------------------------------------------------- + +(ert-deftest test-make-packages-from-layers--symbols-only () + (let* ((layer1 (cfgl-layer "layer1" + :name 'layer1 + :dir "/path/" + :packages '(pkg1 pkg2 pkg3))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (helper--set-layers (list layer1) t) + (defun layer1/init-pkg1 nil) + (defun layer1/init-pkg2 nil) + (defun layer1/init-pkg3 nil) + (configuration-layer/make-packages-from-layers '(layer1)) + (should + (and (equal (cfgl-package "pkg3" :name 'pkg3 :owners '(layer1)) + (ht-get configuration-layer--indexed-packages 'pkg3)) + (equal (cfgl-package "pkg2" :name 'pkg2 :owners '(layer1)) + (ht-get configuration-layer--indexed-packages 'pkg2)) + (equal (cfgl-package "pkg1" :name 'pkg1 :owners '(layer1)) + (ht-get configuration-layer--indexed-packages 'pkg1)))))) + +(ert-deftest test-make-packages-from-layers--lists-only () + (let* ((layer1 (cfgl-layer "layer1" + :name 'layer1 + :dir "/path/" + :packages '((pkg1 :location elpa :excluded t) + (pkg2 :location (recipe blahblah)) + (pkg3 :location local :step pre)))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (helper--set-layers (list layer1) t) + (defun layer1/init-pkg1 nil) + (defun layer1/init-pkg2 nil) + (defun layer1/init-pkg3 nil) + (configuration-layer/make-packages-from-layers '(layer1)) + (should + (and (equal (cfgl-package "pkg3" + :name 'pkg3 + :owners '(layer1) + :location 'local + :step 'pre) + (ht-get configuration-layer--indexed-packages 'pkg3)) + (equal (cfgl-package "pkg2" + :name 'pkg2 + :owners '(layer1) + :location '(recipe blahblah)) + (ht-get configuration-layer--indexed-packages 'pkg2)) + (equal (cfgl-package "pkg1" :name 'pkg1 :owners '(layer1) :excluded t) + (ht-get configuration-layer--indexed-packages 'pkg1)))))) + +(ert-deftest test-make-packages-from-layers--symbols-and-lists () + (let* ((layer1 (cfgl-layer "layer1" + :name 'layer1 + :dir "/path/" + :packages '(pkg1 + (pkg2 :location (recipe blahblah)) + (pkg3 :location local :step pre) + pkg4))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (helper--set-layers (list layer1) t) + (defun layer1/init-pkg1 nil) + (defun layer1/init-pkg2 nil) + (defun layer1/init-pkg3 nil) + (defun layer1/init-pkg4 nil) + (configuration-layer/make-packages-from-layers '(layer1)) + (should + (and (equal (cfgl-package "pkg4" :name 'pkg4 :owners '(layer1)) + (ht-get configuration-layer--indexed-packages 'pkg4)) + (equal (cfgl-package "pkg3" + :name 'pkg3 + :owners '(layer1) + :location 'local + :step 'pre) + (ht-get configuration-layer--indexed-packages 'pkg3)) + (equal (cfgl-package "pkg2" + :name 'pkg2 + :owners '(layer1) + :location '(recipe blahblah)) + (ht-get configuration-layer--indexed-packages 'pkg2)) + (equal (cfgl-package "pkg1" :name 'pkg1 :owners '(layer1)) + (ht-get configuration-layer--indexed-packages 'pkg1)))))) + +(ert-deftest test-make-packages-from-layers--pkg2-has-no-owner-because-no-init-function () + (let* ((layer2 (cfgl-layer "layer2" + :name 'layer2 + :dir "/path/" + :packages '(pkg1 pkg2 pkg3))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers (list layer2) t) + (defun layer2/init-pkg1 nil) + (defun layer2/init-pkg3 nil) + (mocker-let + ((configuration-layer//warning (msg &rest args) ((:output nil :occur 1)))) + (configuration-layer/make-packages-from-layers '(layer2)) + (should + (and (equal (cfgl-package "pkg3" :name 'pkg3 :owners '(layer2)) + (ht-get configuration-layer--indexed-packages 'pkg3)) + (equal (cfgl-package "pkg2" :name 'pkg2) + (ht-get configuration-layer--indexed-packages 'pkg2)) + (equal (cfgl-package "pkg1" :name 'pkg1 :owners '(layer2)) + (ht-get configuration-layer--indexed-packages 'pkg1))))))) + +(ert-deftest test-make-packages-from-layers--pre-init-function () + (let* ((layer3 (cfgl-layer "layer3" + :name 'layer3 + :dir "/path/" + :packages '(pkg1))) + (layer4 (cfgl-layer "layer4" + :name 'layer4 + :dir "/path/" + :packages '(pkg1))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (helper--set-layers (list layer3 layer4) t) + (defun layer3/init-pkg1 nil) + (defun layer4/pre-init-pkg1 nil) + (configuration-layer/make-packages-from-layers '(layer3 layer4)) + (should (equal (cfgl-package "pkg1" + :name 'pkg1 + :owners '(layer3) + :pre-layers '(layer4)) + (ht-get configuration-layer--indexed-packages 'pkg1))))) + +(ert-deftest test-make-packages-from-layers--post-init-function () + (let* ((layer3 (cfgl-layer "layer3" + :name 'layer3 + :dir "/path/" + :packages '(pkg1))) + (layer5 (cfgl-layer "layer5" + :name 'layer5 + :dir "/path/" + :packages '(pkg1))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (helper--set-layers (list layer3 layer5) t) + (defun layer3/init-pkg1 nil) + (defun layer5/post-init-pkg1 nil) + (configuration-layer/make-packages-from-layers '(layer3 layer5)) + (should (equal (cfgl-package "pkg1" + :name 'pkg1 + :owners '(layer3) + :post-layers '(layer5)) + (ht-get configuration-layer--indexed-packages 'pkg1))))) + +(ert-deftest test-make-packages-from-layers--pre-and-post-init-functions () + (let* ((layer3 (cfgl-layer "layer3" + :name 'layer3 + :dir "/path/" + :packages '(pkg1))) + (layer6 (cfgl-layer "layer6" + :name 'layer6 + :dir "/path/" + :packages '(pkg1))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (helper--set-layers (list layer3 layer6) t) + (defun layer3/init-pkg1 nil) + (defun layer6/pre-init-pkg1 nil) + (defun layer6/post-init-pkg1 nil) + (configuration-layer/make-packages-from-layers '(layer3 layer6)) + (should (equal (cfgl-package "pkg1" + :name 'pkg1 + :owners '(layer3) + :pre-layers '(layer6) + :post-layers '(layer6)) + (ht-get configuration-layer--indexed-packages 'pkg1))))) + +(ert-deftest test-make-packages-from-layers--several-init-functions-last-one-is-the-owner () + (let* ((layer7 (cfgl-layer "layer7" + :name 'layer7 + :dir "/path/" + :packages '(pkg1))) + (layer8 (cfgl-layer "layer8" + :name 'layer8 + :dir "/path/" + :packages '(pkg1))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers (list layer7 layer8) t) + (defun layer7/init-pkg1 nil) + (defun layer8/init-pkg1 nil) + (mocker-let + ((configuration-layer//warning (msg &rest args) ((:output nil :occur 1)))) + (configuration-layer/make-packages-from-layers '(layer7 layer8)) + (should (equal (cfgl-package "pkg1" + :name 'pkg1 + :owners '(layer8 layer7)) + (ht-get configuration-layer--indexed-packages 'pkg1)))))) + +(ert-deftest test-make-packages-from-layers--layer-10-excludes-pkg2-in-layer-9 () + (let* ((layer9 (cfgl-layer "layer9" + :name 'layer9 + :dir "/path/" + :packages '(pkg1 pkg2))) + (layer10 (cfgl-layer "layer10" + :name 'layer10 + :dir "/path/" + :packages '(pkg3 (pkg2 :excluded t)))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (helper--set-layers (list layer9 layer10) t) + (defun layer9/init-pkg1 nil) + (defun layer9/init-pkg2 nil) + (defun layer10/init-pkg3 nil) + (configuration-layer/make-packages-from-layers '(layer9 layer10)) + (should + (and (equal (cfgl-package "pkg3" :name 'pkg3 :owners '(layer10)) + (ht-get configuration-layer--indexed-packages 'pkg3)) + (equal (cfgl-package "pkg2" :name 'pkg2 :owners '(layer9) :excluded t) + (ht-get configuration-layer--indexed-packages 'pkg2)) + (equal (cfgl-package "pkg1" :name 'pkg1 :owners '(layer9)) + (ht-get configuration-layer--indexed-packages 'pkg1)))))) + +(ert-deftest test-make-packages-from-layers--last-owner-can-overwrite-location () + (let* ((layer13 (cfgl-layer "layer13" + :name 'layer13 + :dir "/path/" + :packages '((pkg1 :location elpa)))) + (layer14 (cfgl-layer "layer14" + :name 'layer14 + :dir "/path/" + :packages '((pkg1 :location local)))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers (list layer13 layer14) t) + (defun layer13/init-pkg1 nil) + (defun layer14/init-pkg1 nil) + (mocker-let + ((configuration-layer//warning (msg &rest args) ((:output nil :occur 1)))) + (configuration-layer/make-packages-from-layers '(layer13 layer14)) + (should (equal (cfgl-package "pkg1" + :name 'pkg1 + :owners '(layer14 layer13) + :location 'local) + (ht-get configuration-layer--indexed-packages 'pkg1)))))) + +(ert-deftest test-make-packages-from-layers--last-owner-can-overwrite-step-nil-to-pre () + (let* ((layer15 (cfgl-layer "layer15" + :name 'layer15 + :dir "/path/" + :packages '((pkg1 :step nil)))) + (layer16 (cfgl-layer "layer16" + :name 'layer16 + :dir "/path/" + :packages '((pkg1 :step pre)))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers (list layer15 layer16) t) + (defun layer15/init-pkg1 nil) + (defun layer16/init-pkg1 nil) + (mocker-let + ((configuration-layer//warning (msg &rest args) ((:output nil :occur 1)))) + (configuration-layer/make-packages-from-layers '(layer15 layer16)) + (should (equal (cfgl-package "pkg1" + :name 'pkg1 + :owners '(layer16 layer15) + :step 'pre) + (ht-get configuration-layer--indexed-packages 'pkg1)))))) + +(ert-deftest test-make-packages-from-layers--last-owner-cannot-overwrite-step-pre-to-nil () + (let* ((layer15 (cfgl-layer "layer15" + :name 'layer15 + :dir "/path/" + :packages '((pkg1 :step pre)))) + (layer16 (cfgl-layer "layer16" + :name 'layer16 + :dir "/path/" + :packages '((pkg1 :step nil)))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers (list layer15 layer16) t) + (defun layer15/init-pkg1 nil) + (defun layer16/init-pkg1 nil) + (mocker-let + ((configuration-layer//warning (msg &rest args) ((:output nil :occur 1)))) + (configuration-layer/make-packages-from-layers '(layer15 layer16)) + (should (equal (cfgl-package "pkg1" + :name 'pkg1 + :owners '(layer16 layer15) + :step 'pre) + (ht-get configuration-layer--indexed-packages 'pkg1)))))) + +(ert-deftest test-make-packages-from-layers--last-owner-can-overwrite-exclude () + (let* ((layer17 (cfgl-layer "layer17" + :name 'layer17 + :dir "/path/" + :packages '(pkg1))) + (layer18 (cfgl-layer "layer18" + :name 'layer18 + :dir "/path/" + :packages '((pkg1 :excluded t)) + )) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers (list layer17 layer18) t) + (defun layer17/init-pkg1 nil) + (defun layer18/init-pkg1 nil) + (mocker-let + ((configuration-layer//warning (msg &rest args) ((:output nil :occur 1)))) + (configuration-layer/make-packages-from-layers '(layer17 layer18)) + (should (equal (cfgl-package "pkg1" + :name 'pkg1 + :owners '(layer18 layer17) + :excluded t) + (ht-get configuration-layer--indexed-packages 'pkg1)))))) + +(ert-deftest test-make-packages-from-layers--owner-layer-can-define-toggle () + (let* ((layer19 (cfgl-layer "layer19" + :name 'layer19 + :dir "/path/" + :packages '((pkg1 :toggle (foo-toggle))))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (helper--set-layers (list layer19) t) + (defun layer19/init-pkg1 nil) + (let (configuration-layer--used-packages)) + (configuration-layer/make-packages-from-layers '(layer19)) + (should (equal (cfgl-package "pkg1" + :name 'pkg1 + :owners '(layer19) + :toggle '(foo-toggle)) + (ht-get configuration-layer--indexed-packages 'pkg1))))) + +(ert-deftest test-make-packages-from-layers--not-owner-layer-can-define-toggle-with-warning () + (let* ((layer20 (cfgl-layer "layer20" + :name 'layer20 + :dir "/path/" + :packages '(pkg1))) + (layer21 (cfgl-layer "layer21" + :name 'layer21 + :dir "/path/" + :packages '((pkg1 :toggle (foo-toggle))))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers (list layer20 layer21) t) + (defun layer20/init-pkg1 nil) + (defun layer21/post-init-pkg1 nil) + (mocker-let + ((configuration-layer//warning (msg &rest args) ((:output nil :occur 1)))) + (configuration-layer/make-packages-from-layers '(layer20 layer21)) + (should (equal (cfgl-package "pkg1" + :name 'pkg1 + :owners '(layer20) + :post-layers '(layer21) + :toggle '(foo-toggle)) + (ht-get configuration-layer--indexed-packages 'pkg1)))))) + +(ert-deftest test-make-packages-from-layers--layer-can-override-toggle () + (let* ((layer22 (cfgl-layer "layer22" + :name 'layer22 + :dir "/path/" + :packages '((pkg1 :toggle (foo-toggle))))) + (layer23 (cfgl-layer "layer23" + :name 'layer23 + :dir "/path/" + :packages '((pkg1 :toggle (bar-toggle))))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers (list layer22 layer23) t) + (defun layer22/init-pkg1 nil) + (defun layer23/init-pkg1 nil) + (mocker-let + ((configuration-layer//warning (msg &rest args) ((:output nil :occur 1)))) + (configuration-layer/make-packages-from-layers '(layer22 layer23)) + (should (equal (cfgl-package "pkg1" + :name 'pkg1 + :owners '(layer23 layer22) + :toggle '(bar-toggle)) + (ht-get configuration-layer--indexed-packages 'pkg1)))))) + +(ert-deftest test-make-packages-from-layers--not-selected-packages-are-not-excluded () + (let* ((layer24 (cfgl-layer "layer24" + :name 'layer24 + :dir "/path/" + :packages '(pkg1 (pkg2 :location local)) + :selected-packages '(pkg2))) + (layer25 (cfgl-layer "layer25" + :name 'layer25 + :dir "/path/" + :packages '(pkg1 (pkg2 :location local)) + :selected-packages '(pkg1))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (helper--set-layers (list layer24 layer25)) + (defun layer24/post-init-pkg1 nil) + (defun layer24/init-pkg2 nil) + (defun layer25/init-pkg1 nil) + (defun layer25/post-init-pkg2 nil) + (configuration-layer/make-packages-from-layers '(layer24 layer25)) + (should + (and (equal (cfgl-package "pkg1" + :name 'pkg1 + :owners '(layer25) + :excluded nil) + (ht-get configuration-layer--indexed-packages 'pkg1)) + (equal (cfgl-package "pkg2" + :name 'pkg2 + :owners '(layer24) + :location 'local + :excluded nil) + (ht-get configuration-layer--indexed-packages 'pkg2)))))) + +(ert-deftest test-make-packages-from-layers--not-selected-package-in-a-layer-can-still-be-created-with-no-owner () + (let* ((layer26 (cfgl-layer "layer26" + :name 'layer26 + :dir "/path/" + :packages '(pkg1 (pkg2 :location local)) + :selected-packages '(pkg2))) + (layer27 (cfgl-layer "layer27" + :name 'layer27 + :dir "/path/" + :packages '(pkg1 pkg2))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (helper--set-layers (list layer26 layer27)) + (defun layer26/init-pkg1 nil) + (defun layer26/init-pkg2 nil) + (defun layer27/post-init-pkg1 nil) + (defun layer27/post-init-pkg2 nil) + (configuration-layer/make-packages-from-layers '(layer26 layer27)) + (should + (and (equal (cfgl-package "pkg1" + :name 'pkg1 + :post-layers '(layer27) + :owners nil) + (ht-get configuration-layer--indexed-packages 'pkg1)) + (equal (cfgl-package "pkg2" + :name 'pkg2 + :owners '(layer26) + :post-layers '(layer27) + :location 'local) + (ht-get configuration-layer--indexed-packages 'pkg2)))))) + +(ert-deftest test-make-packages-from-layers--package-properties-read-only () + ;; we expect that :excluded is still nil + (let* (configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (layer28 (cfgl-layer "layer28" + :name 'layer28 + :packages '((pkg1 :excluded nil)))) + (layer29 (cfgl-layer "layer29" + :name 'layer29 + :packages '((pkg1 :excluded t)))) + (expected (cfgl-package "pkg1" + :name 'pkg1 + :owners '(layer28) + :excluded nil)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (defun layer28/init-pkg1 nil) + (helper--set-layers (list layer28) t) + (helper--set-layers (list layer29)) + (mocker-let + ((configuration-layer//warning (msg &rest args) ((:output nil :occur 1)))) + (configuration-layer/make-packages-from-layers '(layer28) t) + (let ((configuration-layer--package-properties-read-onlyp t)) + (configuration-layer/make-packages-from-layers '(layer28 layer29))) + (should + (equal expected (ht-get configuration-layer--indexed-packages 'pkg1)))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer/make-packages-from-dotfile +;; --------------------------------------------------------------------------- + +(ert-deftest test-make-packages-from-dotfile--dotfile-declares-and-owns-one-additional-package () + (let* ((layer-dotfile-1 (cfgl-layer "layer-dotfile-1" + :name 'layer-dotfile-1 + :dir "/path/" + :packages '(pkg1 pkg2))) + (dotspacemacs-additional-packages '(pkg3)) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (defun layer-dotfile-1/init-pkg1 nil) + (defun layer-dotfile-1/init-pkg2 nil) + (helper--set-layers (list layer-dotfile-1) t) + (configuration-layer/make-packages-from-layers '(layer-dotfile-1) 'used) + (configuration-layer/make-packages-from-dotfile 'used) + (should + (and (equal (cfgl-package "pkg3" :name 'pkg3 :owners '(dotfile)) + (ht-get configuration-layer--indexed-packages 'pkg3)) + (equal (cfgl-package "pkg2" :name 'pkg2 :owners '(layer-dotfile-1)) + (ht-get configuration-layer--indexed-packages 'pkg2)) + (equal (cfgl-package "pkg1" :name 'pkg1 :owners '(layer-dotfile-1)) + (ht-get configuration-layer--indexed-packages 'pkg1)))))) + +(ert-deftest test-make-packages-from-dotfile--dotfile-cannot-own-package-owned-by-layer () + (let* ((layer-dotfile-2 (cfgl-layer "layer-dotfile-2" + :name 'layer-dotfile-2 + :dir "/path/" + :packages '(pkg1))) + (dotspacemacs-additional-packages '(pkg1)) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (defun layer-dotfile-2/init-pkg1 nil) + (helper--set-layers (list layer-dotfile-2) t) + (configuration-layer/make-packages-from-layers '(layer-dotfile-2) 'used) + (configuration-layer/make-packages-from-dotfile 'used) + (should + (equal (cfgl-package "pkg1" :name 'pkg1 :owners '(layer-dotfile-2)) + (ht-get configuration-layer--indexed-packages 'pkg1))))) + +(ert-deftest test-make-packages-from-dotfile--dotfile-excludes-pkg2-in-layer-11 () + (let* ((layer-dotfile-3 (cfgl-layer "layer-dotfile-3" + :name 'layer-dotfile-3 + :dir "/path/" + :packages '(pkg1 pkg2 pkg3))) + (dotspacemacs-excluded-packages '(pkg2)) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (defun layer-dotfile-3/init-pkg1 nil) + (defun layer-dotfile-3/init-pkg2 nil) + (defun layer-dotfile-3/init-pkg3 nil) + (helper--set-layers (list layer-dotfile-3) t) + (configuration-layer/make-packages-from-layers '(layer-dotfile-3) 'used) + (configuration-layer/make-packages-from-dotfile 'used) + (should + (and (equal (cfgl-package "pkg3" :name 'pkg3 :owners '(layer-dotfile-3)) + (ht-get configuration-layer--indexed-packages 'pkg3)) + (equal (cfgl-package "pkg2" :name 'pkg2 :owners '(layer-dotfile-3) + :excluded t) + (ht-get configuration-layer--indexed-packages 'pkg2)) + (equal (cfgl-package "pkg1" :name 'pkg1 :owners '(layer-dotfile-3)) + (ht-get configuration-layer--indexed-packages 'pkg1)))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer/make-all-packages +;; --------------------------------------------------------------------------- + +(ert-deftest test-make-all-packages () + (let* (configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (helper--set-layers + `(,(cfgl-layer "layerall1" + :name 'layerall1 + :packages '(pkg1) + :dir "/layerall1/") + ,(cfgl-layer "layerall2" + :name 'layerall2 + :packages '(pkg2 pkg6) + :dir "/layerall2/") + ,(cfgl-layer "layerall3" + :name 'layerall3 + :packages '(pkg3) + :dir "/layerall3/") + ,(cfgl-layer "layerall4" + :name 'layerall4 + :packages '(pkg4 pkg7 pkg8) + :dir "/layerall4/") + ,(cfgl-layer "layerall5" + :name 'layerall5 + :packages '(pkg5 pkg9) + :dir "/layerall5/"))) + (defun layerall1/init-pkg1 nil) + (defun layerall2/init-pkg2 nil) + (defun layerall2/init-pkg6 nil) + (defun layerall3/init-pkg3 nil) + (defun layerall4/init-pkg4 nil) + (defun layerall4/init-pkg7 nil) + (defun layerall4/init-pkg8 nil) + (defun layerall5/init-pkg5 nil) + (defun layerall5/init-pkg9 nil) + (configuration-layer/make-all-packages) + (should (null configuration-layer--used-packages)) + (should (equal '(pkg1 + pkg6 + pkg2 + pkg3 + pkg8 + pkg7 + pkg4 + pkg9 + pkg5) + (ht-keys configuration-layer--indexed-packages))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer//configure-package +;; --------------------------------------------------------------------------- + +(ert-deftest test-configure-package--init-is-evaluated () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers `(,(cfgl-layer "layer1" :name 'layer1)) t) + (defun layer1/init-pkg nil) + (mocker-let + ((spacemacs-buffer/message (m) ((:output nil))) + (layer1/init-pkg nil ((:output nil :occur 1)))) + (configuration-layer//configure-package pkg)))) + +(ert-deftest test-configure-package--pre-init-is-evaluated () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1) :pre-layers '(layer2))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers `(,(cfgl-layer "layer1" :name 'layer1) + ,(cfgl-layer "layer2" :name 'layer2)) t) + (defun layer1/init-pkg nil) + (defun layer2/pre-init-pkg nil) + (mocker-let + ((spacemacs-buffer/message (m) ((:output nil))) + (layer2/pre-init-pkg nil ((:output nil :occur 1)))) + (configuration-layer//configure-package pkg)))) + +(ert-deftest test-configure-package--post-init-is-evaluated () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1) :post-layers '(layer2))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers `(,(cfgl-layer "layer1" :name 'layer1) + ,(cfgl-layer "layer2" :name 'layer2)) t) + (defun layer1/init-pkg nil) + (defun layer2/post-init-pkg nil) + (mocker-let + ((spacemacs-buffer/message (m) ((:output nil))) + (layer2/post-init-pkg nil ((:output nil :occur 1)))) + (configuration-layer//configure-package pkg)))) + +(ert-deftest test-configure-package--pre-init-is-evaluated-before-init () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1) :pre-layers '(layer2))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (witness nil) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers `(,(cfgl-layer "layer1" :name 'layer1) + ,(cfgl-layer "layer2" :name 'layer2)) t) + (defun layer1/init-pkg () (push 'init witness)) + (defun layer2/pre-init-pkg () (push 'pre-init witness)) + (mocker-let + ((spacemacs-buffer/message (m) ((:output nil)))) + (configuration-layer//configure-package pkg) + (should (equal '(init pre-init) witness))))) + +(ert-deftest test-configure-package--post-init-is-evaluated-after-init () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1) :post-layers '(layer2))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (witness nil) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers `(,(cfgl-layer "layer1" :name 'layer1) + ,(cfgl-layer "layer2" :name 'layer2)) t) + (defun layer1/init-pkg () (push 'init witness)) + (defun layer2/post-init-pkg () (push 'post-init witness)) + (mocker-let + ((spacemacs-buffer/message (m) ((:output nil)))) + (configuration-layer//configure-package pkg) + (should (equal '(post-init init) witness))))) + +(ert-deftest test-configure-package--disabled-for-does-not-call-pre-post-init () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1) + :pre-layers '(layer2) + :post-layers '(layer3))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (witness nil) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers + `(,(cfgl-layer "layer1" :name 'layer1 :disabled-for '(layer2 layer3)) + ,(cfgl-layer "layer2" :name 'layer2) + ,(cfgl-layer "layer2" :name 'layer3)) t) + (defun layer1/init-pkg () (push 'init witness)) + (defun layer2/pre-init-pkg () (push 'pre-init witness)) + (defun layer3/post-init-pkg () (push 'post-init witness)) + (mocker-let + ((spacemacs-buffer/message (m) ((:output nil)))) + (configuration-layer//configure-package pkg) + (should (equal '(init) witness))))) + +(ert-deftest test-configure-package--enabled-for-unspecified-does-call-pre-post-init () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1) + :pre-layers '(layer2) + :post-layers '(layer3))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (witness nil) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers + `(,(cfgl-layer "layer1" :name 'layer1 :enabled-for 'unspecified) + ,(cfgl-layer "layer2" :name 'layer2) + ,(cfgl-layer "layer2" :name 'layer3)) t) + (defun layer1/init-pkg () (push 'init witness)) + (defun layer2/pre-init-pkg () (push 'pre-init witness)) + (defun layer3/post-init-pkg () (push 'post-init witness)) + (mocker-let + ((spacemacs-buffer/message (m) ((:output nil)))) + (configuration-layer//configure-package pkg) + (should (equal '(post-init init pre-init) witness))))) + +(ert-deftest test-configure-package--enabled-for-nil-does-not-call-pre-post-init () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1) + :pre-layers '(layer2) + :post-layers '(layer3))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (witness nil) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers + `(,(cfgl-layer "layer1" :name 'layer1 :enabled-for nil) + ,(cfgl-layer "layer2" :name 'layer2) + ,(cfgl-layer "layer2" :name 'layer3)) t) + (defun layer1/init-pkg () (push 'init witness)) + (defun layer2/pre-init-pkg () (push 'pre-init witness)) + (defun layer3/post-init-pkg () (push 'post-init witness)) + (mocker-let + ((spacemacs-buffer/message (m) ((:output nil)))) + (configuration-layer//configure-package pkg) + (should (equal '(init) witness))))) + +(ert-deftest test-configure-package--enabled-for-partial () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1) + :pre-layers '(layer2) + :post-layers '(layer3))) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (witness nil) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers + `(,(cfgl-layer "layer1" :name 'layer1 :enabled-for '(layer2)) + ,(cfgl-layer "layer2" :name 'layer2) + ,(cfgl-layer "layer2" :name 'layer3)) t) + (defun layer1/init-pkg () (push 'init witness)) + (defun layer2/pre-init-pkg () (push 'pre-init witness)) + (defun layer3/post-init-pkg () (push 'post-init witness)) + (mocker-let + ((spacemacs-buffer/message (m) ((:output nil)))) + (configuration-layer//configure-package pkg) + (should (equal '(init pre-init) witness))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer//configure-packages-2 +;; --------------------------------------------------------------------------- + +(ert-deftest test-configure-packages-2--package-w/-layer-owner-is-configured() + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1))) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-packages (list pkg) t) + (mocker-let + ((configuration-layer//configure-package (p) ((:occur 1))) + (spacemacs-buffer/loading-animation nil ((:output nil)))) + (configuration-layer//configure-packages-2 `(,(oref pkg :name)))))) + +(ert-deftest test-configure-packages-2--site-package-is-configured() + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1) :location 'site)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-packages (list pkg) t) + (mocker-let + ((configuration-layer//configure-package (p) ((:occur 1))) + (spacemacs-buffer/loading-animation nil ((:output nil)))) + (configuration-layer//configure-packages-2 `(,(oref pkg :name)))))) + +(ert-deftest test-configure-packages-2--toggle-t-is-configured () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1) :toggle t)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-packages (list pkg) t) + (mocker-let + ((configuration-layer//configure-package (p) ((:occur 1))) + (spacemacs-buffer/loading-animation nil ((:output nil)))) + (configuration-layer//configure-packages-2 `(,(oref pkg :name)))))) + +(ert-deftest test-configure-packages-2--toggle-nil-is-not-configured () + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1) :toggle nil)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-packages (list pkg) t) + (mocker-let + ((configuration-layer//configure-package (p) nil) + (spacemacs-buffer/loading-animation nil ((:output nil))) + (spacemacs-buffer/message (m) ((:output nil)))) + (configuration-layer//configure-packages-2 `(,(oref pkg :name)))))) + +(ert-deftest test-configure-packages-2--protected-package-is-configured() + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1) :protected t)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-packages (list pkg) t) + (mocker-let + ((configuration-layer//configure-package (p) ((:occur 1))) + (spacemacs-buffer/loading-animation nil ((:output nil)))) + (configuration-layer//configure-packages-2 `(,(oref pkg :name)))))) + +(ert-deftest test-configure-packages-2--protected-excluded-package-is-configured() + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1) :excluded t :protected t)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-packages (list pkg) t) + (mocker-let + ((configuration-layer//configure-package (p) ((:occur 1))) + (spacemacs-buffer/loading-animation nil ((:output nil)))) + (configuration-layer//configure-packages-2 `(,(oref pkg :name)))))) + +(ert-deftest test-configure-packages-2--excluded-package-is-not-configured() + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1) :excluded t)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-packages (list pkg) t) + (mocker-let + ((configuration-layer//configure-package (p) nil) + (spacemacs-buffer/loading-animation nil ((:output nil))) + (spacemacs-buffer/message (m) ((:output nil)))) + (configuration-layer//configure-packages-2 `(,(oref pkg :name)))))) + +(ert-deftest test-configure-packages-2--package-w/o-owner-is-not-configured() + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners nil)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-packages (list pkg) t) + (mocker-let + ((configuration-layer//configure-package (p) nil) + (spacemacs-buffer/loading-animation nil ((:output nil))) + (spacemacs-buffer/message (m) ((:output nil)))) + (configuration-layer//configure-packages-2 `(,(oref pkg :name)))))) + +(ert-deftest + test-configure-packages-2--package-owned-by-dotfile-is-not-configured() + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(dotfile))) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-packages (list pkg) t) + (mocker-let + ((configuration-layer//configure-package (p) nil) + (spacemacs-buffer/loading-animation nil ((:output nil))) + (spacemacs-buffer/message (m) ((:output nil)))) + (configuration-layer//configure-packages-2 `(,(oref pkg :name)))))) + +(ert-deftest test-configure-packages-2--lazy-install-package-is-not-configured() + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer) :lazy-install t)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-packages (list pkg) t) + (mocker-let + ((configuration-layer//configure-package (p) nil) + (spacemacs-buffer/loading-animation nil ((:output nil))) + (spacemacs-buffer/message (m) ((:output nil)))) + (configuration-layer//configure-packages-2 `(,(oref pkg :name)))))) + +(ert-deftest + test-configure-packages-2--local-package-w/-layer-owner-update-load-path() + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(layer1) :location 'local)) + configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (expected-load-path load-path) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers `(,(cfgl-layer "layer1" :name 'layer1 :dir "/path/")) t) + (helper--set-packages (list pkg) t) + (mocker-let + ((spacemacs-buffer/loading-animation nil ((:output nil))) + (configuration-layer//configure-package (p) ((:occur 1)))) + (configuration-layer//configure-packages-2 `(,(oref pkg :name))) + (push "/path/local/pkg/" expected-load-path) + (should (equal expected-load-path load-path))))) + +(ert-deftest + test-configure-packages-2--local-package-w/-dotfile-owner-update-load-path() + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners '(dotfile) :location 'local)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (expected-load-path load-path) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-packages (list pkg) t) + (mocker-let + ((spacemacs-buffer/loading-animation nil ((:output nil)))) + (configuration-layer//configure-packages-2 `(,(oref pkg :name))) + (push (file-name-as-directory + (concat configuration-layer-private-directory "local/pkg")) + expected-load-path) + (should (equal expected-load-path load-path))))) + +(ert-deftest + test-configure-packages-2--local-package-w/o-owner-doesnt-update-load-path() + (let ((pkg (cfgl-package "pkg" :name 'pkg :owners nil :location 'local)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (old-load-path load-path) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-packages (list pkg) t) + (mocker-let + ((spacemacs-buffer/loading-animation nil ((:output nil))) + (spacemacs-buffer/message (m) ((:output nil)))) + (configuration-layer//configure-packages-2 `(,(oref pkg :name))) + (should (equal load-path old-load-path))))) + +(ert-deftest + test-configure-packages-2--local-package-w/-string-location-update-load-path() + (let ((pkg (cfgl-package "pkg" + :name 'pkg + :owners '(dotfile) + :location spacemacs-docs-directory)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (expected-load-path load-path) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-packages (list pkg) t) + (mocker-let + ((spacemacs-buffer/loading-animation nil ((:output nil)))) + (configuration-layer//configure-packages-2 `(,(oref pkg :name))) + (push spacemacs-docs-directory expected-load-path) + (should (equal expected-load-path load-path))))) + +(ert-deftest + test-configure-packages-2--local-package-w/-bad-string-location-gives-warning() + (let ((pkg (cfgl-package "pkg" + :name 'pkg + :owners '(dotfile) + :location "/this/directory/does/not/exist/")) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-packages (list pkg) t) + (mocker-let + ((spacemacs-buffer/loading-animation nil ((:output nil))) + (configuration-layer//warning + (msg &rest args) + ((:record-cls 'mocker-stub-record :output nil :occur 1)))) + (configuration-layer//configure-packages-2 `(,(oref pkg :name)))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer//sort-packages +;; --------------------------------------------------------------------------- + +(ert-deftest test-sort-packages--example () + (let ((pkgs '(pkg4 pkg3 pkg6 pkg2 pkg1))) + (should (equal '(pkg1 pkg2 pkg3 pkg4 pkg6) + (configuration-layer//sort-packages pkgs))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer//package-has-recipe-p +;; --------------------------------------------------------------------------- + +(ert-deftest test-package-has-a-recipe-p--true () + (let (configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (helper--set-layers `(,(cfgl-layer "layer1" :name 'layer1)) t) + (helper--set-packages + `(,(configuration-layer/make-package '(pkg1 :location (recipe blah)) + 'layer1) + ,(configuration-layer/make-package '(pkg2 :location elpa) 'layer1)) t) + (should (configuration-layer//package-has-recipe-p 'pkg1)))) + +(ert-deftest test-package-has-a-recipe-p--false () + (let (configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (helper--set-layers `(,(cfgl-layer "layer1" :name 'layer1)) t) + (helper--set-packages + `(,(configuration-layer/make-package '(pkg1 :location (recipe blah)) + 'layer1) + ,(configuration-layer/make-package '(pkg2 :location elpa) 'layer1)) t) + (should (not (configuration-layer//package-has-recipe-p 'pkg2))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer//get-package-recipe +;; --------------------------------------------------------------------------- + +(ert-deftest test-get-package-recipe--return-recipe-if-package-has-one () + (let (configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (defun layer-no-recipe-1/init-pkg1 nil) + (defun layer-no-recipe-1/init-pkg2 nil) + (helper--set-layers + `(,(cfgl-layer "layer-no-recipe-1" :name 'layer-no-recipe-1)) t) + (helper--set-packages + `(,(configuration-layer/make-package '(pkg1 :location (recipe blah)) + 'layer-no-recipe-1) + ,(configuration-layer/make-package '(pkg2 :location elpa) + 'layer-no-recipe-1)) t) + (should (eq 'pkg1 + (car (configuration-layer//get-package-recipe 'pkg1)))))) + +(ert-deftest test-get-package-recipe--return-nil-if-package-has-no-recipe () + (let (configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (defun layer-no-recipe-2/init-pkg1 nil) + (defun layer-no-recipe-2/init-pkg2 nil) + (helper--set-layers + `(,(cfgl-layer "layer-no-recipe-2" :name 'layer-no-recipe-2)) t) + (helper--set-packages + `(,(configuration-layer/make-package '(pkg1 :location (recipe blah)) + 'layer-no-recipe-2) + ,(configuration-layer/make-package '(pkg2 :location elpa) + 'layer-no-recipe-2)) t) + (should (null (configuration-layer//get-package-recipe 'pkg2))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer/filter-objects +;; --------------------------------------------------------------------------- + +(ert-deftest test-filter-packages--example-filter-excluded-packages () + (defun layer-filter-1/init-pkg1 nil) + (defun layer-filter-1/init-pkg2 nil) + (defun layer-filter-1/init-pkg3 nil) + (defun layer-filter-1/init-pkg4 nil) + (defun layer-filter-1/init-pkg5 nil) + (defun layer-filter-1/init-pkg6 nil) + (defun layer-filter-1/init-pkg7 nil) + (defun layer-filter-1/init-pkg8 nil) + (let* (configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (pkg1 (configuration-layer/make-package 'pkg1 'layer-filter-1)) + (pkg2 (configuration-layer/make-package 'pkg2 'layer-filter-1)) + (pkg3 (configuration-layer/make-package 'pkg3 'layer-filter-1)) + (pkg4 (configuration-layer/make-package 'pkg4 'layer-filter-1)) + (pkg5 (configuration-layer/make-package 'pkg5 'layer-filter-1)) + (pkg6 (configuration-layer/make-package 'pkg6 'layer-filter-1)) + (pkg7 (configuration-layer/make-package 'pkg7 'layer-filter-1)) + (pkg8 (configuration-layer/make-package 'pkg8 'layer-filter-1)) + (pkgs (list pkg1 pkg2 pkg3 pkg4 pkg5 pkg6 pkg7 pkg8))) + (helper--set-layers + `(,(cfgl-layer "layer-filter-1" :name 'layer-filter-1)) t) + (oset pkg1 :excluded t) + (oset pkg3 :excluded t) + (oset pkg5 :excluded t) + (oset pkg6 :excluded t) + (should + (equal (list (cfgl-package "pkg2" :name 'pkg2 :owners '(layer-filter-1)) + (cfgl-package "pkg4" :name 'pkg4 :owners '(layer-filter-1)) + (cfgl-package "pkg7" :name 'pkg7 :owners '(layer-filter-1)) + (cfgl-package "pkg8" :name 'pkg8 :owners '(layer-filter-1))) + (configuration-layer/filter-objects + pkgs (lambda (x) + (not (oref x :excluded)))))))) + +(ert-deftest test-filter-packages--expample-filter-local-packages () + (defun layer-filter-2/init-pkg1 nil) + (defun layer-filter-2/init-pkg2 nil) + (defun layer-filter-2/init-pkg3 nil) + (defun layer-filter-2/init-pkg4 nil) + (defun layer-filter-2/init-pkg5 nil) + (defun layer-filter-2/init-pkg6 nil) + (defun layer-filter-2/init-pkg7 nil) + (defun layer-filter-2/init-pkg8 nil) + (let* (configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (pkg1 (configuration-layer/make-package 'pkg1 'layer-filter-2)) + (pkg2 (configuration-layer/make-package 'pkg2 'layer-filter-2)) + (pkg3 (configuration-layer/make-package 'pkg3 'layer-filter-2)) + (pkg4 (configuration-layer/make-package 'pkg4 'layer-filter-2)) + (pkg5 (configuration-layer/make-package 'pkg5 'layer-filter-2)) + (pkg6 (configuration-layer/make-package 'pkg6 'layer-filter-2)) + (pkg7 (configuration-layer/make-package 'pkg7 'layer-filter-2)) + (pkg8 (configuration-layer/make-package 'pkg8 'layer-filter-2)) + (pkgs (list pkg1 pkg2 pkg3 pkg4 pkg5 pkg6 pkg7 pkg8))) + (helper--set-layers + `(,(cfgl-layer "layer-filter-2" :name 'layer-filter-2)) t) + (oset pkg1 :location 'local) + (oset pkg3 :location 'local) + (oset pkg5 :location 'local) + (oset pkg6 :location 'local) + (should + (equal (list (cfgl-package "pkg2" :name 'pkg2 :owners '(layer-filter-2)) + (cfgl-package "pkg4" :name 'pkg4 :owners '(layer-filter-2)) + (cfgl-package "pkg7" :name 'pkg7 :owners '(layer-filter-2)) + (cfgl-package "pkg8" :name 'pkg8 :owners '(layer-filter-2))) + (configuration-layer/filter-objects + pkgs (lambda (x) + (not (eq 'local (oref x :location))))))))) + + +(ert-deftest test-filter-packages--example-filter-packages-local-or-excluded () + (defun layer-filter-3/init-pkg1 nil) + (defun layer-filter-3/init-pkg2 nil) + (defun layer-filter-3/init-pkg3 nil) + (defun layer-filter-3/init-pkg4 nil) + (defun layer-filter-3/init-pkg5 nil) + (defun layer-filter-3/init-pkg6 nil) + (defun layer-filter-3/init-pkg7 nil) + (defun layer-filter-3/init-pkg8 nil) + (let* (configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (pkg1 (configuration-layer/make-package 'pkg1 'layer-filter-3)) + (pkg2 (configuration-layer/make-package 'pkg2 'layer-filter-3)) + (pkg3 (configuration-layer/make-package 'pkg3 'layer-filter-3)) + (pkg4 (configuration-layer/make-package 'pkg4 'layer-filter-3)) + (pkg5 (configuration-layer/make-package 'pkg5 'layer-filter-3)) + (pkg6 (configuration-layer/make-package 'pkg6 'layer-filter-3)) + (pkg7 (configuration-layer/make-package 'pkg7 'layer-filter-3)) + (pkg8 (configuration-layer/make-package 'pkg8 'layer-filter-3)) + (pkgs (list pkg1 pkg2 pkg3 pkg4 pkg5 pkg6 pkg7 pkg8))) + (helper--set-layers + `(,(cfgl-layer "layer-filter-4" :name 'layer-filter-4)) t) + (oset pkg1 :location 'local) + (oset pkg1 :excluded t) + (oset pkg3 :location 'local) + (oset pkg5 :location 'local) + (oset pkg6 :location 'local) + (oset pkg6 :excluded t) + (oset pkg7 :excluded t) + (should + (equal (list (cfgl-package "pkg2" :name 'pkg2 :owners '(layer-filter-3)) + (cfgl-package "pkg4" :name 'pkg4 :owners '(layer-filter-3)) + (cfgl-package "pkg8" :name 'pkg8 :owners '(layer-filter-3))) + (configuration-layer/filter-objects + pkgs (lambda (x) + (and (not (eq 'local (oref x :location))) + (not (oref x :excluded))))))))) + +(ert-deftest test-filter-packages--example-filter-packages-both-local-and-excluded () + (defun layer-filter-4/init-pkg1 nil) + (defun layer-filter-4/init-pkg2 nil) + (defun layer-filter-4/init-pkg3 nil) + (defun layer-filter-4/init-pkg4 nil) + (defun layer-filter-4/init-pkg5 nil) + (defun layer-filter-4/init-pkg6 nil) + (defun layer-filter-4/init-pkg7 nil) + (defun layer-filter-4/init-pkg8 nil) + (let* (configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + (pkg1 (configuration-layer/make-package 'pkg1 'layer-filter-4)) + (pkg2 (configuration-layer/make-package 'pkg2 'layer-filter-4)) + (pkg3 (configuration-layer/make-package 'pkg3 'layer-filter-4)) + (pkg4 (configuration-layer/make-package 'pkg4 'layer-filter-4)) + (pkg5 (configuration-layer/make-package 'pkg5 'layer-filter-4)) + (pkg6 (configuration-layer/make-package 'pkg6 'layer-filter-4)) + (pkg7 (configuration-layer/make-package 'pkg7 'layer-filter-4)) + (pkg8 (configuration-layer/make-package 'pkg8 'layer-filter-4)) + (pkgs (list pkg1 pkg2 pkg3 pkg4 pkg5 pkg6 pkg7 pkg8))) + (helper--set-layers + `(,(cfgl-layer "layer-filter-4" :name 'layer-filter-4)) t) + (oset pkg1 :location 'local) + (oset pkg1 :excluded t) + (oset pkg3 :location 'local) + (oset pkg5 :excluded t) + (oset pkg6 :location 'local) + (oset pkg6 :excluded t) + (should + (equal (list (cfgl-package "pkg2" + :name 'pkg2 + :owners '(layer-filter-4)) + (cfgl-package "pkg3" + :name 'pkg3 + :location 'local + :owners '(layer-filter-4)) + (cfgl-package "pkg4" :name 'pkg4 + :owners '(layer-filter-4)) + (cfgl-package "pkg5" :name 'pkg5 + :excluded t + :owners '(layer-filter-4)) + (cfgl-package "pkg7" :name 'pkg7 + :owners '(layer-filter-4)) + (cfgl-package "pkg8" :name 'pkg8 + :owners '(layer-filter-4))) + (configuration-layer/filter-objects + pkgs (lambda (x) + (or (not (eq 'local (oref x :location))) + (not (oref x :excluded))))))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer/package-usedp +;; --------------------------------------------------------------------------- + +(ert-deftest test-package-usedp--package-with-owner-can-be-used () + (let* ((layer1 (cfgl-layer "layer1" :name 'layer1 :dir "/path/")) + (layer1-packages '(pkg1 pkg2 pkg3)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (mocker-mock-default-record-cls 'mocker-stub-record)) + (helper--set-layers (list layer1) t) + (helper--set-packages + (list (cfgl-package "pkg3" :name 'pkg3 :owners '(layer1)) + (cfgl-package "pkg2" :name 'pkg2 :owners '(layer1)) + (cfgl-package "pkg1" :name 'pkg1 :owners '(layer1))) t) + (should (configuration-layer/package-usedp (nth (random 3) + layer1-packages))))) + +(ert-deftest test-package-usedp--package-with-no-owner-cannot-be-used () + (let* ((layer1 (cfgl-layer "layer1" :name 'layer1 :dir "/path/")) + (layers (list layer1)) + (layer1-packages '(pkg1 pkg2 pkg3)) + (mocker-mock-default-record-cls 'mocker-stub-record) + (configuration-layer--used-packages + (list (cfgl-package "pkg3" :name 'pkg3) + (cfgl-package "pkg2" :name 'pkg2) + (cfgl-package "pkg1" :name 'pkg1)))) + (should (null (configuration-layer/package-usedp (nth (random 3) + layer1-packages)))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer//directory-type +;; --------------------------------------------------------------------------- + +(ert-deftest test-directory-type--input-is-a-file () + (let ((input "/a/path/to/a/layer/file")) + (mocker-let + ((file-directory-p (f) + ((:record-cls 'mocker-stub-record + :output nil + :occur 1)))) + (should (null (configuration-layer//directory-type input)))))) + +(ert-deftest test-directory-type--category () + (let ((input (concat configuration-layer-directory "+vim/"))) + (mocker-let + ((file-directory-p (f) + ((:record-cls 'mocker-stub-record :output t :occur 1)))) + (should (eq 'category (configuration-layer//directory-type input)))))) + +(ert-deftest test-directory-type--input-is-an-empty-directory () + (let ((input "/a/path/to/a/layer/")) + (mocker-let + ((file-directory-p (f) + ((:record-cls 'mocker-stub-record :output t :occur 1))) + (directory-files + (directory &optional full match nosort) + ((:record-cls 'mocker-stub-record :output nil :occur 1)))) + (should (null (configuration-layer//directory-type input)))))) + +(ert-deftest test-directory-type--input-is-directory-and-not-a-layer () + (let ((input "/a/path/to/a/layer/")) + (mocker-let + ((file-directory-p (f) + ((:record-cls 'mocker-stub-record :output t :occur 1))) + (directory-files + (directory &optional full match nosort) + ((:record-cls 'mocker-stub-record + :output '("toto.el" "tata.el") + :occur 1)))) + (should (null (configuration-layer//directory-type input)))))) + +(ert-deftest test-directory-type--layer-with-packages.el () + (let ((input "/a/path/to/a/layer/")) + (mocker-let + ((file-directory-p (f) + ((:record-cls 'mocker-stub-record :output t :occur 1))) + (directory-files + (directory &optional full match nosort) + ((:record-cls 'mocker-stub-record :output '("packages.el") :occur 1)))) + (should (eq 'layer (configuration-layer//directory-type input)))))) + +(ert-deftest test-directory-type--layer-with-config.el () + (let ((input "/a/path/to/a/layer/")) + (mocker-let + ((file-directory-p (f) + ((:record-cls 'mocker-stub-record :output t :occur 1))) + (directory-files + (directory &optional full match nosort) + ((:record-cls 'mocker-stub-record :output '("config.el") :occur 1)))) + (should (eq 'layer (configuration-layer//directory-type input)))))) + +(ert-deftest test-directory-type--layer-with-keybindings.el () + (let ((input "/a/path/to/a/layer/")) + (mocker-let + ((file-directory-p (f) + ((:record-cls 'mocker-stub-record :output t :occur 1))) + (directory-files + (directory &optional full match nosort) + ((:record-cls 'mocker-stub-record + :output '("keybindings.el") + :occur 1)))) + (should (eq 'layer (configuration-layer//directory-type input)))))) + +(ert-deftest test-directory-type--layer-with-funcs.el () + (let ((input "/a/path/to/a/layer/")) + (mocker-let + ((file-directory-p (f) + ((:record-cls 'mocker-stub-record :output t :occur 1))) + (directory-files + (directory &optional full match nosort) + ((:record-cls 'mocker-stub-record :output '("funcs.el") :occur 1)))) + (should (eq 'layer (configuration-layer//directory-type input)))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer//get-category-from-path +;; --------------------------------------------------------------------------- + +(ert-deftest test-get-category-from-path--input-is-a-file () + (let ((input "/a/path/to/a/file")) + (mocker-let + ((file-directory-p (f) + ((:record-cls 'mocker-stub-record + :output nil + :occur 1)))) + (should (null (configuration-layer//get-category-from-path input)))))) + +(ert-deftest test-get-category-from-path--input-is-a-regular-directory () + (let ((input "/a/path/to/a/layer/")) + (mocker-let + ((file-directory-p (f) + ((:record-cls 'mocker-stub-record + :output t + :occur 1)))) + (should (null (configuration-layer//get-category-from-path input)))))) + +(ert-deftest test-get-category-from-path--return-category () + (let ((input "/a/path/to/a/+cat/")) + (mocker-let + ((file-directory-p (f) + ((:record-cls 'mocker-stub-record :output t :occur 1)))) + (should (eq 'cat (configuration-layer//get-category-from-path input)))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer//gather-auto-mode-extensions +;; --------------------------------------------------------------------------- + +(ert-deftest test-gather-auto-mode-extensions--one-entry-in-auto-mode-alist () + (let ((auto-mode-alist '(("\\.spacemacs\\'" . mode)))) + (should (equal + "\\(\\.spacemacs\\'\\)" + (configuration-layer//gather-auto-mode-extensions 'mode))))) + +(ert-deftest test-gather-auto-mode-extensions--several-entries-in-auto-mode-alist () + (let ((auto-mode-alist '(("\\.spacemacs\\'" . mode) + ("\\.dotspacemacs\\'" . mode) + ("\\.spacelayer\\'" . mode)))) + (should (equal + "\\(\\.spacelayer\\'\\|\\.dotspacemacs\\'\\|\\.spacemacs\\'\\)" + (configuration-layer//gather-auto-mode-extensions 'mode))))) + +(ert-deftest test-gather-auto-mode-extensions--ext-entry-is-not-symbol () + (let ((auto-mode-alist '(((nil t) . mode)))) + (should (null (configuration-layer//gather-auto-mode-extensions 'mode))))) + +(ert-deftest test-gather-auto-mode-extensions--mode-entry-is-not-symbol () + (let ((auto-mode-alist '(("ext" . (lambda nil nil))))) + (should (null (configuration-layer//gather-auto-mode-extensions 'mode))))) + +(ert-deftest test-gather-auto-mode-extensions--regexp-correctness () + "Correctness is a big word here :-)" + (let ((regexp (configuration-layer//gather-auto-mode-extensions + 'emacs-lisp-mode))) + (should (string-match-p regexp "/_emacs")) + (should (string-match-p regexp "/.toto_gnus")) + (should (string-match-p regexp "/.toto_viper")) + (should (string-match-p regexp "/toto/emacs.el")) + (should (string-match-p regexp "/toto/project.ede")) + (should (not (string-match-p regexp "/toto/emacs.dummy"))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer//lazy-install-extensions-for-layer +;; --------------------------------------------------------------------------- + +(ert-deftest test-lazy-install-extensions-for-layer--owned-packages () + (let (configuration-layer--used-layers + (configuration-layer--indexed-layers (make-hash-table :size 1024)) + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048)) + (auto-mode-alist '(("\\.pkg1\\'" . pkg1) + ("\\.pkg2\\'" . pkg2)))) + (helper--set-layers + (list (cfgl-layer "layer" :name 'layer :packages '(pkg1 pkg2))) t) + (helper--set-packages + (list (cfgl-package "pkg1" :name 'pkg1 :owners '(layer)) + (cfgl-package "pkg2" :name 'pkg2 :owners '(layer))) t) + (should (equal '((pkg2 . "\\(\\.pkg2\\'\\)") + (pkg1 . "\\(\\.pkg1\\'\\)")) + (configuration-layer//lazy-install-extensions-for-layer + 'layer))))) + +(ert-deftest test-lazy-install-extensions-for-layer--not-owned-package () + (let ((configuration-layer--layers + (list (cfgl-layer "layer" :name 'layer :packages '(pkg1)))) + (configuration-layer--used-packages + (list (cfgl-package "pkg1" :name 'pkg1 :owners '(other)))) + (auto-mode-alist '(("\\.pkg1\\'" . pkg1)))) + (should (null (configuration-layer//lazy-install-extensions-for-layer 'layer))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer//insert-lazy-install-form +;; --------------------------------------------------------------------------- + +(ert-deftest test-insert-lazy-install-form () + (cl-letf (((symbol-function 'insert) 'identity)) + (should + (equal + (concat "(configuration-layer/lazy-install 'layer " + ":extensions '(\"\\\\(\\\\.ext\\\\'\\\\)\" mode))\n") + (configuration-layer//insert-lazy-install-form 'layer 'mode "\\(\\.ext\\'\\)"))))) + +;; --------------------------------------------------------------------------- +;; configuration-layer/configured-packages-stats +;; --------------------------------------------------------------------------- + +(ert-deftest test-configured-packages-stats--correct-counts () + (let (configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (helper--set-packages + (list (cfgl-package "pkg1" :name 'pkg1 :location 'built-in) + (cfgl-package "pkg2" :name 'pkg2 :location 'built-in) + (cfgl-package "pkg3" :name 'pkg3 :location 'elpa) + (cfgl-package "pkg4" :name 'pkg4 :location 'elpa) + (cfgl-package "pkg5" :name 'pkg5 :location 'elpa) + (cfgl-package "pkg6" :name 'pkg6 :location 'local) + (cfgl-package "pkg7" :name 'pkg7 :location '(recipe :foo bar)) + (cfgl-package "pkg8" :name 'pkg8 :location '(recipe :foo bar))) t) + (should (equal '((total 8) + (elpa 3) + (recipe 2) + (local 1) + (built-in 2)) + (configuration-layer/configured-packages-stats + configuration-layer--used-packages))))) + +(ert-deftest test-configured-packages-stats--sum-is-correct () + (let (stats + configuration-layer--used-packages + (configuration-layer--indexed-packages (make-hash-table :size 2048))) + (helper--set-packages + (list (cfgl-package "pkg1" :name 'pkg1 :location 'built-in) + (cfgl-package "pkg2" :name 'pkg2 :location 'built-in) + (cfgl-package "pkg3" :name 'pkg3 :location 'elpa) + (cfgl-package "pkg4" :name 'pkg4 :location 'elpa) + (cfgl-package "pkg5" :name 'pkg5 :location 'elpa) + (cfgl-package "pkg6" :name 'pkg6 :location 'local) + (cfgl-package "pkg7" :name 'pkg7 :location '(recipe :foo bar)) + (cfgl-package "pkg8" :name 'pkg8 :location '(recipe :foo bar))) t) + (setq stats (configuration-layer/configured-packages-stats + configuration-layer--used-packages)) + (should (equal 8 (+ (cadr (assq 'elpa stats)) + (cadr (assq 'recipe stats)) + (cadr (assq 'local stats)) + (cadr (assq 'built-in stats))))))) diff --git a/tests/core/core-funcs-utest.el b/tests/core/core-funcs-utest.el new file mode 100644 index 0000000..117f3e8 --- /dev/null +++ b/tests/core/core-funcs-utest.el @@ -0,0 +1,80 @@ +;;; core-funcs-utest.el --- Spacemacs Unit Test File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(require 'mocker) +(require 'core-funcs) + +;; --------------------------------------------------------------------------- +;; spacemacs/mplist-get +;; --------------------------------------------------------------------------- + +(ert-deftest test-mplist-get--one-property () + (let* ((input '(dummy :property sym1 sym2 sym3)) + (result (spacemacs/mplist-get input :property))) + (should (equal '(sym1 sym2 sym3) result)))) + +(ert-deftest test-mplist-get--multiple-properties-get-first () + (let* ((input '(dummy :prop1 sym1 sym2 sym3 :prop2 sym4 :prop3 sym5 sym6)) + (result (spacemacs/mplist-get input :prop1))) + (should (equal '(sym1 sym2 sym3) result)))) + +(ert-deftest test-mplist-get--multiple-properties-get-middle () + (let* ((input '(dummy :prop1 sym1 sym2 sym3 :prop2 sym4 :prop3 sym5 sym6)) + (result (spacemacs/mplist-get input :prop2))) + (should (equal '(sym4) result)))) + +(ert-deftest test-mplist-get--multiple-properties-get-last () + (let* ((input '(dummy :prop1 sym1 sym2 sym3 :prop2 sym4 :prop3 sym5 sym6)) + (result (spacemacs/mplist-get input :prop3))) + (should (equal '(sym5 sym6) result)))) + +(ert-deftest test-mplist-get--one-property-no-value () + (let* ((input '(dummy :property)) + (result (spacemacs/mplist-get input :property))) + (should (null result)))) + +(ert-deftest test-mplist-get--multiple-same-poperty-ignore-all-but-first () + (let* ((input '(dummy :property val1 :property val2)) + (result (spacemacs/mplist-get input :property))) + (should (equal '(val1) result)))) + +;; --------------------------------------------------------------------------- +;; spacemacs/mplist-remove +;; --------------------------------------------------------------------------- + +(ert-deftest test-mplist-remove--one-property () + (let* ((input '(dummy :property sym1 sym2 sym3)) + (result (spacemacs/mplist-remove input :property))) + (should (equal '(dummy) result)))) + +(ert-deftest test-mplist-remove--one-property-no-value () + (let* ((input '(dummy :property)) + (result (spacemacs/mplist-remove input :property))) + (should (equal '(dummy) result)))) + +(ert-deftest test-mplist-remove--multiple-properties-remove-first () + (let* ((input '(dummy :prop1 sym1 sym2 sym3 :prop2 sym4 sym5 :prop3 sym6)) + (result (spacemacs/mplist-remove input :prop1))) + (should (equal '(dummy :prop2 sym4 sym5 :prop3 sym6) result)))) + +(ert-deftest test-mplist-remove--multiple-properties-remove-middle () + (let* ((input '(dummy :prop1 sym1 sym2 sym3 :prop2 sym4 sym5 :prop3 sym6)) + (result (spacemacs/mplist-remove input :prop2))) + (should (equal '(dummy :prop1 sym1 sym2 sym3 :prop3 sym6) result)))) + +(ert-deftest test-mplist-remove--multiple-properties-remove-last () + (let* ((input '(dummy :prop1 sym1 sym2 sym3 :prop2 sym4 sym5 :prop3 sym6)) + (result (spacemacs/mplist-remove input :prop3))) + (should (equal '(dummy :prop1 sym1 sym2 sym3 :prop2 sym4 sym5) result)))) + +(ert-deftest test-mplist-remove--multiple-same-property-remove-only-first () + (let* ((input '(dummy :prop1 sym1 sym2 sym3 :prop2 sym4 sym5 :prop1 sym6)) + (result (spacemacs/mplist-remove input :prop1))) + (should (equal '(dummy :prop2 sym4 sym5 :prop1 sym6) result)))) diff --git a/tests/core/core-release-management-ftest.el b/tests/core/core-release-management-ftest.el new file mode 100644 index 0000000..a484861 --- /dev/null +++ b/tests/core/core-release-management-ftest.el @@ -0,0 +1,31 @@ +;;; core-release-management-ftest.el --- Spacemacs Functional Test File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Alberto Zaccagni +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(require 'core-spacemacs) + +;; --------------------------------------------------------------------------- +;; spacemacs//git-has-remote +;; --------------------------------------------------------------------------- + +(ert-deftest test-git-has-remote--command-is-working () + (should (numberp (spacemacs//git-has-remote "origin")))) + +(ert-deftest test-git-has-remote--input-is-not-a-remote () + (should (equal (spacemacs//git-has-remote "clearly-not-a-R3M0T3!") nil))) + +;; --------------------------------------------------------------------------- +;; spacemacs//git-fetch-tags +;; --------------------------------------------------------------------------- + +(ert-deftest test-git-fetch-tags--command-is-working () + (should (equal t (spacemacs//git-fetch-tags "origin" "master")))) + +(ert-deftest test-git-fetch-tags--input-is-not-a-remote () + (should (equal nil (spacemacs//git-fetch-tags "qwerty" "master")))) diff --git a/tests/core/core-spacemacs-buffer-ftest.el b/tests/core/core-spacemacs-buffer-ftest.el new file mode 100644 index 0000000..bfcdc68 --- /dev/null +++ b/tests/core/core-spacemacs-buffer-ftest.el @@ -0,0 +1,121 @@ +;;; core-spacemacs-buffer-ftest.el --- Spacemacs Unit Test File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +(require 'core-spacemacs-buffer) + +(setq-default fill-column 80) + +;; --------------------------------------------------------------------------- +;; spacemacs//render-framed-text +;; --------------------------------------------------------------------------- + +(defvar test-text + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.") + +(ert-deftest test-render-framed-text--msg-width-caption-and-padding () + (should (equal (spacemacs//render-framed-text test-text 32 "Caption" 4) + "╭─Caption──────────────────────╮ +│ │ +│ Lorem ipsum dolor sit │ +│ amet, consectetur │ +│ adipiscing elit, sed │ +│ do eiusmod tempor │ +│ incididunt ut labore │ +│ et dolore magna │ +│ aliqua. │ +│ │ +╰──────────────────────────────╯" + ))) + +(ert-deftest test-render-framed-text--msg-width-caption-no-padding () + (should (equal (spacemacs//render-framed-text test-text 32 "Caption") + "╭─Caption──────────────────────╮ +│ │ +│ Lorem ipsum dolor sit amet, │ +│ consectetur adipiscing elit, │ +│ sed do eiusmod tempor │ +│ incididunt ut labore et │ +│ dolore magna aliqua. │ +│ │ +╰──────────────────────────────╯" + ))) + +(ert-deftest test-render-framed-text--msg-width-no-caption-no-padding () + (should (equal (spacemacs//render-framed-text test-text 32) + "╭──────────────────────────────╮ +│ │ +│ Lorem ipsum dolor sit amet, │ +│ consectetur adipiscing elit, │ +│ sed do eiusmod tempor │ +│ incididunt ut labore et │ +│ dolore magna aliqua. │ +│ │ +╰──────────────────────────────╯" + ))) + +(ert-deftest test-render-framed-text--msg-no-width-no-caption-no-padding () + (should (equal (spacemacs//render-framed-text test-text) + "╭──────────────────────────────────────────────────────────────────────────────────╮ +│ │ +│ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor │ +│ incididunt ut labore et dolore magna aliqua. │ +│ │ +╰──────────────────────────────────────────────────────────────────────────────────╯" + ))) + +(ert-deftest test-render-framed-text--msg-short-text () + (should (equal (spacemacs//render-framed-text "Short content.") + "╭──────────────────────────────────────────────────────────────────────────────────╮ +│ │ +│ Short content. │ +│ │ +╰──────────────────────────────────────────────────────────────────────────────────╯" + ))) + +(ert-deftest test-render-framed-text--msg-several-paragraphs () + (should (equal (spacemacs//render-framed-text + (concat "\n" + test-text "\n\n\n" + test-text "\n\n" + test-text "\n")) + "╭──────────────────────────────────────────────────────────────────────────────────╮ +│ │ +│ │ +│ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor │ +│ incididunt ut labore et dolore magna aliqua. │ +│ │ +│ │ +│ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor │ +│ incididunt ut labore et dolore magna aliqua. │ +│ │ +│ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor │ +│ incididunt ut labore et dolore magna aliqua. │ +│ │ +│ │ +╰──────────────────────────────────────────────────────────────────────────────────╯" + ))) + +(ert-deftest test-render-framed-text--file-caption-and-padding () + (should (equal (spacemacs//render-framed-text + (concat spacemacs-test-directory "core/data/framed-text.txt") + 62 "Caption" 4) + "╭─Caption────────────────────────────────────────────────────╮ +│ │ +│ Lorem ipsum dolor sit amet, consectetur adipiscing │ +│ elit, sed do eiusmod tempor incididunt ut labore et │ +│ dolore magna aliqua. Ut enim ad minim veniam, quis │ +│ nostrud exercitation ullamco laboris nisi ut aliquip │ +│ ex ea commodo consequat. Duis aute irure dolor in │ +│ reprehenderit in voluptate velit esse cillum dolore │ +│ eu fugiat nulla pariatur. Excepteur sint occaecat │ +│ cupidatat non proident, sunt in culpa qui officia │ +│ deserunt mollit anim id est laborum. │ +│ │ +╰────────────────────────────────────────────────────────────╯" + ))) diff --git a/tests/core/core-spacemacs-ftest.el b/tests/core/core-spacemacs-ftest.el new file mode 100644 index 0000000..2678609 --- /dev/null +++ b/tests/core/core-spacemacs-ftest.el @@ -0,0 +1,22 @@ +;;; core-spacemacs-ftest.el --- Spacemacs Functional Test File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Alberto Zaccagni +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(require 'mocker) +(require 'core-spacemacs) + +(ert-deftest assertion-library-should-work () + "the assertion library should works" + (mocker-let ((foo (n) + ((:input '(1) :output 1))) + (bar (n m) + ((:input '(2 2) :output 2)))) + (should (equal (foo 1) 1)) + (should (equal (bar 2 2) 2)))) + diff --git a/tests/core/data/framed-text.txt b/tests/core/data/framed-text.txt new file mode 100644 index 0000000..1b37687 --- /dev/null +++ b/tests/core/data/framed-text.txt @@ -0,0 +1 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. diff --git a/tests/layers/+distribution/spacemacs-base/Makefile b/tests/layers/+distribution/spacemacs-base/Makefile new file mode 100644 index 0000000..78606df --- /dev/null +++ b/tests/layers/+distribution/spacemacs-base/Makefile @@ -0,0 +1,20 @@ +## Makefile --- Spacemacs Core +## +## Copyright (c) 2012-2016 Sylvain Benner & Contributors +## +## Author: Sylvain Benner +## URL: https://github.com/syl20bnr/spacemacs +## +## This file is not part of GNU Emacs. +## +## License: GPLv3 + +TEST_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) + +LOAD_FILES = init.el +UNIT_TEST_FILES = \ + evil-evilified-state-utest.el +FUNC_TEST_FILES = \ + evil-evilified-state-ftest.el + +include ../../../../spacemacs.mk diff --git a/tests/layers/+distribution/spacemacs-base/dotspacemacs.el b/tests/layers/+distribution/spacemacs-base/dotspacemacs.el new file mode 100644 index 0000000..8cc9a7f --- /dev/null +++ b/tests/layers/+distribution/spacemacs-base/dotspacemacs.el @@ -0,0 +1,7 @@ +(defun dotspacemacs/layers () + (setq-default + dotspacemacs-distribution 'spacemacs)) +(defun dotspacemacs/init ()) +(defun dotspacemacs/user-init ()) +(defun dotspacemacs/config ()) +(defun dotspacemacs/user-config ()) diff --git a/tests/layers/+distribution/spacemacs-base/evil-evilified-state-ftest.el b/tests/layers/+distribution/spacemacs-base/evil-evilified-state-ftest.el new file mode 100644 index 0000000..0e36833 --- /dev/null +++ b/tests/layers/+distribution/spacemacs-base/evil-evilified-state-ftest.el @@ -0,0 +1,410 @@ +;;; core-evilified-state-ftest.el --- Spacemacs Functional Test File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +(require 'mocker) +(require 'evil-evilified-state) + +;; --------------------------------------------------------------------------- +;; evilified-state-evilify-map +;; --------------------------------------------------------------------------- + +;; commands + +(ert-deftest test-evilify-map--s () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "s" 'evil-func) + evil-map)) + (input-map (make-sparse-keymap))) + (define-key input-map "s" 'func) + (evilified-state-evilify-map input-map) + (should (equal '((115 . func) + (evilified-state + keymap "Auxiliary keymap for Evilified state" + (83 . func) + (115 . evil-func))) + (evilified-state--sort-keymap input-map))))) + +(ert-deftest test-evilify-map--s-2-evilified () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "s" 'evil-func) + (define-key evil-map "S" 'evil-func2) + evil-map)) + (input-map (make-sparse-keymap))) + (define-key input-map "s" 'func) + (evilified-state-evilify-map input-map) + (should (equal '((115 . func) + (evilified-state + keymap "Auxiliary keymap for Evilified state" + (19 . func) + (83 . evil-func2) + (115 . evil-func))) + (evilified-state--sort-keymap input-map))))) + +(ert-deftest test-evilify-map--s-S () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "s" 'evil-func) + evil-map)) + (input-map (make-sparse-keymap))) + (define-key input-map "s" 'func1) + (define-key input-map "S" 'func2) + (evilified-state-evilify-map input-map) + (should (equal '((115 . func1) + (83 . func2) + (evilified-state + keymap "Auxiliary keymap for Evilified state" + (19 . func2) + (83 . func1) + (115 . evil-func))) + (evilified-state--sort-keymap input-map))))) + +(ert-deftest test-evilify-map--s-S-reversed-order () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "s" 'evil-func) + evil-map)) + (input-map (make-sparse-keymap))) + (define-key input-map "S" 'func2) + (define-key input-map "s" 'func1) + (evilified-state-evilify-map input-map) + (should (equal '((115 . func1) + (83 . func2) + (evilified-state + keymap "Auxiliary keymap for Evilified state" + (19 . func2) + (83 . func1) + (115 . evil-func))) + (evilified-state--sort-keymap input-map))))) + +(ert-deftest test-evilify-map--s-S-2-evilified () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "s" 'evil-func1) + (define-key evil-map "S" 'evil-func2) + evil-map)) + (input-map (make-sparse-keymap))) + (define-key input-map "s" 'func1) + (define-key input-map "S" 'func2) + (evilified-state-evilify-map input-map) + (should (equal '((115 . func1) + (83 . func2) + (evilified-state + keymap "Auxiliary keymap for Evilified state" + (33554451 . func2) + (19 . func1) + (83 . evil-func2) + (115 . evil-func1))) + (evilified-state--sort-keymap input-map))))) + +(ert-deftest test-evilify-map--s-S-2-evilified-reversed-order () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "S" 'evil-func2) + (define-key evil-map "s" 'evil-func1) + evil-map)) + (input-map (make-sparse-keymap))) + (define-key input-map "S" 'func2) + (define-key input-map "s" 'func1) + (evilified-state-evilify-map input-map) + (should (equal '((115 . func1) + (83 . func2) + (evilified-state + keymap "Auxiliary keymap for Evilified state" + (33554451 . func2) + (19 . func1) + (83 . evil-func2) + (115 . evil-func1))) + (evilified-state--sort-keymap input-map))))) + +(ert-deftest test-evilify-map--s-S-C-s () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "s" 'evil-func) + evil-map)) + (input-map (make-sparse-keymap))) + (define-key input-map "s" 'func1) + (define-key input-map "S" 'func2) + (define-key input-map (kbd "C-s") 'func3) + (evilified-state-evilify-map input-map) + (should (equal '((115 . func1) + (83 . func2) + (19 . func3) + (evilified-state + keymap "Auxiliary keymap for Evilified state" + (33554451 . func3) + (19 . func2) + (83 . func1) + (115 . evil-func))) + (evilified-state--sort-keymap input-map))))) + +(ert-deftest test-evilify-map--s-S-C-s-shuffled () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "s" 'evil-func) + evil-map)) + (input-map (make-sparse-keymap))) + (define-key input-map "s" 'func1) + (define-key input-map (kbd "C-s") 'func3) + (define-key input-map "S" 'func2) + (evilified-state-evilify-map input-map) + (should (equal '((115 . func1) + (83 . func2) + (19 . func3) + (evilified-state + keymap "Auxiliary keymap for Evilified state" + (33554451 . func3) + (19 . func2) + (83 . func1) + (115 . evil-func))) + (evilified-state--sort-keymap input-map))))) + +(ert-deftest test-evilify-map--s-S-C-s-2-evilified () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "s" 'evil-func1) + (define-key evil-map "S" 'evil-func2) + evil-map)) + (input-map (make-sparse-keymap))) + (define-key input-map "s" 'func1) + (define-key input-map "S" 'func2) + (define-key input-map (kbd "C-s") 'func3) + (mocker-let + ((spacemacs-buffer/warning (msg &rest args) + ((:record-cls 'mocker-stub-record + :output nil :occur 1)))) + (evilified-state-evilify-map input-map) + (should (equal '((115 . func1) + (83 . func2) + (19 . func3) + (evilified-state + keymap "Auxiliary keymap for Evilified state" + (33554451 . func2) + (19 . func1) + (83 . evil-func2) + (115 . evil-func1))) + (evilified-state--sort-keymap input-map)))))) + +(ert-deftest test-evilify-map--s-C-s-S-2-evilified-shuffled () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "s" 'evil-func1) + (define-key evil-map "S" 'evil-func2) + evil-map)) + (input-map (make-sparse-keymap))) + (define-key input-map "s" 'func1) + (define-key input-map (kbd "C-s") 'func3) + (define-key input-map "S" 'func2) + (mocker-let + ((spacemacs-buffer/warning (msg &rest args) + ((:record-cls 'mocker-stub-record + :output nil :occur 1)))) + (evilified-state-evilify-map input-map) + (should (equal '((115 . func1) + (83 . func2) + (19 . func3) + (evilified-state + keymap "Auxiliary keymap for Evilified state" + (33554451 . func2) + (19 . func1) + (83 . evil-func2) + (115 . evil-func1))) + (evilified-state--sort-keymap input-map)))))) + +;; keymaps + +(ert-deftest test-evilify-map--s-keymap () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "s" 'evil-func) + evil-map)) + (input-map (make-sparse-keymap)) + (submap (make-sparse-keymap))) + (define-key input-map "s" submap) + (define-key submap "t" 'func) + (evilified-state-evilify-map input-map) + (should (equal '((115 keymap (116 . func)) + (evilified-state + keymap "Auxiliary keymap for Evilified state" + (83 keymap (116 . func)) + (115 . evil-func))) + (evilified-state--sort-keymap input-map))))) + +(ert-deftest test-evilify-map--s-keymap-2-evilified () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "s" 'evil-func1) + (define-key evil-map "S" 'evil-func2) + evil-map)) + (input-map (make-sparse-keymap)) + (submap (make-sparse-keymap))) + (define-key input-map "s" submap) + (define-key submap "t" 'func) + (evilified-state-evilify-map input-map) + (should (equal '((115 keymap (116 . func)) + (evilified-state + keymap "Auxiliary keymap for Evilified state" + (19 keymap (116 . func)) + (83 . evil-func2) + (115 . evil-func1))) + (evilified-state--sort-keymap input-map))))) + +(ert-deftest test-evilify-map--s-S-keymaps () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "s" 'evil-func) + evil-map)) + (input-map (make-sparse-keymap)) + (submap (make-sparse-keymap))) + (define-key input-map "s" submap) + (define-key input-map "S" submap) + (define-key submap "t" 'func) + (evilified-state-evilify-map input-map) + (should (equal '((115 keymap (116 . func)) + (83 keymap (116 . func)) + (evilified-state + keymap "Auxiliary keymap for Evilified state" + (19 keymap (116 . func)) + (83 keymap (116 . func)) + (115 . evil-func))) + (evilified-state--sort-keymap input-map))))) + +(ert-deftest test-evilify-map--s-S-keymaps-2-evilified () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "s" 'evil-func1) + (define-key evil-map "S" 'evil-func2) + evil-map)) + (input-map (make-sparse-keymap)) + (submap (make-sparse-keymap))) + (define-key input-map "s" submap) + (define-key input-map "S" submap) + (define-key submap "t" 'func) + (evilified-state-evilify-map input-map) + (should (equal '((115 keymap (116 . func)) + (83 keymap (116 . func)) + (evilified-state + keymap "Auxiliary keymap for Evilified state" + (33554451 keymap (116 . func)) + (19 keymap (116 . func)) + (83 . evil-func2) + (115 . evil-func1))) + (evilified-state--sort-keymap input-map))))) + +(ert-deftest test-evilify-map--s-S-C-s-keymaps () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "s" 'evil-func) + evil-map)) + (input-map (make-sparse-keymap)) + (submap (make-sparse-keymap))) + (define-key input-map "s" submap) + (define-key input-map "S" submap) + (define-key input-map (kbd "C-s") submap) + (define-key submap "t" 'func) + (evilified-state-evilify-map input-map) + (should (equal '((115 keymap (116 . func)) + (83 keymap (116 . func)) + (19 keymap (116 . func)) + (evilified-state + keymap "Auxiliary keymap for Evilified state" + (33554451 keymap (116 . func)) + (19 keymap (116 . func)) + (83 keymap (116 . func)) + (115 . evil-func))) + (evilified-state--sort-keymap input-map))))) + +(ert-deftest test-evilify-map--s-S-C-s-keymaps-2-evilified () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "s" 'evil-func1) + (define-key evil-map "S" 'evil-func2) + evil-map)) + (input-map (make-sparse-keymap)) + (submap (make-sparse-keymap))) + (define-key input-map "s" submap) + (define-key input-map "S" submap) + (define-key input-map (kbd "C-s") submap) + (define-key submap "t" 'func) + (mocker-let + ((spacemacs-buffer/warning (msg &rest args) + ((:record-cls 'mocker-stub-record + :output nil :occur 1)))) + (evilified-state-evilify-map input-map) + (should (equal '((115 keymap (116 . func)) + (83 keymap (116 . func)) + (19 keymap (116 . func)) + (evilified-state + keymap "Auxiliary keymap for Evilified state" + (33554451 keymap (116 . func)) + (19 keymap (116 . func)) + (83 . evil-func2) + (115 . evil-func1))) + (evilified-state--sort-keymap input-map)))))) + +;; commands and keymaps + +(ert-deftest test-evilify-map--s-command-and-keymap () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "s" 'evil-func) + evil-map)) + (input-map (make-sparse-keymap)) + (submap (make-sparse-keymap))) + (define-key input-map "s" 'func) + (define-key input-map "S" submap) + (define-key submap "t" 'func) + (evilified-state-evilify-map input-map) + (should (equal '((115 . func) + (83 keymap (116 . func)) + (evilified-state + keymap "Auxiliary keymap for Evilified state" + (19 keymap (116 . func)) + (83 . func) + (115 . evil-func))) + (evilified-state--sort-keymap input-map))))) + +;; idem-potency + +(ert-deftest test-evilify-map--idem-potent () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "s" 'evil-func) + evil-map)) + (input-map (make-sparse-keymap)) + (submap (make-sparse-keymap))) + (define-key input-map "e" 'func1) + (define-key input-map (kbd "C-c C-x") 'func3) + (define-key input-map "s" 'func2) + (define-key input-map "S" submap) + (define-key submap "t" 'func) + (dotimes (_ 10) + (evilified-state-evilify-map input-map)) + (should (equal '((115 . func2) + (101 . func1) + (83 keymap (116 . func)) + (3 keymap (24 . func3)) + (evilified-state + keymap "Auxiliary keymap for Evilified state" + (19 keymap (116 . func)) + (83 . func2) + (115 . evil-func))) + (evilified-state--sort-keymap input-map))))) + +;; eval-after-load + +(ert-deftest test-evilify-map--eval-after-load-already-loaded () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "s" 'evil-func) + evil-map)) + (input-map (make-sparse-keymap))) + (define-key input-map "s" 'func) + ;; pass a feature already loaded at the time of calling + (evilified-state-evilify-map input-map :eval-after-load core-funcs) + (should (equal '((115 . func) + (evilified-state + keymap "Auxiliary keymap for Evilified state" + (83 . func) + (115 . evil-func))) + (evilified-state--sort-keymap input-map))))) + +(ert-deftest test-evilify-map--eval-after-load-not-loaded () + (let ((evil-evilified-state-map (let ((evil-map (make-sparse-keymap))) + (define-key evil-map "s" 'evil-func) + evil-map)) + (input-map (make-sparse-keymap))) + (define-key input-map "s" 'func) + (evilified-state-evilify-map input-map :eval-after-load dummy-feature) + ;; unmodified keymap since `dummy-feature' is not loaded + (should (equal '((115 . func)) + (evilified-state--sort-keymap input-map))))) diff --git a/tests/layers/+distribution/spacemacs-base/evil-evilified-state-utest.el b/tests/layers/+distribution/spacemacs-base/evil-evilified-state-utest.el new file mode 100644 index 0000000..0281c8a --- /dev/null +++ b/tests/layers/+distribution/spacemacs-base/evil-evilified-state-utest.el @@ -0,0 +1,117 @@ +;;; evil-evilified-state-utest.el --- Spacemacs Unit Test File +;; +;; Copyright (c) 2012-2016 Sylvain Benner & Contributors +;; +;; Author: Sylvain Benner +;; URL: https://github.com/syl20bnr/spacemacs +;; +;; This file is not part of GNU Emacs. +;; +;;; License: GPLv3 +;; --------------------------------------------------------------------------- +;; evilified-state--find-new-event +;; --------------------------------------------------------------------------- + +(ert-deftest test-evilify-find-new-event--s-to-S () + (let ((input ?s)) + (should (equal ?S (evilified-state--find-new-event input))))) + +(ert-deftest test-evilify-find-new-event--S-to-C-s () + (let ((input ?S)) + (should (equal ?\C-s (evilified-state--find-new-event input))))) + +(ert-deftest test-evilify-find-new-event--C-s-to-C-S-s () + (let ((input ?\C-s) + (output (+ (expt 2 25) ?\C-s))) + (should (equal output (evilified-state--find-new-event input))))) + +(ert-deftest test-evilify-find-new-event--C-S-s-error-return-nil () + (let ((input (+ (expt 2 25) ?\C-s))) + (should (equal nil (evilified-state--find-new-event input))))) + +(ert-deftest test-evilify-find-new-event--Space-remap () + (let ((input 32)) + (should (equal ?' (evilified-state--find-new-event input))))) + +(ert-deftest test-evilify-find-new-event--/-remap () + (let ((input ?/)) + (should (equal ?\\ (evilified-state--find-new-event input))))) + +(ert-deftest test-evilify-find-new-event--:-remap () + (let ((input ?:)) + (should (equal ?| (evilified-state--find-new-event input))))) + +;; --------------------------------------------------------------------------- +;; evilified-state--sort-keymap +;; --------------------------------------------------------------------------- + +(ert-deftest test-evilify-sort-keymap-1 () + (let ((map '(keymap + (menu-bar keymap + (Menu menu-item "Title" + (keymap "Map" + (Action1 menu-item "Action1" action1) + (Action2 menu-item "Action2" action2)))) + (23 . func1) + (M-tab . func9) + (remap keymap (func1 . func4) (func2. func5) (func3 . func6)) + (s-tab . func8) + (24 keymap (52 keymap (97 . func2)) (97 . func3)) + (33 . func4) + (58 . func5) + (122 . func6) + (M-return . func7) + (C-tab . func10)))) + (should (equal '((122 . func6) + (58 . func5) + (33 . func4) + (24 keymap (52 keymap (97 . func2)) (97 . func3)) + (23 . func1) + (C-tab . func10) + (M-return . func7) + (M-tab . func9) + (menu-bar + keymap + (Menu menu-item "Title" + (keymap "Map" + (Action1 menu-item "Action1" action1) + (Action2 menu-item "Action2" action2)))) + (remap keymap (func1 . func4) (func2. func5) (func3 . func6)) + (s-tab . func8)) + (evilified-state--sort-keymap map))))) + + +(ert-deftest test-evilify-sort-keymap-2 () + (let ((map '(keymap + (s-tab . func8) + (23 . func1) + (122 . func6) + (remap keymap (func1 . func4) (func2. func5) (func3 . func6)) + (33 . func4) + (M-return . func7) + (menu-bar keymap + (Menu menu-item "Title" + (keymap "Map" + (Action1 menu-item "Action1" action1) + (Action2 menu-item "Action2" action2)))) + (58 . func5) + (M-tab . func9) + (24 keymap (52 keymap (97 . func2)) (97 . func3)) + (C-tab . func10)))) + (should (equal '((122 . func6) + (58 . func5) + (33 . func4) + (24 keymap (52 keymap (97 . func2)) (97 . func3)) + (23 . func1) + (C-tab . func10) + (M-return . func7) + (M-tab . func9) + (menu-bar + keymap + (Menu menu-item "Title" + (keymap "Map" + (Action1 menu-item "Action1" action1) + (Action2 menu-item "Action2" action2)))) + (remap keymap (func1 . func4) (func2. func5) (func3 . func6)) + (s-tab . func8)) + (evilified-state--sort-keymap map))))) diff --git a/tests/layers/+distribution/spacemacs/Makefile b/tests/layers/+distribution/spacemacs/Makefile new file mode 100644 index 0000000..6caf657 --- /dev/null +++ b/tests/layers/+distribution/spacemacs/Makefile @@ -0,0 +1,18 @@ +## Makefile --- Spacemacs Core +## +## Copyright (c) 2012-2016 Sylvain Benner & Contributors +## +## Author: Sylvain Benner +## URL: https://github.com/syl20bnr/spacemacs +## +## This file is not part of GNU Emacs. +## +## License: GPLv3 + +TEST_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) + +LOAD_FILES = init.el +UNIT_TEST_FILES = +FUNC_TEST_FILES = + +include ../../../../spacemacs.mk diff --git a/tests/layers/+distribution/spacemacs/dotspacemacs.el b/tests/layers/+distribution/spacemacs/dotspacemacs.el new file mode 100644 index 0000000..8cc9a7f --- /dev/null +++ b/tests/layers/+distribution/spacemacs/dotspacemacs.el @@ -0,0 +1,7 @@ +(defun dotspacemacs/layers () + (setq-default + dotspacemacs-distribution 'spacemacs)) +(defun dotspacemacs/init ()) +(defun dotspacemacs/user-init ()) +(defun dotspacemacs/config ()) +(defun dotspacemacs/user-config ())