Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add awreece theme #443

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions modules/last_command/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Last Command
============

Provides information about the last command run.

Exported variables
------------------

- `last_command`: The string of the last command.
- `last_command_time`: The execution time (in floating point seconds) of the
last command.
- `last_command_status`: The exit status of the last command.


Exported functions
------------------

- `time_to_human`: Prints a floating point time duration in seconds.


Authors
-------

*The authors of this module should be contacted via the [issue tracker][1].*

- [Alex Reece](https://github.com/awreece)

[1]: https://github.com/awreece/prezto/issues

24 changes: 24 additions & 0 deletions modules/last_command/functions/time_to_human
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#
# Pretty prints a time in human readable format.
#
# Authors:
# Alex Reece <[email protected]>
#

# Converts a floating point time duration in seconds to a human readable string.
seconds=$1
if (( seconds < 10 )); then
printf "%6.3fs" $seconds
elif (( seconds < 60 )); then
printf "%6.3fs" $seconds
elif (( seconds < (60*60) )); then
printf "%6.3fm" $(( seconds / 60 ))
elif (( seconds < (60*60*24) )); then
printf "%6.3fh" $(( seconds / (60*60) ))
elif (( seconds < (60*60*24*30) )); then
printf "%6.3fd" $(( seconds / (60*60*24) ))
elif (( seconds < (60*60*24*30*12) )); then
printf "%6.3fm" $(( seconds / (60*60*24*30) ))
else
printf "%6.3fy" $(( seconds / (60*60*24*30*12) ))
fi
40 changes: 40 additions & 0 deletions modules/last_command/init.zsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#
# Provides information about the last command.
#
# Authors:
# Alex Reece <[email protected]>
#

# Provided values.
last_command=''
last_command_status=0
last_command_time=0.0

zmodload zsh/datetime # For EPOCHREALTIME.

# This value is used internally by this module and is not intended to be used
# elsewhere.
last_command_start_time='invalid'

function last_command_precmd {
exit_status=$? # TODO(awreece) What happens if another precmd runs first?

# We do these 'invalid' shenanigans because zsh executes precmd but not
# preexec if an empty line is entered.
if [[ $last_command_start_time != 'invalid' ]]; then
last_command_status=$exit_status
last_command_time=$((EPOCHREALTIME - last_command_start_time))

last_command_start_time='invalid'
fi
}

function last_command_preexec {
last_command_start_time=$EPOCHREALTIME
last_command=$1
}

autoload -Uz add-zsh-hook

add-zsh-hook precmd last_command_precmd
add-zsh-hook preexec last_command_preexec
42 changes: 42 additions & 0 deletions modules/notify/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
Notify
======

Cross platform notification support.

Functions
---------

- `notify` opens a notification with the given args. Usage: `notify hello world`.

Settings
--------

### Growl

By default, `notify` will use the Notification Center on Mac OSX via
`terminal-notifier` and will fall back to Growl if this is not available. To
force the use of growl, add the following to *zpreztorc*.

zstyle ':prezto:module:notify' force-growl 'yes'

### Auto-notify if window not focused

This module can automatically notify if a (long running) command completes
while the terminal window does not have focus. This will pop up a notification
with information about the last command like this:

![Last command notification](http://codearcana.com/images/zsh_theme_popup.png)

To enable this feature, add the following to *zpreztorc*:

zstyle ':prezto:module:notify' auto-notify 'yes'

Authors
-------

*The authors of this module should be contacted via the [issue tracker][1].*

- [Alex Reece](https://github.com/awreece)

[1]: https://github.com/awreece/prezto/issues

20 changes: 20 additions & 0 deletions modules/notify/functions/focused_window_id
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Gets the id of the current focused window.
#
# Authors:
# Alex Reece <[email protected]>
#

case "$OSTYPE" in
(darwin*)
osascript -e 'tell application (path to frontmost application as text) ¬' \
-e ' to get id of front window' 2>/dev/null
;;
(linux-gnu*)
# http://stackoverflow.com/a/8688624/447288
xprop -root -f _NET_ACTIVE_WINDOW 0x ' $0' _NET_ACTIVE_WINDOW \
| awk '{print $2}'
;;
(*)
return 1
;;
esac
27 changes: 27 additions & 0 deletions modules/notify/functions/notify
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Pops up a notification with the provided arg.
#
# Authors:
# Alex Reece <[email protected]>
#

# I actually want all the args as one string.
message="$*"

case "$OSTYPE" in
(darwin*)
if is-callable terminal-notifier && \
! zstyle -t ':prezto:module:notify' force-growl; then
terminal-notifier >/dev/null -message $message
elif is-callable growlnotify; then
growlnotify --message $message
else
return 1
fi
;;
(linux-gnu*)
notify-send $message
;;
(*)
return 1
;;
esac
40 changes: 40 additions & 0 deletions modules/notify/functions/notify_last_command
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Sends a notification that the last command completed.
#
# Assumes $terminal_window_id is the id of the terminals window and that
# last_comand module is loaded.
#
# Authors:
# Alex Reece <[email protected]>
#

message=$(printf "Command \"%s\" finished (%d) after %s." \
$last_command \
$last_command_status \
$(time_to_human $last_command_time))

# We duplicate a lot of the functionality of notify, but it means we can
# have this nifty callback to select the window that finished.

# TODO(awreece) Add support for user defined callback.
case "$OSTYPE" in
(darwin*)
if is-callable terminal-notifier &&
! zstyle -t ':prezto:module:notify' force-growl; then
callback="osascript -e 'tell application \"Terminal\"' \
-e 'activate' \
-e 'set index of window id $terminal_window_id to 1' \
-e 'end tell'"
terminal-notifier -message $message -execute $callback >/dev/null
elif is-callable growlnotify; then
growlnotify --message $message
else
return 1
fi
;;
(linux-gnu*)
notify-send "Command finished" $message
;;
(*)
return 1
;;
esac
35 changes: 35 additions & 0 deletions modules/notify/functions/should_auto_notify
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Check if it makes sense to load the notify module.
#
# Checks for requirements, that it is an xsession, etc.
#
# Authors:
# Alex Reece <[email protected]>
#

if ! zstyle -t ':prezto:module:notify' auto-notify; then
return 1
fi

case "$OSTYPE" in
(darwin*)
# TODO(awreece) Disable if ssh with no windows?
is-callable terminal-notifier || is-callable growlnotify
;;
(linux-gnu*)
# Disable if don't have X.
if [[ -z $XAUTHORITY ]]; then
return 1
fi

# We need both of these functions to operate.
if (( ! $+commands[notify-send] || ! $+commands[xprop] )); then
return 1
fi

return 0
;;
(*)
# If we don't know, then just disable.
return 1
;;
esac
25 changes: 25 additions & 0 deletions modules/notify/init.zsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Notifies if the last command completes and terminal window is not in
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A notification module ought to be generic and should be able to notify of anything. The code found in this module does not satisfy the requirement.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you prefer I rename the module to make it clear that it is not generic (to something like 'notify_last_command'), or that I add support for generic notifications?

For reference, I don't think it would be that easy to decouple the notification functionality from the notify-if-not-focused functionality (on Mac OSX, additional flags are needed to specific a callback to focus the window, etc). However, it might not be too hard to add support for arbitrary notifications and then offer a setup function to enable notify-if-not-focused.

# foreground.
#
# Authors:
# Alex Reece <[email protected]>
#

pmodload 'helper'

if should_auto_notify; then
pmodload 'last_command'

# Initialize $terminal_window_id to the current active window.
terminal_window_id=$(focused_window_id)

function notify_precmd {
if [[ $(focused_window_id) != $terminal_window_id ]]; then
notify_last_command
fi
}

autoload -Uz add-zsh-hook

add-zsh-hook precmd notify_precmd
fi
81 changes: 81 additions & 0 deletions modules/prompt/functions/prompt_awreece_setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#
# A simple theme that displays relevant, contextual information.
#
# Authors:
# Alex Reece <[email protected]>
#
# Screenshots:
# http://codearcana.com/posts/2013/11/06/my-zsh-theme.html
# http://codearcana.com/images/zsh_theme.png
#

function prompt_awreece_help {
cat <<EOH
Prompt will look like:
#############################################################################
+----------- Last part in path to current working directory.
|
| +-- A '#' if root shell, colored green if the last command was
| | successful and red otherwise.
| |
| | Duration of last command, colored green if last command --+
| | was successful and red otherwise. |
| | |
| | ssh user and hostname -------------------------+ |
| | (if connected via ssh). | |
| | | |
| | Full path to current working --+ | |
| | directory (if longer than | | |
| | than 1 segment). | | |
| | | | |
| | Number of background jobs --+ | | |
| | (if any). | | | |
v v v v v v
#############################################################################
Developer% 1& ~/bin/Developer [alex@cmu] 2.001s
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the point of showing the path twice? It's redundant. The path on the left ought to be removed. The path on the right could be shortened like the sorin theme when it's too long or always.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the command line is long (and forces the RPROMPT to be hidden), it provides a small amount of context. And if it is actually redundant (the exact same text) the right hand path isn't displayed. I think this is more of a taste thing, and perhaps something I could leave configurable.

I do like the sorin theme shortening, and would consider using that for the right hand prompt.

EOH
}

function prompt_awreece_setup {
prompt_opts=(cr percent subst)

# Load prerequisites.
pmodload 'last_command'

# Variables used for prompts.
local background_job_status='%(1j.%F{yellow}%j&%f .)'
local full_directory='%(2~.%F{blue}%~%f .)'
local ssh_host=''
if prompt_awreece_is_ssh; then
ssh_host='%F{cyan}[%n@%m]%f '
fi
local command_time='%(?.%F{green}.%F{red})$(prompt_awreece_command_time)%f'

# Define prompts.
PROMPT='%F{blue}%1~%f%F{magenta}%#%f '
RPROMPT="${background_job_status}${full_directory}${ssh_host}${command_time}"
}

function prompt_awreece_command_time {
time_to_human $last_command_time
}

# Return a zero exit status (true) iff the current shell is controlled via ssh.
function prompt_awreece_is_ssh {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is not necessary. You can check inside the RPROMPT definition with ${SSH_TTY:+"%F{cyan}[%n@%m]%f"}.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you read the comment in is_ssh? It is harder than just checking a variable, and I want to leave myself the room to update and handle more cases.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did. I believe that there is a sudo switch that makes it inherit the environment. It's not a big issue. I know of no other solution.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is rather dangerous to have sudo inherit the environment (variables like LD_PRELOAD probably shouldn't be inherited).

An alternative solution (that I don't like) would be to walk up the chain of parent processes until ssh is found.

# Actually, sudo etc clear a bunch of environment variables, including
# SSH_CONNECTION, so this doesn't always work. Unfortunately, I don't know
# the best way to make it work. For now, I'll hide it in a function and I can
# update it when I figure out a better way later.
[[ -n $SSH_CONNECTION ]]
}

function prompt_awreece_preview {
local +h PROMPT='%# '
local +h RPROMPT=''
# Set a last_command_time to make it interesting.
local +h last_commmand_time=3.14159

prompt_preview_theme 'awreece' "$@"
}

prompt_awreece_setup "$@"