Reorganize files to use stow for installation #dotfiles

This commit is contained in:
Colin Powell
2019-01-10 10:19:27 -05:00
parent cbbffe7f60
commit eaa394e556
123 changed files with 2227 additions and 131 deletions

3
.gitignore vendored
View File

@ -1,3 +1,4 @@
doom
spacemacs
config/fish/functions/fish_prompt.fish
emacs/.config/doom/+org-gcal-sync.el

View File

@ -1,30 +0,0 @@
package ansible
package aws
package config
package direnv
package fasd
package git-flow
package osx
package pbcopy
package pyenv
package python
package spark
package thefuck
package tmux-zen
package vcs
package weather
package words
theme chain
theme dangerous
theme default
theme eclm
theme fishbone
theme gnuykeaj
theme l
theme mars
theme nai
theme pastfish
theme shellder
theme sushi
theme syl20bnr
theme toaster

View File

@ -1 +0,0 @@
stable

View File

@ -1 +0,0 @@
shellder

View File

@ -1 +0,0 @@
34da4a18e8fdacda2ce10061f1cd6340

View File

@ -1 +0,0 @@
30

View File

@ -1 +0,0 @@
default

482
emacs/.config/doom/+mail.el Normal file
View File

@ -0,0 +1,482 @@
;;; -*- lexical-binding: t; -*-
;;; Config is mostly from https://kkatsuyuki.github.io/notmuch-conf/ aadsa
;;; This is all modified from
;;; https://github.com/fuxialexander/doom-emacs-private-xfu/
;;;; Notmuch
(def-package! notmuch
:commands (notmuch
notmuch-tree
notmuch-tree-mode
notmuch-search
notmuch-search-mode
notmuch-hello
notmuch-hello-mode
notmuch-show
notmuch-show-mode
notmuch-message-mode)
:init
(map!
(:leader
(:prefix "o"
(:desc "APP: Email" "e" #'=mail))))
:config
(setq notmuch-fcc-dirs nil
notmuch-show-logo nil
notmuch-message-headers-visible nil
message-kill-buffer-on-exit t
message-send-mail-function 'message-send-mail-with-sendmail
notmuch-search-oldest-first nil
send-mail-function 'sendmail-send-it
;; sendmail-program "/usr/local/bin/msmtp"
notmuch-search-result-format '(("date" . "%12s ")
("count" . "%-7s ")
("authors" . "%-30s ")
("subject" . "%-100s ")
("tags" . "(%s)"))
notmuch-tag-formats '(("unread"
(propertize tag 'face 'notmuch-tag-unread)))
notmuch-hello-sections '(notmuch-hello-insert-saved-searches
notmuch-hello-insert-alltags)
notmuch-saved-searches '(
(:name "inbox" :query "tag:inbox not tag:trash" :key "i")
(:name "sent" :query "tag:sent" :key "s")
(:name "archived":query "tag:archived" :key "a")
(:name "drafts" :query "tag:draft" :key "d"))
notmuch-archive-tags '("-inbox" "-unread" "+archived"))
(set-evil-initial-state! '(notmuch-hello-mode
notmuch-show-mode
notmuch-search-mode
notmuch-tree-mode
notmuch-message-mode) 'normal)
;; (add-hook 'notmuch-tree-mode-hook '+mail/buffer-face-mode-notmuch)
;; (add-hook 'notmuch-search-mode-hook '+mail/buffer-face-mode-notmuch)
;; (add-hook 'notmuch-message-mode-hook '+mail/buffer-face-mode-notmuch)
(add-hook 'notmuch-message-mode-hook (lambda () (set (make-local-variable 'company-backends) '(notmuch-company (company-ispell :with company-yasnippet)))))
(add-hook 'notmuch-tree-mode-hook (lambda () (setq-local line-spacing nil)))
(remove-hook 'message-mode-hook #'turn-on-auto-fill)
(remove-hook 'notmuch-message-mode-hook #'turn-on-auto-fill)
(push 'notmuch-tree-mode evil-snipe-disabled-modes)
(push 'notmuch-hello-mode evil-snipe-disabled-modes)
(push 'notmuch-search-mode evil-snipe-disabled-modes)
(push 'notmuch-show-mode evil-snipe-disabled-modes)
(advice-add #'notmuch-start-notmuch-sentinel :override #'+mail/notmuch-start-notmuch-sentinel)
(advice-add #'notmuch-show :override #'+mail/notmuch-show-reuse-buffer)
(advice-add #'notmuch-hello-insert-searches :override #'+mail/notmuch-hello-insert-searches)
(advice-add #'notmuch-hello-insert-saved-searches :override #'+mail/notmuch-hello-insert-saved-searches)
(advice-add #'notmuch-hello-insert-buttons :override #'+mail/notmuch-hello-insert-buttons)
;; (set! :popup "\\*notmuch-hello\\*" '((size . 20) (side . left)) '((quit . t) (modeline . nil)))
(set-popup-rule! "\\*offlineimap\\*" :side 'bottom :size 0.4 :quit t)
(push (lambda (buf) (string-match-p "^\\*notmuch" (buffer-name buf)))
doom-real-buffer-functions)
(map! (:after notmuch
(:map notmuch-show-mode-map
:nmv "o" #'ace-link-notmuch-show
:nmv "i" #'+mail/open-message-with-mail-app-notmuch-show
:nmv "I" #'notmuch-show-view-all-mime-parts
:nmv "q" #'notmuch-bury-or-kill-this-buffer
(:when (featurep! :completion ivy)
:nmv "s" #'counsel-notmuch)
(:when (featurep! :completion helm)
:nmv "s" #'helm-notmuch)
:nmv "t" #'notmuch-tree-from-show-current-query
:nmv "N" #'notmuch-mua-new-mail
:nmv "n" #'notmuch-show-next-thread-show
:nmv "r" #'notmuch-show-reply
:nmv "<tab>" #'notmuch-show-toggle-visibility-headers
:nmv "R" #'notmuch-show-reply-sender
:nmv "p" #'notmuch-show-previous-thread-show)
(:map notmuch-hello-mode-map
:nmv "o" #'ace-link-notmuch-hello
:nmv "t" #'notmuch-tree
:nmv "k" #'widget-backward
:nmv "n" #'notmuch-mua-new-mail
:nmv "N" #'notmuch-mua-new-mail
:nmv "j" #'widget-forward
(:when (featurep! :completion ivy)
:nmv "s" #'counsel-notmuch)
(:when (featurep! :completion helm)
:nmv "s" #'helm-notmuch)
:nmv "q" #'+mail/quit
:nmv "r" #'notmuch-hello-update)
(:map notmuch-search-mode-map
:nmv "j" #'notmuch-search-next-thread
:nmv "k" #'notmuch-search-previous-thread
:nmv "t" #'notmuch-tree-from-search-thread
;; :nmv "RET" #'notmuch-tree-from-search-thread
:nmv "RET" #'notmuch-search-show-thread
:nmv "N" #'notmuch-mua-new-mail
:nmv "T" #'notmuch-tree-from-search-current-query
:nmv ";" #'notmuch-search-tag
:nmv "," #'notmuch-jump-search
:nmv "d" #'+mail/notmuch-search-delete
:nmv "a" #'notmuch-search-archive-thread
;; :nmv "q" #'notmuch
:nmv "q" #'+mail/quit
:nmv "R" #'notmuch-search-reply-to-thread-sender
:nmv "r" #'notmuch-search-reply-to-thread
:nmv "go" #'+notmuch-exec-offlineimap
(:when (featurep! :completion ivy)
:nmv "s" #'counsel-notmuch)
(:when (featurep! :completion helm)
:nmv "s" #'helm-notmuch)
:nmv "x" #'+mail/notmuch-search-spam)
(:map notmuch-tree-mode-map
:nmv "j" #'notmuch-tree-next-message
:nmv "k" #'notmuch-tree-prev-message
:nmv "S" #'notmuch-search-from-tree-current-query
(:when (featurep! :completion ivy)
:nmv "s" #'counsel-notmuch)
(:when (featurep! :completion helm)
:nmv "s" #'helm-notmuch)
:nmv "t" #'notmuch-tree
:nmv ";" #'notmuch-tree-tag
:nmv "RET" #'notmuch-tree-show-message
:nmv "q" #'notmuch-tree-quit
:nmv "s-n" #'notmuch-mua-new-mail
:nmv "r" #'notmuch-search-reply-to-thread-sender
:nmv "a" #'notmuch-tree-archive-message-then-next
:nmv "A" #'notmuch-tree-archive-thread
:nmv "i" #'+mail/open-message-with-mail-app-notmuch-tree
:nmv "d" #'+mail/notmuch-tree-delete
:nmv "x" #'+mail/notmuch-tree-spam)
(:map notmuch-message-mode-map
:localleader
:desc "Send and Exit" doom-localleader-key #'notmuch-mua-send-and-exit
:desc "Kill Message Buffer" "k" #'notmuch-mua-kill-buffer
:desc "Save as Draft" "s" #'message-dont-send
:desc "Attach file" "f" #'mml-attach-file))))
; Use w3m to parse HTML email
(setq mm-text-html-renderer 'w3m)
(setq w3m-fill-column 72)
;;;; counsel-notmuch
(when (featurep! :completion ivy)
(def-package! counsel-notmuch
:commands counsel-notmuch
:after notmuch))
;;;; helm-notmuch
(when (featurep! :completion helm)
(def-package! helm-notmuch
:commands helm-notmuch
:after notmuch))
;;;; org-mime
(def-package! org-mime
:after (org notmuch))
:config (setq org-mime-library 'mml)
;;;###autoload
(defun =mail ()
"Activate (or switch to) `notmuch' in its workspace."
(interactive)
(if-let* ((buf (cl-find-if (lambda (it) (string-match-p "^\\*notmuch" (buffer-name (window-buffer it))))
(doom-visible-windows))))
(select-window (get-buffer-window buf))
(notmuch-search "tag:inbox")))
;; (call-interactively 'notmuch-hello-sidebar)
;;;###autoload
(defun +mail/quit ()
(interactive)
;; (+popup/close (get-buffer-window "*notmuch-hello*"))
(doom-kill-matching-buffers "^\\*notmuch"))
;;;###autoload
(defun +mail/notmuch-search-delete ()
(interactive)
(notmuch-search-add-tag
(list "+trash" "-inbox" "-unread"))
(notmuch-search-next-thread))
;;;###autoload
(defun +mail/notmuch-tree-delete ()
(interactive)
(notmuch-tree-add-tag
(list "+trash" "-inbox" "-unread"))
(notmuch-tree-next-message))
;;;###autoload
(defun +mail/notmuch-search-spam ()
(interactive)
(notmuch-search-add-tag
(list "+spam" "-inbox" "-unread"))
(notmuch-search-next-thread))
;;;###autoload
(defun +mail/notmuch-tree-spam ()
(interactive)
(notmuch-tree-add-tag
(list "+spam" "-inbox" "-unread"))
(notmuch-tree-next-message))
;;;###autoload
(defun +mail/open-message-with-mail-app-notmuch-tree ()
(interactive)
(let* ((msg-path (car (plist-get (notmuch-tree-get-message-properties) :filename)))
(temp (make-temp-file "notmuch-message-" nil ".eml")))
(shell-command-to-string (format "cp '%s' '%s'" msg-path temp))
(start-process-shell-command "email" nil (format "thunderbird '%s'" temp))))
;; Override
;;;###autoload
(defun +mail/notmuch-start-notmuch-sentinel (proc event)
"Process sentinel function used by `notmuch-start-notmuch'."
(let* ((err-file (process-get proc 'err-file))
(err-buffer (or (process-get proc 'err-buffer)
(find-file-noselect err-file)))
(err (when (not (zerop (buffer-size err-buffer)))
(with-current-buffer err-buffer (buffer-string))))
(sub-sentinel (process-get proc 'sub-sentinel))
(real-command (process-get proc 'real-command)))
(condition-case err
(progn
;; Invoke the sub-sentinel, if any
(when sub-sentinel
(funcall sub-sentinel proc event))
;; Check the exit status. This will signal an error if the
;; exit status is non-zero. Don't do this if the process
;; buffer is dead since that means Emacs killed the process
;; and there's no point in telling the user that (but we
;; still check for and report stderr output below).
(when (buffer-live-p (process-buffer proc))
(notmuch-check-async-exit-status proc event real-command err))
;; If that didn't signal an error, then any error output was
;; really warning output. Show warnings, if any.
(let ((warnings
(when err
(with-current-buffer err-buffer
(goto-char (point-min))
(end-of-line)
;; Show first line; stuff remaining lines in the
;; errors buffer.
(let ((l1 (buffer-substring (point-min) (point))))
(skip-chars-forward "\n")
(cons l1 (unless (eobp)
(buffer-substring (point) (point-max)))))))))
(when warnings
(notmuch-logged-error (car warnings) (cdr warnings)))))
(error
;; Emacs behaves strangely if an error escapes from a sentinel,
;; so turn errors into messages.
(message "%s" (error-message-string err))))
(when err-buffer
(set-process-query-on-exit-flag (get-buffer-process err-buffer) nil)
(kill-buffer err-buffer))
(when err-file (ignore-errors (delete-file err-file)))))
;;;###autoload
(defun +mail/notmuch-show-reuse-buffer (thread-id &optional elide-toggle parent-buffer query-context buffer-name)
"Run \"notmuch show\" with the given thread ID and display results.
ELIDE-TOGGLE, if non-nil, inverts the default elide behavior.
The optional PARENT-BUFFER is the notmuch-search buffer from
which this notmuch-show command was executed, (so that the
next thread from that buffer can be show when done with this
one).
The optional QUERY-CONTEXT is a notmuch search term. Only
messages from the thread matching this search term are shown if
non-nil.
The optional BUFFER-NAME provides the name of the buffer in
which the message thread is shown. If it is nil (which occurs
when the command is called interactively) the argument to the
function is used.
Returns the buffer containing the messages, or NIL if no messages
matched."
(interactive "sNotmuch show: \nP")
(let ((buffer-name (generate-new-buffer-name
(or (concat "*notmuch-" buffer-name "*")
(concat "*notmuch-" thread-id "*"))))
;; We override mm-inline-override-types to stop application/*
;; parts from being displayed unless the user has customized
;; it themselves.
(mm-inline-override-types
(if (equal mm-inline-override-types
(eval (car (get 'mm-inline-override-types 'standard-value))))
(cons "application/*" mm-inline-override-types)
mm-inline-override-types)))
(switch-to-buffer (get-buffer-create buffer-name))
;; No need to track undo information for this buffer.
(setq buffer-undo-list t)
(notmuch-show-mode)
;; Set various buffer local variables to their appropriate initial
;; state. Do this after enabling `notmuch-show-mode' so that they
;; aren't wiped out.
(setq notmuch-show-thread-id thread-id
notmuch-show-parent-buffer parent-buffer
notmuch-show-query-context (if (or (string= query-context "")
(string= query-context "*"))
nil query-context)
notmuch-show-process-crypto notmuch-crypto-process-mime
;; If `elide-toggle', invert the default value.
notmuch-show-elide-non-matching-messages
(if elide-toggle
(not notmuch-show-only-matching-messages)
notmuch-show-only-matching-messages))
(add-hook 'post-command-hook #'notmuch-show-command-hook nil t)
(jit-lock-register #'notmuch-show-buttonise-links)
(notmuch-tag-clear-cache)
(let ((inhibit-read-only t))
(if (notmuch-show--build-buffer)
;; Messages were inserted into the buffer.
(current-buffer)
;; No messages were inserted - presumably none matched the
;; query.
(kill-buffer (current-buffer))
(ding)
(message "No messages matched the query!")
nil))))
;;;###autoload
(defun +mail/notmuch-hello-insert-searches (title query-list &rest options)
"Insert a section with TITLE showing a list of buttons made from QUERY-LIST.
QUERY-LIST should ideally be a plist but for backwards
compatibility other forms are also accepted (see
`notmuch-saved-searches' for details). The plist should
contain keys :name and :query; if :count-query is also present
then it specifies an alternate query to be used to generate the
count for the associated search.
Supports the following entries in OPTIONS as a plist:
:initially-hidden - if non-nil, section will be hidden on startup
:show-empty-searches - show buttons with no matching messages
:hide-if-empty - hide if no buttons would be shown
(only makes sense without :show-empty-searches)
:filter - This can be a function that takes the search query as its argument and
returns a filter to be used in conjuction with the query for that search or nil
to hide the element. This can also be a string that is used as a combined with
each query using \"and\".
:filter-count - Separate filter to generate the count displayed each search. Accepts
the same values as :filter. If :filter and :filter-count are specified, this
will be used instead of :filter, not in conjunction with it."
(widget-insert (propertize title 'face 'org-agenda-structure))
(if (and notmuch-hello-first-run (plist-get options :initially-hidden))
(add-to-list 'notmuch-hello-hidden-sections title))
(let ((is-hidden (member title notmuch-hello-hidden-sections))
(widget-push-button-prefix "")
(widget-push-button-suffix "")
(start (point)))
(if is-hidden
(widget-create 'push-button
:notify `(lambda (widget &rest ignore)
(setq notmuch-hello-hidden-sections
(delete ,title notmuch-hello-hidden-sections))
(notmuch-hello-update))
(propertize " +" 'face 'org-agenda-structure))
(widget-create 'push-button
:notify `(lambda (widget &rest ignore)
(add-to-list 'notmuch-hello-hidden-sections
,title)
(notmuch-hello-update))
" -"))
(widget-insert "\n")
(when (not is-hidden)
(let ((searches (apply 'notmuch-hello-query-counts query-list options)))
(when (or (not (plist-get options :hide-if-empty))
searches)
(widget-insert "\n")
(notmuch-hello-insert-buttons searches)
(indent-rigidly start (point) notmuch-hello-indent))))))
;;;###autoload
(defun +mail/notmuch-hello-insert-saved-searches ()
"Insert the saved-searches section."
(let ((searches (notmuch-hello-query-counts
(if notmuch-saved-search-sort-function
(funcall notmuch-saved-search-sort-function
notmuch-saved-searches)
notmuch-saved-searches)
:show-empty-searches notmuch-show-empty-saved-searches)))
(when searches
(widget-insert (propertize "Notmuch" 'face 'org-agenda-date-today))
(widget-insert "\n\n")
(widget-insert (propertize "Saved searches" 'face 'org-agenda-structure))
(widget-insert "\n\n")
(let ((start (point)))
(notmuch-hello-insert-buttons searches)
(indent-rigidly start (point) notmuch-hello-indent)))))
;;;###autoload
(defun +mail/notmuch-hello-insert-buttons (searches)
"Insert buttons for SEARCHES.
SEARCHES must be a list of plists each of which should contain at
least the properties :name NAME :query QUERY and :count COUNT,
where QUERY is the query to start when the button for the
corresponding entry is activated, and COUNT should be the number
of messages matching the query. Such a plist can be computed
with `notmuch-hello-query-counts'."
(let* ((widest (notmuch-hello-longest-label searches))
(tags-and-width (notmuch-hello-tags-per-line widest))
(tags-per-line (car tags-and-width))
(column-width (cdr tags-and-width))
(column-indent 0)
(count 0)
(reordered-list (notmuch-hello-reflect searches tags-per-line))
;; Hack the display of the buttons used.
(widget-push-button-prefix "")
(widget-push-button-suffix ""))
;; dme: It feels as though there should be a better way to
;; implement this loop than using an incrementing counter.
(mapc (lambda (elem)
;; (not elem) indicates an empty slot in the matrix.
(when elem
(if (> column-indent 0)
(widget-insert (make-string column-indent ? )))
(let* ((name (plist-get elem :name))
(query (plist-get elem :query))
(oldest-first (case (plist-get elem :sort-order)
(newest-first nil)
(oldest-first t)
(otherwise notmuch-search-oldest-first)))
(search-type (eq (plist-get elem :search-type) 'tree))
(msg-count (plist-get elem :count)))
(widget-insert (format "\n%5s "
(notmuch-hello-nice-number msg-count)))
(widget-create 'push-button
:notify #'notmuch-hello-widget-search
:notmuch-search-terms query
:notmuch-search-oldest-first oldest-first
:notmuch-search-type search-type
name)
(setq column-indent
(1+ (max 0 (- column-width (length name)))))))
(setq count (1+ count))
(when (eq (% count tags-per-line) 0)
(setq column-indent 0)
(widget-insert "\n")))
reordered-list)
;; If the last line was not full (and hence did not include a
;; carriage return), insert one now.
(unless (eq (% count tags-per-line) 0)
(widget-insert "\n"))))
(defun +notmuch-exec-offlineimap ()
"Execute offlineimap"
(interactive)
(set-process-sentinel
(start-process-shell-command "offlineimap"
"*offlineimap*"
"offlineimap -o")
'(lambda (process event)
(notmuch-refresh-all-buffers)
(message "Done!"))))
; Kill email message buffers when you close them
(setq message-kill-buffer-on-exit t)
(setq message-default-mail-headers "Cc: \nBcc: \n")
(setq message-auto-save-directory "~/Mail/colin@onec.me/Drafts/")
(setq message-directory "~/Mail/colin@onec.me/")

View File

@ -0,0 +1,14 @@
;;; -*- lexical-binding: t; -*-
;;;
(defvar counsel-spotify-client-id "515f0ff545a349bcadf98efab945972f")
(defvar counsel-spotify-client-secret "7618bf445df14b568782b13e37cf63e6")
(map!
(:leader
(:desc "applications" :prefix "a"
(:desc "music" :prefix "m"
:desc "Play/Pause Music" "m" #'counsel-spotify-toggle-play-pause
:desc "Next song" "n" #'counsel-spotify-plus-next
:desc "Search songs" "s" #'counsel-spotify-search-track
:desc "Search albums" "a" #'counsel-spotify-search-album))))

View File

@ -0,0 +1,156 @@
;;; org-daypage.el --- Org-Mode Day Page.
;;
;; Copyright (C) 2010-2011 Thomas Parslow
;;
;; Author: Thomas Parslow <tom@almostobsolete.net>
;; Created: June, 2010
;; Version: 1
;; Keywords: orgmode, daypage
;;; 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 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in he 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 <http://www.gnu.org/licenses/>.
;;
;;; Installation
;;
;; Add org-daypage.el to your load path and add (require 'org-daypage)
;; to your .emacs.
;;; Configuration:
;;
;; No keys are defined by default. So you may wish to add something
;; like the following to your .emacs as well:
;;
;; (define-key daypage-mode-map (kbd "<C-left>") 'daypage-prev)
;; (define-key daypage-mode-map (kbd "<C-right>") 'daypage-next)
;; (define-key daypage-mode-map (kbd "<C-up>") 'daypage-prev-week)
;; (define-key daypage-mode-map (kbd "<C-down>") 'daypage-next-week)
;; (define-key daypage-mode-map "\C-c." 'daypage-time-stamp)
;;
;; (global-set-key [f11] 'todays-daypage)
;; (global-set-key [f10] 'yesterdays-daypage)
;; (global-set-key "\C-con" 'todays-daypage)
;; (global-set-key "\C-coN" 'find-daypage)
(eval-when-compile (require 'cl))
(setq daypage-path "~/notes/days/")
(defvar daypage-mode-map
(let ((map (make-sparse-keymap)))
map)
"The key map for daypage buffers.")
(defun find-daypage (&optional date)
"Go to the day page for the specified date, or todays if none is specified."
(interactive (list
(org-read-date "" 'totime nil nil
(current-time) "")))
(setq date (or date (current-time)))
(find-file (expand-file-name (concat daypage-path (format-time-string "%Y-%m-%d" date) ".org"))))
(defun daypage-p ()
"Return true if the current buffer is visiting a daypage"
(if (daypage-date)
t
nil))
(defun daypage-date ()
"Return the date for the daypage visited by the current buffer
or nil if the current buffer isn't visiting a dayage"
(let ((file (buffer-file-name))
(root-path (expand-file-name daypage-path)))
(if (and file
(string= root-path (substring file 0 (length root-path)))
(string-match "\\([0-9]\\{4\\}\\)-\\([0-9]\\{2\\}\\)-\\([0-9]\\{2\\}\\).org$" file))
(flet ((d (i) (string-to-number (match-string i file))))
(encode-time 0 0 0 (d 3) (d 2) (d 1)))
nil)))
(defun maybe-daypage ()
"Set up daypage stuff if the org file being visited is in the daypage folder"
(let ((date (daypage-date)))
(when date
; set up the daypage key map
(use-local-map daypage-mode-map)
(set-keymap-parent daypage-mode-map
org-mode-map)
(run-hooks 'daypage-hook))))
(add-hook 'org-mode-hook 'maybe-daypage)
(defun daypage-next ()
(interactive)
(find-daypage
(seconds-to-time (+ (time-to-seconds (daypage-date))
86400)))
(run-hooks 'daypage-movement-hook))
(defun daypage-prev ()
(interactive)
(find-daypage
(seconds-to-time (- (time-to-seconds (daypage-date))
86400)))
(run-hooks 'daypage-movement-hook))
(defun daypage-next-week ()
(interactive)
(find-daypage
(seconds-to-time (+ (time-to-seconds (daypage-date))
(* 86400 7))))
(run-hooks 'daypage-movement-hook))
(defun daypage-prev-week ()
(interactive)
(find-daypage
(seconds-to-time (- (time-to-seconds (daypage-date))
(* 86400 7))))
(run-hooks 'daypage-movement-hook))
(defun todays-daypage ()
"Go straight to todays day page without prompting for a date."
(interactive)
(find-daypage)
(run-hooks 'daypage-movement-hook))
(defun yesterdays-daypage ()
"Go straight to todays day page without prompting for a date."
(interactive)
(find-daypage
(seconds-to-time (- (time-to-seconds (current-time))
86400)))
(run-hooks 'daypage-movement-hook))
(defun daypage-time-stamp ()
"Works like (and is basically a thin wrapper round)
org-time-stamp except the default date will be the date of the daypage."
(interactive)
(unless (org-at-timestamp-p)
(insert "<" (format-time-string "%Y-%m-%d %a" (daypage-date)) ">")
(backward-char 1))
(org-time-stamp nil))
(defun daypage-new-item ()
"Switches to the current daypage and inserts a top level heading and a timestamp"
(interactive)
(todays-daypage)
(end-of-buffer)
(if (not (bolp))
(insert "\n"))
(insert "* <" (format-time-string "%Y-%m-%d %a" (daypage-date)) "> "))
(provide 'org-daypage)

102
emacs/.config/doom/+org.el Normal file
View File

@ -0,0 +1,102 @@
;;; package --- summary +org.el
;;; lexical-binding: t; -*-
;;; Commentary:
;;; Code:
(setq +todo-file "~/org/inbox.org")
(setq org-directory (expand-file-name "~/Org/")
org-journal-dir "~/Org/journal/"
org-startup-indented t
org-agenda-files (list org-directory)
org-pretty-entities t
org-hide-emphasis-markers t
org-hide-leading-stars t
org-contacts-files '("~/Org/contacts.org")
; attempt to return todo function to spacemacs
evil-org-key-theme '(textobjects navigation additional insert todo)
;; show actually italicized text instead of /italicized text/
org-agenda-block-separator ""
org-fontify-whole-heading-line t
org-fontify-done-headline t
org-fontify-quote-and-verse-blocks t
org-log-done 'time
org-bullets-face-name (quote org-bullet-face)
org-bullets-bullet-list '("" "" "" "")
org-capture-templates
'(("i" "Send to inbox" entry (file+headline "~/Org/inbox.org" "Inbox")
"* TODO %?\n %i\n %a")
("n" "Create new note" entry (file "~/Org/notes.org")
"* %?\nEntered on %U\n %i\n %a")
("e" "Elation related note" entry (file "~/Org/elation.org")
"* %?\nEntered on %U\n %i\n %a")
("g" "Add glossary note" entry (file "~/Org/glossary.org")
"* %?\nEntered on %U\n %i\n")
("d" "Add an idea" entry (file "~/Org/ideas.org")
"* %?\nEntered on %U\n %i\n"))
org-todo-keywords '((sequence "TODO(t)" "|" "DONE(d)"))
org-agenda-include-diary nil
org-agenda-custom-commands
'(("h" todo "HOLD")
("d" "Agenda + Next Actions" ((agenda) (todo "NEXT"))))
org-tag-alist '(("@home" . ?h)
("@townhall" . ?t)
("@farm" . ?f)
("@read" . ?r)
("@computer" . ?c))
org-modules '(org-drill
org-id
org-info
org-habit
org-protocol
org-annotate-file
org-eval
org-expiry
org-contacts
org-man
org-notmuch
org-collector
org-panel
org-screen
org-toc)
; refile targets
org-refile-targets '(("~/Org/todo.org" :maxlevel . 2)
("~/Org/someday.org" :maxlevel . 2)
("~/Org/town.org" :maxlevel . 2)
("~/Org/personal.org" :maxlevel . 2)
("~/Org/elation.org" :maxlevel . 2)))
;; org-match-sparse-tree
;; org-set-tags-command
(defun +open-todo-file ()
(interactive)
"Opens the todo file"
(find-file +todo-file))
(map!
:leader
:desc "Open todo file" "O" #'+open-todo-file)
(defun +show-agenda ()
(interactive)
(delete-other-windows)
(with-popup-rules! nil
(org-agenda-list)
(calendar))
(other-window 1)
(split-window-vertically)
(other-window 1)
(find-file +todo-file))
(map! :leader
(:prefix "o"
:desc "Org Agenda" "a" #'org-agenda-list
:desc "Org open link" "l" #'org-open-at-point
:desc "Org Agenda and Notes" "A" #'+show-agenda))

View File

@ -0,0 +1 @@
;;; ~/devel/dotfiles/config/doom/+python.el -*- lexical-binding: t; -*-

View File

@ -0,0 +1,14 @@
;;; -*- lexical-binding: t; -*-
(def-package! ranger
:commands (ranger deer ranger-override-dired-fn)
:config
(set-popup-rule! "^\\*ranger" :ignore t))
(map!
(:leader
(:prefix "a"
:desc "Ranger" "r" #'ranger
:desc "Deer" "d" #'deer)))
(add-hook! dired-mode #'ranger-override-dired-fn) ;; Override dired-mode so it uses deer

View File

@ -0,0 +1,30 @@
;;; -*- lexical-binding: t; -*-
(def-package! reason-mode
:mode "\\.rei?$"
:commands (reason-mode)
:config
(let* (
(refmt-bin (executable-find "refmt"))
(merlin-bin (executable-find "ocamlmerlin"))
(merlin-base-dir (when merlin-bin
(replace-regexp-in-string "bin/ocamlmerlin$" "" merlin-bin))))
;; Add npm merlin.el to the emacs load path and tell emacs where to find ocamlmerlin
(when merlin-bin
(add-to-list 'load-path (concat merlin-base-dir "share/emacs/site-lisp/"))
(setq merlin-command merlin-bin))
(when refmt-bin
(setq refmt-command refmt-bin))
(require 'merlin)
(add-hook! reason-mode
(add-hook 'before-save-hook #'refmt-before-save nil t)
(merlin-mode))
(setq-hook! reason-mode
indent-region-function #'apply-refmt)
(set-electric! 'some-mode :chars '(?|))
(set-lookup-handlers! 'reason-mode
:definition #'merlin-locate
:references #'merlin-occurrences
:documentation #'merlin-document)
(set-company-backend! 'reason-mode 'merlin-company-backend)))

11
emacs/.config/doom/+ui.el Normal file
View File

@ -0,0 +1,11 @@
;;; -*- lexical-binding: t; -*-
(setq doom-theme 'doom-Iosvkem)
;; Fonts
(setq doom-font (font-spec :family "FuraCode Nerd Font" :size 14))
(setq doom-big-font (font-spec :family "FuraCode Nerd Font" :size 20))
;; Dash highlighting
;; (after! dash (dash-enable-font-lock))
;;(load! "+magit")

View File

@ -0,0 +1,9 @@
;;; ~/.config/doom/+wttrin.el -*- lexical-binding: t; -*-
(setq wttrin-default-cities '("Castine, ME" "San Francisco" "Thessaloniki"))
(setq wttrin-default-accept-language '("Accept-Language" . "en-US"))
(map!
(:leader
(:prefix "o"
:desc "Weather" "w" #'wttrin)))

View File

@ -0,0 +1,34 @@
;;; private/hlissner/autoload.el -*- lexical-binding: t; -*-
;;;###autoload
(defun +hlissner/find-in-dotfiles ()
"Open a file somewhere in ~/.dotfiles via a fuzzy filename search."
(interactive)
(doom-project-find-file (expand-file-name "~/.dotfiles")))
;;;###autoload
(defun +hlissner/browse-dotfiles ()
"Browse the files in ~/.dotfiles."
(interactive)
(doom-project-browse (expand-file-name "~/.dotfiles")))
;;;###autoload
(defun +hlissner/find-notes-for-major-mode (&optional arg)
"TODO"
(interactive "P")
(let ((default-directory (expand-file-name "code/" +org-dir)))
(if arg
(call-interactively #'find-file)
(find-file
(expand-file-name (concat (string-remove-suffix "-mode" (symbol-name major-mode)) ".org"))))))
;;;###autoload
(defun +hlissner/find-notes-for-project (&optional arg)
"TODO"
(interactive "P")
(let ((project-root (doom-project-name 'nocache))
(default-directory (expand-file-name "projects/" +org-dir)))
(if arg
(call-interactively #'find-file)
(find-file
(expand-file-name (concat project-root ".org"))))))

View File

@ -0,0 +1,126 @@
;;; ~/.config/doom/config.el -*- lexical-binding: t; -*-
;; (defvar xdg-data (getenv "XDG_DATA_HOME"))
;; (defvar xdg-bin (getenv "XDG_BIN_HOME"))
;; (defvar xdg-cache (getenv "XDG_CACHE_HOME"))
;; (defvar xdg-config (getenv "XDG_CONFIG_HOME"))
(add-to-list 'default-frame-alist '(inhibit-double-buffering . t))
(setq-default
user-full-name "Colin Powell"
user-mail-address "colin@onec.me"
+workspaces-switch-project-function #'ignore
+pretty-code-enabled-modes '(emacs-lisp-mode org-mode python-mode)
+format-on-save-enabled-modes '(not emacs-lisp-mode)
)
;; (setq-hook! 'minibuffer-setup-hook show-trailing-whitespace nil)
(setq ns-use-thin-smoothing t)
(add-to-list 'default-frame-alist '(ns-transparent-titlebar . t))
(add-to-list 'default-frame-alist '(ns-appearance . dark))
;(add-hook 'window-setup-hook 'toggle-frame-maximized)
;;
;; Keybindings
(map!
;; Easier window navigation
:n "C-h" #'evil-window-left
:n "C-j" #'evil-window-down
:n "C-k" #'evil-window-up
:n "C-l" #'evil-window-right
(:after treemacs-evil
(:map evil-treemacs-state-map
"C-h" #'evil-window-left
"C-l" #'evil-window-right))
;; Leader tricks
(:leader
(:prefix "f"
:desc "Find file in dotfiles" :n "t" #'+hlissner/find-in-dotfiles
:desc "Browse dotfiles" :n "T" #'+hlissner/browse-dotfiles)
(:prefix "t"
:desc "Switch themes" :n "t" #'counsel-load-theme)
(:prefix "o"
:desc "Elfeed feed reader" :n "f" #'elfeed)
(:prefix "a"
:desc "Save all org buffers" :n "a" #'org-save-all-org-buffers
:desc "Set task deadline" :n "d" #'org-deadline
:desc "New journal entry" :n "j" #'org-journal-new-entry
:desc "Sync gcal with org" :n "g" #'org-gcal-sync
:desc "Open agenda" :n "o" #'org-agenda-list
:desc "Schedule task" :n "s" #'org-schedule)
(:prefix "p"
:desc "Black buffer" :n "b" #'blacken-buffer)
(:prefix "y"
:desc "Yank pop!" :n "p" #'counsel-yank-pop
:desc "Git yank link" :n "g" #'git-link)
(:prefix "n"
:desc "Browse mode notes" :n "m" #'+hlissner/find-notes-for-major-mode
:desc "Browse project notes" :n "p" #'+hlissner/find-notes-for-project)))
;; Company mode
(require 'company)
(setq company-idle-delay 0.2
completion-ignore-case t
company-minimum-prefix-length 3
company-async-timeout 2)
;;(set! :company-backend 'python-mode '(company-anaconda))
(add-hook 'prog-mode-hook 'global-company-mode)
;; importmagic
(add-hook 'python-mode-hook 'importmagic-mode)
;; Golang
(add-hook 'go-mode-hook 'gofmt-before-save)
;; app/rss
(add-hook! 'elfeed-show-mode-hook (text-scale-set 1.5))
;; emacs/eshell
(after! eshell
(set-eshell-alias!
"f" "find-file $1"
"l" "ls -lh"
"d" "dired $1"
"dc" "docker-compose $1"
"gl" "(call-interactively 'magit-log-current)"
"gs" "magit-status"
"gc" "magit-commit"
"rg" "rg --color=always $*"))
;; Add notice for lines over 88 chars
;;(setq-default
;; whitespace-line-column 88
;; whitespace-style '(face lines-tail))
;; tools/magit
(setq magit-repository-directories '(("~/devel" . 2))
magit-save-repository-buffers nil)
;; make the lines in the buffer wrap around the edges of the screen.
;(add-hook 'org-mode-hook '(lambda () (visual-line-mode)))
;;; Setup sending email with msmtp
(setq send-mail-function 'sendmail-send-it
sendmail-program "/usr/local/bin/msmtp"
mail-specify-envelope-from t
message-sendmail-envelope-from 'header
mail-envelope-from 'header)
;; Hide hidden files in treemacs
(setq treemacs-show-hidden-files nil)
;;(load! "+org-daypage") ;; hardwire this baby in here somewhere
(load! "+ui") ;; My ui mods. Also contains ligature stuff.
(load! "+music") ;; Music stuff, visible through SPC-a-m. Not perfect.
(load! "+ranger") ;; File manager stuff
;;(load! "+reason") ;; ReasonML stuff
(load! "+mail") ;; Mail stuff
(load! "+org") ;; Org mode stuff like todos and rebindings
(load! "+wttrin") ;; Weather config

161
emacs/.config/doom/init.el Normal file
View File

@ -0,0 +1,161 @@
;;; init.el -*- lexical-binding: t; -*-
;; Copy me to ~/.doom.d/init.el or ~/.config/doom/init.el, then edit me!
(doom! :feature
;;debugger ; FIXME stepping through code, to help you add bugs
eval ; run code, run (also, repls)
(evil +everywhere); come to the dark side, we have cookies
file-templates ; auto-snippets for empty files
(lookup ; helps you navigate your code and documentation
+docsets) ; ...or in Dash docsets locally
snippets ; my elves. They type so I don't have to
spellcheck ; tasing you for misspelling mispelling
(syntax-checker +childframe)
workspaces ; tab emulation, persistence & separate workspaces
:completion
company ; the ultimate code completion backend
;;(helm +fuzzy)
;;ido ; the other *other* search engine...
(ivy +childframe +fuzzy) ; a search engine for love and life
:ui
;;deft ; notational velocity for Emacs
doom ; what makes DOOM look the way it does
doom-dashboard ; a nifty splash screen for Emacs
doom-modeline ; a snazzy Atom-inspired mode-line
doom-quit ; DOOM quit-message prompts when you quit Emacs
evil-goggles ; display visual hints when editing in evil
fci ; a `fill-column' indicator
hl-todo ; highlight TODO/FIXME/NOTE tags
;;modeline ; snazzy, Atom-inspired modeline, plus API
nav-flash ; blink the current line after jumping
;;neotree ; a project drawer, like NERDTree for vim
treemacs ; a project drawer, like neotree but cooler
(popup ; tame sudden yet inevitable temporary windows
+all ; catch all popups that start with an asterix
+defaults) ; default popup rules
pretty-code ; replace bits of code with pretty symbols
;;tabbar ; FIXME an (incomplete) tab bar for Emacs
unicode ; extended unicode support for various languages
vc-gutter ; vcs diff in the fringe
vi-tilde-fringe ; fringe tildes to mark beyond EOB
window-select ; visually switch windows
:editor
(format +onsave) ; automated prettiness
;;lispy ; vim for lisp, for people who dont like vim
multiple-cursors ; editing in many places at once
;;parinfer ; turn lisp into python, sort of
rotate-text ; cycle region at point between text candidates
:emacs
(dired ; making dired pretty [functional]
+ranger ; bringing the goodness of ranger to dired
+icons ; colorful icons for dired-mode
)
ediff ; comparing files in Emacs
electric ; smarter, keyword-based electric-indent
eshell ; a consistent, cross-platform shell (WIP)
hideshow ; basic code-folding support
imenu ; an imenu sidebar and searchable code index
term ; terminals in Emacs
vc ; version-control and Emacs, sitting in a tree
:tools
ansible
docker
editorconfig ; let someone else argue about tabs vs spaces
;;ein ; tame Jupyter notebooks with emacs
gist ; interacting with github gists
macos ; MacOS-specific commands
make ; run make tasks from Emacs
magit ; a git porcelain for Emacs
password-store ; password manager for nerds
pdf ; pdf enhancements
;;prodigy ; FIXME managing external services & code builders
;;rgb ; creating color strings
terraform ; infrastructure as code
;;tmux ; an API for interacting with tmux
upload ; map local to remote projects via ssh/ftp
;;wakatime
:lang
;;assembly ; assembly for fun or debugging
;;(cc +irony +rtags); C/C++/Obj-C madness
;;clojure ; java with a lisp
common-lisp ; if you've seen one lisp, you've seen them all
;;coq ; proofs-as-programs
;;crystal ; ruby at the speed of c
;;csharp ; unity, .NET, and mono shenanigans
data ; config/data formats
erlang ; an elegant language for a more civilized age
elixir ; erlang done right
elm ; care for a cup of TEA?
emacs-lisp ; drown in parentheses
;;ess ; emacs speaks statistics
go ; the hipster dialect
;;(haskell +intero) ; a language that's lazier than I am
;;hy ; readability of scheme w/ speed of python
;;idris ;
(java +meghanada) ; the poster child for carpal tunnel syndrome
javascript ; all(hope(abandon(ye(who(enter(here))))))
;;julia ; a better, faster MATLAB
;;latex ; writing papers in Emacs has never been so fun
ledger ; an accounting system in Emacs
;;lua ; one-based indices? one-based indices
markdown ; writing docs for people to ignore
;;nim ; python + lisp at the speed of c
;;nix ; I hereby declare "nix geht mehr!"
;;ocaml ; an objective camel
(org ; organize your plain life in plain text
+attach ; custom attachment system
+babel ; running code in org
+capture ; org-capture in and outside of Emacs
+export ; Exporting org to whatever you want
+hugo
+journal
+present) ; Emacs for presentations
;;perl ; write code no one else can comprehend
php ; perl's insecure younger brother
;;plantuml ; diagrams for confusing people more
;;purescript ; javascript, but functional
python ; beautiful is better than ugly
;;qt ; the 'cutest' gui framework ever
racket ; a DSL for DSLs
rest ; Emacs as a REST client
ruby ; 1.step do {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
rust ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
;;scala ; java, but good
(sh +fish) ; she sells (ba|z|fi)sh shells on the C xor
;;solidity ; do you need a blockchain? No.
;;swift ; who asked for emoji variables?
web ; the tubes
;;vala ; GObjective-C
;; Applications are complex and opinionated modules that transform Emacs
;; toward a specific purpose. They may have additional dependencies and
;; should be loaded late.
:app
notmuch
;;(email +gmail) ; emacs as an email client
irc ; how neckbeards socialize
(rss +org) ; emacs as an RSS reader
;;twitter ; twitter client https://twitter.com/vnought
;(write ; emacs as a word processor (latex + org + markdown)
;; +wordnut ; wordnet (wn) search
;; +langtool) ; a proofreader (grammar/style check) for Emacs
:collab
;;floobits ; peer programming for a price
impatient-mode ; show off code over HTTP
:config
;; For literate config users. This will tangle+compile a config.org
;; literate config in your `doom-private-dir' whenever it changes.
;;literate
;; The default module sets reasonable defaults for Emacs. It also
;; provides a Spacemacs-inspired keybinding scheme and a smartparens
;; config. Use it as a reference for your own modules.
(default +bindings +smartparens))

View File

@ -0,0 +1,61 @@
;; -*- no-byte-compile: t; -*-
;;; ~/.config/doom/packages.el
;;;
;; Snippets! From hlissner!
(package! emacs-snippets
:recipe (:fetcher github
:repo "hlissner/emacs-snippets"
:files ("*")))
(package! declutter
:recipe (:fetcher github
:repo "sanel/declutter"))
(package! ox-slack
:recipe (:fetcher github
:repo "titaniumbones/ox-slack"))
(package! counsel-spotify
:recipe (:fetcher github
:repo "Lautaro-Garcia/counsel-spotify"))
;;(package! org-daypage
;; :recipe (:fetcher github
;; :repo "almost/org-daypage"))
;; python stuffs
(package! w3m)
(package! blacken)
(package! pylint)
(package! py-isort)
(package! importmagic)
;; weather?
(package! wttrin)
;; org stuffs
(package! org-journal)
(package! ox-hugo)
(package! org-gcal)
(package! org-web-tools)
(package! org-vcard)
(package! org-snooze)
;; handy tools
(package! git-link)
(package! restclient)
(package! atomic-chrome)
(package! auth-source-pass)
(package! ivy-todo)
(package! ivy-explorer)
(package! counsel-spotify)
(package! ivy-lobsters)
;; modes!
(package! terraform-mode)
(package! exec-path-from-shell :disable t)
(package! evil-matchit :recipe (:fetcher github :repo "redguardtoo/evil-matchit" :commit "7d65b4167b1f0086c2b42b3aec805e47a0d355c4"))

View File

@ -0,0 +1 @@
fisher copy-user-key-bindings

View File

@ -0,0 +1,41 @@
# This file is automatically generated by the fish.
# Do NOT edit it directly, your changes will be overwritten.
SET FZF_DEFAULT_OPTS:\x2d\x2dheight\x2040\x25
SET FZF_LEGACY_KEYBINDINGS:1
SET FZF_PREVIEW_DIR_CMD:ls
SET FZF_PREVIEW_FILE_CMD:head\x20\x2dn\x2010
SET FZF_TMUX_HEIGHT:40\x25
SET ZO_CMD:zo
SET Z_CMD:z
SET Z_DATA:/home/powellc/\x2elocal/share/z/data
SET Z_DATA_DIR:/home/powellc/\x2elocal/share/z
SET Z_EXCLUDE:/home/powellc
SET __fish_init_2_39_8:\x1d
SET __fish_init_2_3_0:\x1d
SET fish_color_autosuggestion:555\x1ebrblack
SET fish_color_cancel:\x2dr
SET fish_color_command:\x2d\x2dbold
SET fish_color_comment:red
SET fish_color_cwd:green
SET fish_color_cwd_root:red
SET fish_color_end:brmagenta
SET fish_color_error:brred
SET fish_color_escape:bryellow\x1e\x2d\x2dbold
SET fish_color_history_current:\x2d\x2dbold
SET fish_color_host:normal
SET fish_color_match:\x2d\x2dbackground\x3dbrblue
SET fish_color_normal:normal
SET fish_color_operator:bryellow
SET fish_color_param:cyan
SET fish_color_quote:yellow
SET fish_color_redirection:brblue
SET fish_color_search_match:bryellow\x1e\x2d\x2dbackground\x3dbrblack
SET fish_color_selection:white\x1e\x2d\x2dbold\x1e\x2d\x2dbackground\x3dbrblack
SET fish_color_user:brgreen
SET fish_color_valid_path:\x2d\x2dunderline
SET fish_greeting:Welcome\x20to\x20fish\x2c\x20the\x20friendly\x20interactive\x20shell
SET fish_key_bindings:fish_default_key_bindings
SET fish_pager_color_completion:\x1d
SET fish_pager_color_description:B3A06D\x1eyellow
SET fish_pager_color_prefix:white\x1e\x2d\x2dbold\x1e\x2d\x2dunderline
SET fish_pager_color_progress:brwhite\x1e\x2d\x2dbackground\x3dcyan

View File

@ -0,0 +1,926 @@
# name: bobthefish
#
# bobthefish is a Powerline-style, Git-aware fish theme optimized for awesome.
#
# You will need a Powerline-patched font for this to work:
#
# https://powerline.readthedocs.org/en/master/installation.html#patched-fonts
#
# I recommend picking one of these:
#
# https://github.com/Lokaltog/powerline-fonts
#
# For more advanced awesome, install a nerd fonts patched font (and be sure to
# enable nerd fonts support with `set -g theme_nerd_fonts yes`):
#
# https://github.com/ryanoasis/nerd-fonts
#
# You can override some default prompt options in your config.fish:
#
# set -g theme_display_git no
# set -g theme_display_git_dirty no
# set -g theme_display_git_untracked no
# set -g theme_display_git_ahead_verbose yes
# set -g theme_display_git_dirty_verbose yes
# set -g theme_display_git_master_branch yes
# set -g theme_git_worktree_support yes
# set -g theme_display_vagrant yes
# set -g theme_display_docker_machine no
# set -g theme_display_k8s_context yes
# set -g theme_display_hg yes
# set -g theme_display_virtualenv no
# set -g theme_display_ruby no
# set -g theme_display_user ssh
# set -g theme_display_hostname ssh
# set -g theme_display_vi no
# set -g theme_avoid_ambiguous_glyphs yes
# set -g theme_powerline_fonts no
# set -g theme_nerd_fonts yes
# set -g theme_show_exit_status yes
# set -g default_user your_normal_user
# set -g theme_color_scheme dark
# set -g fish_prompt_pwd_dir_length 0
# set -g theme_project_dir_length 1
# set -g theme_newline_cursor yes
# ==============================
# Helper methods
# ==============================
function __bobthefish_basename -d 'basically basename, but faster'
string replace -r '^.*/' '' -- $argv
end
function __bobthefish_dirname -d 'basically dirname, but faster'
string replace -r '/[^/]+/?$' '' -- $argv
end
function __bobthefish_git_branch -S -d 'Get the current git branch (or commitish)'
set -l ref (command git symbolic-ref HEAD 2>/dev/null); and begin
[ "$theme_display_git_master_branch" != 'yes' -a "$ref" = 'refs/heads/master' ]
and echo $branch_glyph
and return
string replace 'refs/heads/' "$branch_glyph " $ref
and return
end
set -l tag (command git describe --tags --exact-match 2>/dev/null)
and echo "$tag_glyph $tag"
and return
set -l branch (command git show-ref --head -s --abbrev | head -n1 2>/dev/null)
echo "$detached_glyph $branch"
end
function __bobthefish_hg_branch -S -d 'Get the current hg branch'
set -l branch (command hg branch 2>/dev/null)
set -l book (command hg book | command grep \* | cut -d\ -f3)
echo "$branch_glyph $branch @ $book"
end
function __bobthefish_pretty_parent -S -a current_dir -d 'Print a parent directory, shortened to fit the prompt'
set -q fish_prompt_pwd_dir_length
or set -l fish_prompt_pwd_dir_length 1
# Replace $HOME with ~
set -l real_home ~
set -l parent_dir (string replace -r '^'"$real_home"'($|/)' '~$1' (__bobthefish_dirname $current_dir))
# Must check whether `$parent_dir = /` if using native dirname
if [ -z "$parent_dir" ]
echo -n /
return
end
if [ $fish_prompt_pwd_dir_length -eq 0 ]
echo -n "$parent_dir/"
return
end
string replace -ar '(\.?[^/]{'"$fish_prompt_pwd_dir_length"'})[^/]*/' '$1/' "$parent_dir/"
end
function __bobthefish_ignore_vcs_dir -d 'Check whether the current directory should be ignored as a VCS segment'
for p in $theme_vcs_ignore_paths
set ignore_path (realpath $p 2>/dev/null)
switch $PWD/
case $ignore_path/\*
echo 1
return
end
end
end
function __bobthefish_git_project_dir -S -d 'Print the current git project base directory'
[ "$theme_display_git" = 'no' ]; and return
set -q theme_vcs_ignore_paths
and [ (__bobthefish_ignore_vcs_dir) ]
and return
if [ "$theme_git_worktree_support" != 'yes' ]
command git rev-parse --show-toplevel 2>/dev/null
return
end
set -l git_dir (command git rev-parse --git-dir 2>/dev/null); or return
pushd $git_dir
set git_dir $PWD
popd
switch $PWD/
case $git_dir/\*
# Nothing works quite right if we're inside the git dir
# TODO: fix the underlying issues then re-enable the stuff below
# # if we're inside the git dir, sweet. just return that.
# set -l toplevel (command git rev-parse --show-toplevel 2>/dev/null)
# if [ "$toplevel" ]
# switch $git_dir/
# case $toplevel/\*
# echo $git_dir
# end
# end
return
end
set -l project_dir (__bobthefish_dirname $git_dir)
switch $PWD/
case $project_dir/\*
echo $project_dir
return
end
set project_dir (command git rev-parse --show-toplevel 2>/dev/null)
switch $PWD/
case $project_dir/\*
echo $project_dir
end
end
function __bobthefish_hg_project_dir -S -d 'Print the current hg project base directory'
[ "$theme_display_hg" = 'yes' ]; or return
set -q theme_vcs_ignore_paths
and [ (__bobthefish_ignore_vcs_dir) ]
and return
set -l d $PWD
while not [ -z "$d" ]
if [ -e $d/.hg ]
command hg root --cwd "$d" 2>/dev/null
return
end
[ "$d" = '/' ]; and return
set d (__bobthefish_dirname $d)
end
end
function __bobthefish_project_pwd -S -a current_dir -d 'Print the working directory relative to project root'
set -q theme_project_dir_length
or set -l theme_project_dir_length 0
set -l project_dir (string replace -r '^'"$current_dir"'($|/)' '' $PWD)
if [ $theme_project_dir_length -eq 0 ]
echo -n $project_dir
return
end
string replace -ar '(\.?[^/]{'"$theme_project_dir_length"'})[^/]*/' '$1/' $project_dir
end
function __bobthefish_git_ahead -S -d 'Print the ahead/behind state for the current branch'
if [ "$theme_display_git_ahead_verbose" = 'yes' ]
__bobthefish_git_ahead_verbose
return
end
set -l ahead 0
set -l behind 0
for line in (command git rev-list --left-right '@{upstream}...HEAD' 2>/dev/null)
switch "$line"
case '>*'
if [ $behind -eq 1 ]
echo '±'
return
end
set ahead 1
case '<*'
if [ $ahead -eq 1 ]
echo "$git_plus_minus_glyph"
return
end
set behind 1
end
end
if [ $ahead -eq 1 ]
echo "$git_plus_glyph"
else if [ $behind -eq 1 ]
echo "$git_minus_glyph"
end
end
function __bobthefish_git_ahead_verbose -S -d 'Print a more verbose ahead/behind state for the current branch'
set -l commits (command git rev-list --left-right '@{upstream}...HEAD' 2>/dev/null)
or return
set -l behind (count (for arg in $commits; echo $arg; end | command grep '^<'))
set -l ahead (count (for arg in $commits; echo $arg; end | command grep -v '^<'))
switch "$ahead $behind"
case '' # no upstream
case '0 0' # equal to upstream
return
case '* 0' # ahead of upstream
echo "$git_ahead_glyph$ahead"
case '0 *' # behind upstream
echo "$git_behind_glyph$behind"
case '*' # diverged from upstream
echo "$git_ahead_glyph$ahead$git_behind_glyph$behind"
end
end
function __bobthefish_git_dirty_verbose -S -d 'Print a more verbose dirty state for the current working tree'
set -l changes (command git diff --numstat | awk '{ added += $1; removed += $2 } END { print "+" added "/-" removed }')
or return
echo "$changes " | string replace -r '(\+0/(-0)?|/-0)' ''
end
# ==============================
# Segment functions
# ==============================
function __bobthefish_start_segment -S -d 'Start a prompt segment'
set -l bg $argv[1]
set -e argv[1]
set -l fg $argv[1]
set -e argv[1]
set_color normal # clear out anything bold or underline...
set_color -b $bg $fg $argv
switch "$__bobthefish_current_bg"
case ''
# If there's no background, just start one
echo -n ' '
case "$bg"
# If the background is already the same color, draw a separator
echo -ns $right_arrow_glyph ' '
case '*'
# otherwise, draw the end of the previous segment and the start of the next
set_color $__bobthefish_current_bg
echo -ns $right_black_arrow_glyph ' '
set_color $fg $argv
end
set __bobthefish_current_bg $bg
end
function __bobthefish_path_segment -S -a current_dir -d 'Display a shortened form of a directory'
set -l segment_color $color_path
set -l segment_basename_color $color_path_basename
if not [ -w "$current_dir" ]
set segment_color $color_path_nowrite
set segment_basename_color $color_path_nowrite_basename
end
__bobthefish_start_segment $segment_color
set -l directory
set -l parent
switch "$current_dir"
case /
set directory '/'
case "$HOME"
set directory '~'
case '*'
set parent (__bobthefish_pretty_parent "$current_dir")
set directory (__bobthefish_basename "$current_dir")
end
echo -n $parent
set_color -b $segment_basename_color
echo -ns $directory ' '
end
function __bobthefish_finish_segments -S -d 'Close open prompt segments'
if [ -n "$__bobthefish_current_bg" ]
set_color normal
set_color $__bobthefish_current_bg
echo -ns $right_black_arrow_glyph ' '
end
if [ "$theme_newline_cursor" = 'yes' ]
echo -ens "\n"
set_color $fish_color_autosuggestion
if [ "$theme_powerline_fonts" = "no" ]
echo -ns '> '
else
echo -ns "$right_arrow_glyph "
end
else if [ "$theme_newline_cursor" = 'clean' ]
echo -ens "\n"
end
set_color normal
set __bobthefish_current_bg
end
# ==============================
# Status and input mode segments
# ==============================
function __bobthefish_prompt_status -S -a last_status -d 'Display flags for a non-zero exit status, root user, and background jobs'
set -l nonzero
set -l superuser
set -l bg_jobs
# Last exit was nonzero
[ $last_status -ne 0 ]
and set nonzero 1
# If superuser (uid == 0)
#
# Note that iff the current user is root and '/' is not writeable by root this
# will be wrong. But I can't think of a single reason that would happen, and
# it is literally 99.5% faster to check it this way, so that's a tradeoff I'm
# willing to make.
[ -w / ]
and [ (id -u) -eq 0 ]
and set superuser 1
# Jobs display
jobs -p >/dev/null
and set bg_jobs 1
if [ "$nonzero" -o "$superuser" -o "$bg_jobs" ]
__bobthefish_start_segment $color_initial_segment_exit
if [ "$nonzero" ]
set_color normal
set_color -b $color_initial_segment_exit
if [ "$theme_show_exit_status" = 'yes' ]
echo -ns $last_status ' '
else
echo -n $nonzero_exit_glyph
end
end
if [ "$superuser" ]
set_color normal
if [ -z "$FAKEROOTKEY" ]
set_color -b $color_initial_segment_su
else
set_color -b $color_initial_segment_exit
end
echo -n $superuser_glyph
end
if [ "$bg_jobs" ]
set_color normal
set_color -b $color_initial_segment_jobs
echo -n $bg_job_glyph
end
end
end
function __bobthefish_prompt_vi -S -d 'Display vi mode'
[ "$theme_display_vi" != 'no' ]; or return
[ "$fish_key_bindings" = 'fish_vi_key_bindings' \
-o "$fish_key_bindings" = 'hybrid_bindings' \
-o "$fish_key_bindings" = 'fish_hybrid_key_bindings' \
-o "$theme_display_vi" = 'yes' ]; or return
switch $fish_bind_mode
case default
__bobthefish_start_segment $color_vi_mode_default
echo -n 'N '
case insert
__bobthefish_start_segment $color_vi_mode_insert
echo -n 'I '
case replace_one replace-one
__bobthefish_start_segment $color_vi_mode_insert
echo -n 'R '
case visual
__bobthefish_start_segment $color_vi_mode_visual
echo -n 'V '
end
end
# ==============================
# Container and VM segments
# ==============================
function __bobthefish_prompt_vagrant -S -d 'Display Vagrant status'
[ "$theme_display_vagrant" = 'yes' -a -f Vagrantfile ]; or return
# .vagrant/machines/$machine/$provider/id
for file in .vagrant/machines/*/*/id
read -l id <"$file"
if [ -n "$id" ]
switch "$file"
case '*/virtualbox/id'
__bobthefish_prompt_vagrant_vbox $id
case '*/vmware_fusion/id'
__bobthefish_prompt_vagrant_vmware $id
case '*/parallels/id'
__bobthefish_prompt_vagrant_parallels $id
end
end
end
end
function __bobthefish_prompt_vagrant_vbox -S -a id -d 'Display VirtualBox Vagrant status'
set -l vagrant_status
set -l vm_status (VBoxManage showvminfo --machinereadable $id 2>/dev/null | command grep 'VMState=' | tr -d '"' | cut -d '=' -f 2)
switch "$vm_status"
case 'running'
set vagrant_status "$vagrant_status$vagrant_running_glyph"
case 'poweroff'
set vagrant_status "$vagrant_status$vagrant_poweroff_glyph"
case 'aborted'
set vagrant_status "$vagrant_status$vagrant_aborted_glyph"
case 'saved'
set vagrant_status "$vagrant_status$vagrant_saved_glyph"
case 'stopping'
set vagrant_status "$vagrant_status$vagrant_stopping_glyph"
case ''
set vagrant_status "$vagrant_status$vagrant_unknown_glyph"
end
[ -z "$vagrant_status" ]; and return
__bobthefish_start_segment $color_vagrant
echo -ns $vagrant_status ' '
end
function __bobthefish_prompt_vagrant_vmware -S -a id -d 'Display VMWare Vagrant status'
set -l vagrant_status
if [ (pgrep -f "$id") ]
set vagrant_status "$vagrant_status$vagrant_running_glyph"
else
set vagrant_status "$vagrant_status$vagrant_poweroff_glyph"
end
[ -z "$vagrant_status" ]; and return
__bobthefish_start_segment $color_vagrant
echo -ns $vagrant_status ' '
end
function __bobthefish_prompt_vagrant_parallels -S -d 'Display Parallels Vagrant status'
set -l vagrant_status
set -l vm_status (prlctl list $id -o status 2>/dev/null | command tail -1)
switch "$vm_status"
case 'running'
set vagrant_status "$vagrant_status$vagrant_running_glyph"
case 'stopped'
set vagrant_status "$vagrant_status$vagrant_poweroff_glyph"
case 'paused'
set vagrant_status "$vagrant_status$vagrant_saved_glyph"
case 'suspended'
set vagrant_status "$vagrant_status$vagrant_saved_glyph"
case 'stopping'
set vagrant_status "$vagrant_status$vagrant_stopping_glyph"
case ''
set vagrant_status "$vagrant_status$vagrant_unknown_glyph"
end
[ -z "$vagrant_status" ]; and return
__bobthefish_start_segment $color_vagrant
echo -ns $vagrant_status ' '
end
function __bobthefish_prompt_docker -S -d 'Display Docker machine name'
[ "$theme_display_docker_machine" = 'no' -o -z "$DOCKER_MACHINE_NAME" ]; and return
__bobthefish_start_segment $color_vagrant
echo -ns $DOCKER_MACHINE_NAME ' '
end
function __bobthefish_prompt_k8s_context -S -d 'Show current Kubernetes context'
[ "$theme_display_k8s_context" = 'yes' ]; or return
set -l config_paths "$HOME/.kube/config"
[ -n "$KUBECONFIG" ]
and set config_paths (string split ':' "$KUBECONFIG") $config_paths
for file in $config_paths
[ -f "$file" ]; or continue
while read -l key val
if [ "$key" = 'current-context:' ]
set -l context (string trim -c '"\' ' -- $val)
[ -z "$context" ]; and return
__bobthefish_start_segment $color_k8s
echo -ns $context ' '
return
end
end < $file
end
end
# ==============================
# User / hostname info segments
# ==============================
# Polyfill for fish < 2.5.0
if not type -q prompt_hostname
if not set -q __bobthefish_prompt_hostname
set -g __bobthefish_prompt_hostname (hostname | string replace -r '\..*' '')
end
function prompt_hostname
echo $__bobthefish_prompt_hostname
end
end
function __bobthefish_prompt_user -S -d 'Display current user and hostname'
[ "$theme_display_user" = 'yes' -o \( "$theme_display_user" != 'no' -a -n "$SSH_CLIENT" \) -o \( -n "$default_user" -a "$USER" != "$default_user" \) ]
and set -l display_user
[ "$theme_display_hostname" = 'yes' -o \( "$theme_display_hostname" != 'no' -a -n "$SSH_CLIENT" \) ]
and set -l display_hostname
if set -q display_user
__bobthefish_start_segment $color_username
echo -ns (whoami)
end
if set -q display_hostname
if set -q display_user
# reset colors without starting a new segment...
# (so we can have a bold username and non-bold hostname)
set_color normal
set_color -b $color_hostname[1] $color_hostname[2..-1]
echo -ns '@' (prompt_hostname)
else
__bobthefish_start_segment $color_hostname
echo -ns (prompt_hostname)
end
end
set -q display_user
or set -q display_hostname
and echo -ns ' '
end
# ==============================
# Virtual environment segments
# ==============================
function __bobthefish_rvm_parse_ruby -S -a ruby_string scope -d 'Parse RVM Ruby string'
# Function arguments:
# - 'ruby-2.2.3@rails', 'jruby-1.7.19'...
# - 'default' or 'current'
set -l IFS @
echo "$ruby_string" | read __ruby __rvm_{$scope}_ruby_gemset __
set IFS -
echo "$__ruby" | read __rvm_{$scope}_ruby_interpreter __rvm_{$scope}_ruby_version __
set -e __ruby
set -e __
end
function __bobthefish_rvm_info -S -d 'Current Ruby information from RVM'
# look for rvm install path
set -q rvm_path
or set -l rvm_path ~/.rvm /usr/local/rvm
# More `sed`/`grep`/`cut` magic...
set -l __rvm_default_ruby (grep GEM_HOME $rvm_path/environments/default 2>/dev/null | sed -e"s/'//g" | sed -e's/.*\///')
set -l __rvm_current_ruby (rvm-prompt i v g)
[ "$__rvm_default_ruby" = "$__rvm_current_ruby" ]; and return
set -l __rvm_default_ruby_gemset
set -l __rvm_default_ruby_interpreter
set -l __rvm_default_ruby_version
set -l __rvm_current_ruby_gemset
set -l __rvm_current_ruby_interpreter
set -l __rvm_current_ruby_version
# Parse default and current Rubies to global variables
__bobthefish_rvm_parse_ruby $__rvm_default_ruby default
__bobthefish_rvm_parse_ruby $__rvm_current_ruby current
# Show unobtrusive RVM prompt
# If interpreter differs form default interpreter, show everything:
if [ "$__rvm_default_ruby_interpreter" != "$__rvm_current_ruby_interpreter" ]
if [ "$__rvm_current_ruby_gemset" = 'global' ]
rvm-prompt i v
else
rvm-prompt i v g
end
# If version differs form default version
else if [ "$__rvm_default_ruby_version" != "$__rvm_current_ruby_version" ]
if [ "$__rvm_current_ruby_gemset" = 'global' ]
rvm-prompt v
else
rvm-prompt v g
end
# If gemset differs form default or 'global' gemset, just show it
else if [ "$__rvm_default_ruby_gemset" != "$__rvm_current_ruby_gemset" ]
rvm-prompt g
end
end
function __bobthefish_prompt_rubies -S -d 'Display current Ruby information'
[ "$theme_display_ruby" = 'no' ]; and return
set -l ruby_version
if type -fq rvm-prompt
set ruby_version (__bobthefish_rvm_info)
else if type -fq rbenv
set ruby_version (rbenv version-name)
# Don't show global ruby version...
set -q RBENV_ROOT
or set -l RBENV_ROOT $HOME/.rbenv
[ -e "$RBENV_ROOT/version" ]
and read -l global_ruby_version <"$RBENV_ROOT/version"
[ "$global_ruby_version" ]
or set -l global_ruby_version system
[ "$ruby_version" = "$global_ruby_version" ]; and return
else if type -q chruby # chruby is implemented as a function, so omitting the -f is intentional
set ruby_version $RUBY_VERSION
else if type -fq asdf
asdf current ruby 2>/dev/null | read -l asdf_ruby_version asdf_provenance
or return
# If asdf changes their ruby version provenance format, update this to match
[ "$asdf_provenance" = "(set by $HOME/.tool-versions)" ]; and return
set ruby_version $asdf_ruby_version
end
[ -z "$ruby_version" ]; and return
__bobthefish_start_segment $color_rvm
echo -ns $ruby_glyph $ruby_version ' '
end
function __bobthefish_virtualenv_python_version -S -d 'Get current Python version'
switch (python --version 2>&1 | tr '\n' ' ')
case 'Python 2*PyPy*'
echo $pypy_glyph
case 'Python 3*PyPy*'
echo -s $pypy_glyph $superscript_glyph[3]
case 'Python 2*'
echo $superscript_glyph[2]
case 'Python 3*'
echo $superscript_glyph[3]
end
end
function __bobthefish_prompt_virtualfish -S -d "Display current Python virtual environment (only for virtualfish, virtualenv's activate.fish changes prompt by itself) or conda environment."
[ "$theme_display_virtualenv" = 'no' -o -z "$VIRTUAL_ENV" -a -z "$CONDA_DEFAULT_ENV" ]; and return
set -l version_glyph (__bobthefish_virtualenv_python_version)
if [ "$version_glyph" ]
__bobthefish_start_segment $color_virtualfish
echo -ns $virtualenv_glyph $version_glyph ' '
end
if [ "$VIRTUAL_ENV" ]
echo -ns (basename "$VIRTUAL_ENV") ' '
else if [ "$CONDA_DEFAULT_ENV" ]
echo -ns (basename "$CONDA_DEFAULT_ENV") ' '
end
end
function __bobthefish_prompt_virtualgo -S -d 'Display current Go virtual environment'
[ "$theme_display_virtualgo" = 'no' -o -z "$VIRTUALGO" ]; and return
__bobthefish_start_segment $color_virtualgo
echo -ns $go_glyph ' ' (basename "$VIRTUALGO") ' '
set_color normal
end
function __bobthefish_prompt_desk -S -d 'Display current desk environment'
[ "$theme_display_desk" = 'no' -o -z "$DESK_ENV" ]; and return
__bobthefish_start_segment $color_desk
echo -ns $desk_glyph ' ' (basename -a -s ".fish" "$DESK_ENV") ' '
set_color normal
end
# ==============================
# VCS segments
# ==============================
function __bobthefish_prompt_hg -S -a current_dir -d 'Display the actual hg state'
set -l dirty (command hg stat; or echo -n '*')
set -l flags "$dirty"
[ "$flags" ]
and set flags ""
set -l flag_colors $color_repo
if [ "$dirty" ]
set flag_colors $color_repo_dirty
end
__bobthefish_path_segment $current_dir
__bobthefish_start_segment $flag_colors
echo -ns $hg_glyph ' '
__bobthefish_start_segment $flag_colors
echo -ns (__bobthefish_hg_branch) $flags ' '
set_color normal
set -l project_pwd (__bobthefish_project_pwd $current_dir)
if [ "$project_pwd" ]
if [ -w "$PWD" ]
__bobthefish_start_segment $color_path
else
__bobthefish_start_segment $color_path_nowrite
end
echo -ns $project_pwd ' '
end
end
function __bobthefish_prompt_git -S -a current_dir -d 'Display the actual git state'
set -l dirty ''
if [ "$theme_display_git_dirty" != 'no' ]
set -l show_dirty (command git config --bool bash.showDirtyState 2>/dev/null)
if [ "$show_dirty" != 'false' ]
set dirty (command git diff --no-ext-diff --quiet --exit-code 2>/dev/null; or echo -n "$git_dirty_glyph")
if [ "$dirty" -a "$theme_display_git_dirty_verbose" = 'yes' ]
set dirty "$dirty"(__bobthefish_git_dirty_verbose)
end
end
end
set -l staged (command git diff --cached --no-ext-diff --quiet --exit-code 2>/dev/null; or echo -n "$git_staged_glyph")
set -l stashed (command git rev-parse --verify --quiet refs/stash >/dev/null; and echo -n "$git_stashed_glyph")
set -l ahead (__bobthefish_git_ahead)
set -l new ''
if [ "$theme_display_git_untracked" != 'no' ]
set -l show_untracked (command git config --bool bash.showUntrackedFiles 2>/dev/null)
if [ "$show_untracked" != 'false' ]
set new (command git ls-files --other --exclude-standard --directory --no-empty-directory 2>/dev/null)
if [ "$new" ]
set new "$git_untracked_glyph"
end
end
end
set -l flags "$dirty$staged$stashed$ahead$new"
[ "$flags" ]
and set flags " $flags"
set -l flag_colors $color_repo
if [ "$dirty" ]
set flag_colors $color_repo_dirty
else if [ "$staged" ]
set flag_colors $color_repo_staged
end
__bobthefish_path_segment $current_dir
__bobthefish_start_segment $flag_colors
echo -ns (__bobthefish_git_branch) $flags ' '
set_color normal
if [ "$theme_git_worktree_support" != 'yes' ]
set -l project_pwd (__bobthefish_project_pwd $current_dir)
if [ "$project_pwd" ]
if [ -w "$PWD" ]
__bobthefish_start_segment $color_path
else
__bobthefish_start_segment $color_path_nowrite
end
echo -ns $project_pwd ' '
end
return
end
set -l project_pwd (command git rev-parse --show-prefix 2>/dev/null | string trim --right --chars=/)
set -l work_dir (command git rev-parse --show-toplevel 2>/dev/null)
# only show work dir if it's a parent…
if [ "$work_dir" ]
switch $PWD/
case $work_dir/\*
string match "$current_dir*" $work_dir >/dev/null
and set work_dir (string sub -s (math 1 + (string length $current_dir)) $work_dir)
case \*
set -e work_dir
end
end
if [ "$project_pwd" -o "$work_dir" ]
set -l colors $color_path
if not [ -w "$PWD" ]
set colors $color_path_nowrite
end
__bobthefish_start_segment $colors
# handle work_dir != project dir
if [ "$work_dir" ]
set -l work_parent (__bobthefish_dirname $work_dir)
if [ "$work_parent" ]
echo -n "$work_parent/"
end
set_color normal
set_color -b $color_repo_work_tree
echo -n (__bobthefish_basename $work_dir)
set_color normal
set_color -b $colors
[ "$project_pwd" ]
and echo -n '/'
end
echo -ns $project_pwd ' '
else
set project_pwd $PWD
string match "$current_dir*" $project_pwd >/dev/null
and set project_pwd (string sub -s (math 1 + (string length $current_dir)) $project_pwd)
set project_pwd (string trim --left --chars=/ -- $project_pwd)
if [ "$project_pwd" ]
set -l colors $color_path
if not [ -w "$PWD" ]
set colors $color_path_nowrite
end
__bobthefish_start_segment $colors
echo -ns $project_pwd ' '
end
end
end
function __bobthefish_prompt_dir -S -d 'Display a shortened form of the current directory'
__bobthefish_path_segment "$PWD"
end
# ==============================
# Apply theme
# ==============================
function fish_prompt -d 'bobthefish, a fish theme optimized for awesome'
# Save the last status for later (do this before the `set` calls below)
set -l last_status $status
__bobthefish_glyphs
__bobthefish_colors $theme_color_scheme
type -q bobthefish_colors
and bobthefish_colors
# Start each line with a blank slate
set -l __bobthefish_current_bg
# Status flags and input mode
__bobthefish_prompt_status $last_status
__bobthefish_prompt_vi
# Containers and VMs
__bobthefish_prompt_vagrant
__bobthefish_prompt_docker
__bobthefish_prompt_k8s_context
# User / hostname info
__bobthefish_prompt_user
# Virtual environments
__bobthefish_prompt_desk
__bobthefish_prompt_rubies
__bobthefish_prompt_virtualfish
__bobthefish_prompt_virtualgo
# VCS
set -l git_root (__bobthefish_git_project_dir)
set -l hg_root (__bobthefish_hg_project_dir)
if [ "$git_root" -a "$hg_root" ]
# only show the closest parent
switch $git_root
case $hg_root\*
__bobthefish_prompt_git $git_root
case \*
__bobthefish_prompt_hg $hg_root
end
else if [ "$git_root" ]
__bobthefish_prompt_git $git_root
else if [ "$hg_root" ]
__bobthefish_prompt_hg $hg_root
else
__bobthefish_prompt_dir
end
__bobthefish_finish_segments
end

Some files were not shown because too many files have changed in this diff Show More