git.fiddlerwoaroof.com
Raw Blame History
;;; utils -- Summary
;;; Commentary:

(require 'cl)

;;; Code:

(defun fwoar:read-sexps-in-buffer (buffer)
  (with-temp-buffer
    (save-excursion
      (insert "(")
      (insert-buffer buffer)
      (goto-char (point-max))
      (insert "\n)"))
    (read (current-buffer))))

(defun fwoar:read-sexps-in-file (fn)
  (with-temp-buffer
    (save-excursion
      (insert "(")
      (insert-file fn)
      (goto-char (point-max))
      (insert "\n)"))
    (read (current-buffer))))

(defun fwoar:read-strings-in-file (fn)
  (with-temp-buffer
    (insert-file fn)
    (mark-whole-buffer)
    (flush-lines "^[[:space:]]*$")
    (goto-char (point-min))
    (remove "" (s-lines (buffer-string)))))

(defun fwoar::op--collect-args (body)
  (cl-flet ((walker (body &optional args)
              (if (null body)
                  args
                (if (symbolp body)
                    (when (eql ?\_ (elt (symbol-name body) 0))
                      (cons body args))
                  (if (listp body)
                      (append (fwoar::op--collect-args (car body))
                              (fwoar::op--collect-args (cdr body))
                              ))))))
    (sort (walker body)
          (lambda (a b)
            (< (string-to-number (subseq (symbol-name a) 1))
               (string-to-number (subseq (symbol-name b) 1)))))))

(defmacro fwoar:op (&rest body)
  `(lambda ,(fwoar::op--collect-args body)
     ,@body))

(defun fwoar:blank-line-p ()
  (= (current-indentation)
     (- (line-end-position)
        (line-beginning-position))))

(defun fwoar:helm-generate-lisp-skeleton ()
  (interactive)
  (let ((skeletons '(("defunction" . skel-defun)
                     ("defmacro" . skel-defmacro)
                     ("defsystem" . skel-defsystem)
                     ("defpackage" . skel-defpackage)
                     ("defparameter" . skel-defparameter)
                     ("defvar" . skel-defvar))))
    (funcall (helm-comp-read "code template: " skeletons))
    (evil-insert 1)))

(defun fwoar:create-system-files ()
  (interactive)
  (save-excursion
    (mark-defun)
    (mapcar (lambda (it) (save-buffer (find-file (format "%s.lisp" (cadr it)))))
            (getf (cddar (read-from-string
                          (buffer-substring (point)
                                            (mark))))
                  :components)))
  (pop-mark))

(defmacro comment (&rest _))

(comment
 (defun paredit-wiggle-back ()
   (paredit-forward)
   (paredit-backward))

 (defmacro defparedit-wrapper (name invoked-wrapper)
   `(defun ,name ()
      (interactive)
      (paredit-wiggle-back)
      (,invoked-wrapper))))

(defun set-exec-path-from-shell-PATH ()
  "Set up Emacs' `exec-path' and PATH environment variable to match
  that used by the user's shell.

  This is particularly useful under Mac OSX, where GUI apps are not
  started from a shell."
  (interactive)
  (let ((path-from-shell
         (replace-regexp-in-string
          "[ \t\n]*$" ""
          (shell-command-to-string
           (concat "zsh -c '"
                   "  source ~/.zsh.d/dependencies/utils.zsh;"
                   "  source ~/.zsh.d/dependencies/path-setup.zsh;"
                   "  echo $PATH"
                   "'")))))
    (setenv "PATH" path-from-shell)
    (setq exec-path (split-string path-from-shell path-separator))))

