ADD dependency management and conditional loading

This commit is contained in:
Nathan Dwarshuis 2020-08-15 13:00:04 -04:00
parent 4122f4784e
commit 213c8fea95
1 changed files with 165 additions and 116 deletions

View File

@ -162,10 +162,16 @@ OS is one of those in `system-type'."
`(when (not (eq system-type ,os)) (progn ,@body) `(when (not (eq system-type ,os)) (progn ,@body)
(print "Skipping OS-restricted code"))) (print "Skipping OS-restricted code")))
(defvar nd/required-exes '()
"Running list of executables required to run various configuations.")
(defmacro nd/when-bin (bin &rest body) (defmacro nd/when-bin (bin &rest body)
"Execute BODY if the program BIN exists." "Execute BODY if the program BIN exists."
(declare (indent 1)) (declare (indent 1))
`(if (executable-find ,bin) (progn ,@body) `(if (executable-find ,bin)
(progn
(setq nd/required-exes (-union '(,bin) nd/required-exes))
,@body)
(print (format "Executable %s not found. Skipping." ,bin)))) (print (format "Executable %s not found. Skipping." ,bin))))
(defmacro nd/time-exec (&rest body) (defmacro nd/time-exec (&rest body)
@ -262,6 +268,27 @@ If FRONT is t, do to the front of current values instead of the back."
(--each (--each
(where-is-internal f keymap nil nil) (where-is-internal f keymap nil nil)
(define-key keymap it nil))) (define-key keymap it nil)))
(defun nd/detect-package-manager ()
"Return the package manager being used on this OS."
(cond
;; for now only pacman...because arch is the best (TM)
((file-exists-p "/usr/bin/pacman")
'pacman)))
(defun nd/pacman-find-owner (file)
"Return the pacman packages that owns FILE.
Assumes pacman is installed and FILE is an absolute path."
(-some->> (format "pacman -Fq %s" file)
(shell-command-to-string)
(s-trim)
(s-split "\n")
(--map (replace-regexp-in-string ".*/" "" it t))
(cons file)))
(defun nd/detect-dependencies ()
"Return a list of required packages for this configuration."
(--map (nd/pacman-find-owner (format "/usr/bin/%s" it)) nd/required-exes))
#+END_SRC #+END_SRC
** interactive ** interactive
:PROPERTIES: :PROPERTIES:
@ -807,11 +834,12 @@ For me this means R but ess also supports S-plus, SAS, Stata, and other statisti
Flycheck syntax checkers Flycheck syntax checkers
- r-lintr (install from CRAN) - r-lintr (install from CRAN)
#+begin_src emacs-lisp #+begin_src emacs-lisp
(defun nd/init-ess-company () (nd/when-bin "R"
(defun nd/init-ess-company ()
"Set the company backends for ess modes." "Set the company backends for ess modes."
(setq-local company-backends '((company-R-objects company-R-args)))) (setq-local company-backends '((company-R-objects company-R-args))))
(use-package ess (use-package ess
:straight t :straight t
:init :init
(require 'ess-r-mode) (require 'ess-r-mode)
@ -832,35 +860,38 @@ Flycheck syntax checkers
ess-history-file "session.Rhistory" ess-history-file "session.Rhistory"
ess-history-directory (substitute-in-file-name "${XDG_CONFIG_HOME}/r/"))) ess-history-directory (substitute-in-file-name "${XDG_CONFIG_HOME}/r/")))
;; fast compile ;; fast compile
(defun nd/ess-r-add-env (orig-fun inf-buf proc-name start-args) (defun nd/ess-r-add-env (orig-fun inf-buf proc-name start-args)
(let ((process-environment (cons "MAKEFLAGS=-j8" process-environment))) (let ((process-environment (cons "MAKEFLAGS=-j8" process-environment)))
(funcall orig-fun inf-buf proc-name start-args))) (funcall orig-fun inf-buf proc-name start-args)))
(defun nd/ess-r-start-env (orig-fun &rest args) (defun nd/ess-r-start-env (orig-fun &rest args)
(nd/with-advice (nd/with-advice
((#'inferior-ess--start-process :around #'nd/ess-r-add-env)) ((#'inferior-ess--start-process :around #'nd/ess-r-add-env))
(apply orig-fun args))) (apply orig-fun args)))
(defun nd/ess-r-setwd-maybe (orig-fun &rest args) (advice-add #'run-ess-r :around #'nd/ess-r-start-env)
(nd/when-bin "docker"
(defun nd/ess-r-setwd-maybe (orig-fun &rest args)
(nd/with-advice (nd/with-advice
((#'ess-set-working-directory :override #'ignore)) ((#'ess-set-working-directory :override #'ignore))
(apply orig-fun args))) (apply orig-fun args)))
(advice-add #'run-ess-r :around #'nd/ess-r-start-env) (advice-add #'run-ess-r :around #'nd/ess-r-setwd-maybe)
(advice-add #'run-ess-r :around #'nd/ess-r-setwd-maybe) ;; force flycheck to use system R instead of whatever is in docker
(defun nd/flycheck-find-exe-no-docker (orig-fun exe)
;; force flycheck to use the system-wide R install instead of whatever
;; is in docker
(defun nd/flycheck-find-exe-no-docker (orig-fun exe)
(if (or (equal exe "R") (s-starts-with? "R " exe)) (if (or (equal exe "R") (s-starts-with? "R " exe))
"/bin/R" (funcall orig-fun exe))) "/bin/R" (funcall orig-fun exe)))
(advice-add #'flycheck-default-executable-find :around (advice-add #'flycheck-default-executable-find :around
#'nd/flycheck-find-exe-no-docker) #'nd/flycheck-find-exe-no-docker)))
#+END_SRC #+END_SRC
*** C *** C
:PROPERTIES:
:ID: 0ee09480-e722-4a06-af8f-52f7dbf3f906
:END:
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(defun nd/init-c-company () (defun nd/init-c-company ()
"Set the company backends for anaconda mode." "Set the company backends for anaconda mode."
@ -869,19 +900,21 @@ Flycheck syntax checkers
company-irony))) company-irony)))
;; requires clang (duh) ;; requires clang (duh)
(use-package flycheck-clang-analyzer (nd/when-bin "clang"
(use-package flycheck-clang-analyzer
:straight t :straight t
:after flycheck :after flycheck
:config :config
(flycheck-clang-analyzer-setup)) (flycheck-clang-analyzer-setup)))
;; requires cmake/llvm ;; requires cmake/llvm
(use-package irony (nd/when-bin "cmake"
(use-package irony
:straight t :straight t
:hook ((irony-mode . irony-cdb-autosetup-compile-options))) :hook ((irony-mode . irony-cdb-autosetup-compile-options)))
(use-package company-irony (use-package company-irony
:straight t) :straight t))
(use-package company-c-headers (use-package company-c-headers
:straight t) :straight t)
@ -948,8 +981,9 @@ Anaconda (not related to the Python/R distribution?) is much lighter and easier
:END: :END:
[[https://github.com/python/black][Black]] is a really nice syntax formatter. It must be externally installed to work. [[https://github.com/python/black][Black]] is a really nice syntax formatter. It must be externally installed to work.
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package blacken (nd/when-bin "black"
:straight t) (use-package blacken
:straight t))
#+END_SRC #+END_SRC
**** pyenv **** pyenv
:PROPERTIES: :PROPERTIES:
@ -959,16 +993,17 @@ For isolation I use [[https://github.com/pyenv/pyenv][pyenv]] and [[https://gith
Note this also requires all external packages to be installed in each environement (eg ipython, black, flake8, and pylint). Note this also requires all external packages to be installed in each environement (eg ipython, black, flake8, and pylint).
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package pyenv-mode (nd/when-bin "pyenv"
(use-package pyenv-mode
:straight t :straight t
:after python :after python
:init (-some--> (getenv "PYENV_ROOT") :init (-some--> (getenv "PYENV_ROOT")
(f-join it "versions") (f-join it "versions")
(add-to-list 'exec-path it))) (add-to-list 'exec-path it)))
;; resolve symlinks when setting the pyenv, otherwise we get some ;; resolve symlinks when setting the pyenv, otherwise we get some
;; strange errors when activating a symlinked env ;; strange errors when activating a symlinked env
(advice-add #'pyenv-mode-full-path :filter-return #'file-truename) (advice-add #'pyenv-mode-full-path :filter-return #'file-truename))
#+END_SRC #+END_SRC
*** Ruby *** Ruby
:PROPERTIES: :PROPERTIES:
@ -1007,19 +1042,20 @@ Since most of these need GHCi to run properly, I added a hook to load haskell so
I have also found this to be much simpler and conflicting with other packages such as =dante= and =intero= (and probably =haskell-ide-engine= and friends). I have also found this to be much simpler and conflicting with other packages such as =dante= and =intero= (and probably =haskell-ide-engine= and friends).
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(defun nd/init-haskell-company () (nd/when-bin "stack"
(defun nd/init-haskell-company ()
"Set the company backends for haskell mode." "Set the company backends for haskell mode."
(setq-local company-backends (setq-local company-backends
;; capf is standard completion and dabbrev provides ;; capf is standard completion and dabbrev provides
;; local completions in 'where' and 'let' clauses ;; local completions in 'where' and 'let' clauses
'((company-capf company-dabbrev)))) '((company-capf company-dabbrev))))
(defun nd/haskell-load-maybe () (defun nd/haskell-load-maybe ()
"Prompts user to load haskell source to GHCi." "Prompts user to load haskell source to GHCi."
(when (y-or-n-p "Load Haskell source into GHCi? ") (when (y-or-n-p "Load Haskell source into GHCi? ")
(haskell-process-load-or-reload))) (haskell-process-load-or-reload)))
(use-package haskell-mode (use-package haskell-mode
:straight t :straight t
:hook ((haskell-mode . origami-mode) :hook ((haskell-mode . origami-mode)
(haskell-mode . company-mode) (haskell-mode . company-mode)
@ -1045,11 +1081,11 @@ I have also found this to be much simpler and conflicting with other packages su
;; use TAGS file (requires hasktags binary to be in $PATH) ;; use TAGS file (requires hasktags binary to be in $PATH)
haskell-tags-on-save t)) haskell-tags-on-save t))
;; this minor mode name is long and unnecessary ;; this minor mode name is long and unnecessary
(delight 'interactive-haskell-mode nil "haskell") (delight 'interactive-haskell-mode nil "haskell")
;; unnecessary to see on the modeline ;; unnecessary to see on the modeline
(delight 'subword-mode nil "subword") (delight 'subword-mode nil "subword"))
#+END_SRC #+END_SRC
**** hlint **** hlint
:PROPERTIES: :PROPERTIES:
@ -1057,8 +1093,9 @@ I have also found this to be much simpler and conflicting with other packages su
:END: :END:
This is an additional syntax checker and requires the =hlint= binary (install through stack). This is an additional syntax checker and requires the =hlint= binary (install through stack).
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(with-eval-after-load 'haskell (nd/when-bin "hlint"
(flycheck-add-next-checker 'haskell-stack-ghc '(t . haskell-hlint))) (with-eval-after-load 'haskell
(flycheck-add-next-checker 'haskell-stack-ghc '(t . haskell-hlint))))
#+END_SRC #+END_SRC
**** helper functions **** helper functions
:PROPERTIES: :PROPERTIES:
@ -1081,8 +1118,9 @@ Other helper functions that make haskell even more fun.
:END: :END:
For flycheck, install =luacheck= (from AUR on Arch). For flycheck, install =luacheck= (from AUR on Arch).
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package lua-mode (nd/when-bin "luacheck"
:straight t) (use-package lua-mode
:straight t))
#+END_SRC #+END_SRC
*** TeX *** TeX
**** AUCTeX **** AUCTeX
@ -1245,6 +1283,9 @@ Overlays hex color codes with matching colors in certain modes like css and html
:straight t) :straight t)
#+END_SRC #+END_SRC
*** Jinja2 *** Jinja2
:PROPERTIES:
:ID: a38b0792-46fe-43cc-b57a-d8e3a189fdc5
:END:
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package jinja2-mode (use-package jinja2-mode
:straight t :straight t
@ -1365,11 +1406,15 @@ No custom code here, but flycheck needs =sqlint= (on Arch available through the
:ID: ce24b075-ede6-4d6c-81db-4c6aa40e4fd0 :ID: ce24b075-ede6-4d6c-81db-4c6aa40e4fd0
:END: :END:
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package dockerfile-mode (nd/when-bin "docker"
:straight t) (use-package dockerfile-mode
:straight t))
#+END_SRC #+END_SRC
** testing ** testing
*** buttercup *** buttercup
:PROPERTIES:
:ID: 9539395e-98aa-4e47-b2ff-4233b63d40b1
:END:
Include this so I can have the docs and indentation specs handy when writing test suites Include this so I can have the docs and indentation specs handy when writing test suites
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package buttercup (use-package buttercup
@ -3380,12 +3425,13 @@ For some reason there is no default way to get a "print prompt." Instead one nee
:ID: 67e11402-a9e5-4aae-8644-0e2c4f9ad2bc :ID: 67e11402-a9e5-4aae-8644-0e2c4f9ad2bc
:END: :END:
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
(use-package magit (nd/when-bin "git"
(use-package magit
:straight t :straight t
:config :config
:delight auto-revert-mode :delight auto-revert-mode
(setq magit-push-always-verify nil (setq magit-push-always-verify nil
git-commit-summary-max-length 50)) git-commit-summary-max-length 50)))
#+END_SRC #+END_SRC
** dired ** dired
*** no confirm *** no confirm
@ -4615,6 +4661,9 @@ The function keys are nice because they are almost (not always) free in every mo
("=" #'balance-windows :exit t)) ("=" #'balance-windows :exit t))
#+END_SRC #+END_SRC
*** other *** other
:PROPERTIES:
:ID: dff1f586-7231-4394-8f4c-2730dbe8a901
:END:
#+BEGIN_SRC emacs-lisp #+BEGIN_SRC emacs-lisp
;; exchange point and marker (I never saw the use for this) ;; exchange point and marker (I never saw the use for this)
(global-unset-key (kbd "C-x C-x")) (global-unset-key (kbd "C-x C-x"))