(defmacro ensure-use-packages (&rest packages)
  (list* 'progn
         (mapcar (lambda (pck)
                   `(use-package ,(car pck)
                      :ensure t
                      ,@(cdr pck)))
                 packages)))

(defmacro fwoar/defvaralias! (var val-var)
  `(progn
     (setq ,var ,val-var)
     (defvaralias ',var ',val-var)))

(defun setup-indentation ()
  (setq-default indent-tabs-mode nil
                tab-width 2)
  (fwoar/defvaralias! c-basic-offset tab-width)
  (fwoar/defvaralias! sh-basic-offset tab-width)
  (fwoar/defvaralias! js2-basic-offset tab-width)
  (fwoar/defvaralias! sgml-basic-offset tab-width)
  (fwoar/defvaralias! cperl-indent-level tab-width)
  nil)

(defun start-server ()
  (unless (fboundp 'server-running-p)
    (require 'server))
  (let ((server-name (if fwoar::*is-ordinary*
                         server-name
                       "notes")))
    (unless (server-running-p)
      (server-start))))

(defun fwoar:force-info-init ()
  (interactive)
  (setf Info-directory-list nil)
  (info-initialize))

(defun post-init ()
  ;;(centaur-tabs-mode 1)
  (evil-mode 1)

  (setup-indentation)
  (start-server)

  (if (version<= "26.0.50" emacs-version)
      (global-display-line-numbers-mode)
    (setq linum-format "%5d\u2502")
    (global-linum-mode))

  (fwoar:force-info-init)

  (cl-loop
   with infopath = (prog1  (getenv "INFOPATH")
                     (message "infopath: %s" (getenv "INFOPATH")))
   for old-pos = nil then pos
   for pos = (cl-position ?: infopath :from-end t)
   then (cl-position ?: infopath :from-end t :end pos)
   for path = (cl-subseq infopath (if pos (1+ pos) 0)) then (cl-subseq infopath (if pos (1+ pos) 0) old-pos)
   do (cl-adjoin path Info-directory-list :test 'equal)
   while pos)

  (eval-after-load 'with-editor
    (progn
      (setenv "EDITOR" with-editor-emacsclient-executable)
      (setenv "VISUAL" with-editor-emacsclient-executable)))

  ;; NOTE: this must be here...
  (global-company-mode 1))

(defvar fwoar::*is-ordinary*
  (not (string= invocation-name "EmacsNotes")))

(defun fwoar/source (filename pattern)
  "Update environment variables from a shell source file."
  (interactive "fSource file: ")

  (message "Sourcing environment from `%s'..." filename)
  (with-temp-buffer
    (shell-command (format "diff -u <(true; export) <(source %s; export)" filename) '(4))

    (let ((envvar-re "\\([^=[:space:]]+\\)=\\(.*\\)$"))
      ;; Remove environment variables
      (while (search-forward-regexp (concat "^-" envvar-re) nil t)
        (let ((var (match-string 1)))
          (when (s-match pattern var)
            (message "%s" (prin1-to-string `(setenv ,var nil)))
            (setenv var nil))))

      ;; Update environment variables
      (goto-char (point-min))
      (while (search-forward-regexp (concat "^+" envvar-re) nil t)
        (let ((var (match-string 1))
              (value (string-trim (match-string 2) "'" "'")))
          (when (s-match pattern var)
            (message "%s" (prin1-to-string `(setenv ,var ,value)))
            (setenv var value))))))
  (message "Sourcing environment from `%s'... done." filename))

(defun cold-boot ()
  ""
  (fwoar/source "~/.zshrc" ".*PATH")
  (set-exec-path-from-shell-PATH)
  (run-with-idle-timer 5 t 'garbage-collect)
  ;; (setq fwoar::*is-ordinary* (not (string= invocation-name "EmacsNotes")))
  (add-hook 'after-init-hook 'post-init)
  (electric-indent-mode -1)
  (comment
   (electric-pair-mode -1))
  (add-hook 'before-save-hook 'delete-trailing-whitespace)

  (when-let ((ls-executable (executable-find "gls")))
    (setq insert-directory-program ls-executable))

  (setq default-directory "~/emacs-home/")
  (make-directory default-directory t)

  (setq vc-follow-symlinks t)

  (setq browse-url-browser-function 'browse-url-default-browser
        history-delete-duplicates t)

  (require 'use-package))

(defun raise-iterm ()
  (interactive)
  (shell-command "open -a iTerm.app"))
(define-key global-map (kbd "C-M-s-l") 'raise-iterm)

(defun fwoar:hm-edit ()
  (interactive)
  (with-editor-shell-command "(home-manager edit && hm-switch) &"))