summary refs log tree commit diff
path: root/Functions/Misc/sticky-note
blob: cfe9ea684cfef6848f7b0d09cc45b226cd480efe (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/bin/zsh -fi
# A zsh sticky-note ("post-it") application.  Load this file as a function:
#    autoload -Uz sticky-note
#
# It may then be bound as a widget:
#    zle -N sticky-note
# And/or run as a command:
#    sticky-note
#    sticky-note -b
#    sticky-note -l ...
# The -b option is like "zed -b": it installs keymaps/bindings only.
# Use the -l option to list previous sticky notes.  Most options of the
# "fc -l" command are supported, for selecting which notes to display.
# If "sticky-note -l" is run from inside a widget, the cursor is moved
# to the top left of the terminal before display and returned to its
# original position after display.  The -l option is implicitly added
# when sticky-note is called from zle-line-init, to avoid inadvertently
# trapping the user inside the note editor.
#
# Otherwise, invoke the line editor with the previous notes available
# as an editor history.  Two quick taps on the return/enter key finish
# the note, or you can use use ^X^W as usual (ZZ in vicmd mode).

# The application is configured by three zstyles, all using the context
# ":sticky-note".  The first two styles are "notefile" and "maxnotes"
# to name the file in which notes are stored and the maximum number of
# notes to retain:
#   zstyle :sticky-note notefile ~/.zsticky
#   zstyle :sticky-note maxnotes 1000

# The "theme" style may be set to control the appearance of the notes.
# The style is an associative array; the current set of values (defaults
# in parens) are:
#   bg    => name or ANSI escape for background color (yellow)
#   fg    => name or ANSI escape for foreground color (black)
#   color => ANSI escape for color scheme ($theme[bg]$theme[fg])
#   reset => ANSI escape to restore "normal" colors
# Values given as names are looked up in the $bg and $fg arrays from the
# "colors" function.  If a "color" field is set, the "bg" and "fg" fields
# are not used.  Example:
#   zstyle :sticky-note theme \
#     bg red \
#     fg $fg_bold[yellow]

# For backwards compatibility with an earlier version, the notefile may
# also be named by the STICKYFILE variable (defaults to $HOME/.zsticky).
# The number of notes stored may be given by STICKYSIZE (1000).

# I encourage all you creative people to contribute enhancements ...

emulate -LR zsh
setopt nobanghist extendedhistory histignoredups

local STICKYFILE=${STICKYFILE:-$HOME/.zsticky}
local STICKYSIZE=${STICKYSIZE:-1000}
local sticky stickyfile stickysize

zstyle -s :sticky-note notefile stickyfile || stickyfile=$STICKYFILE
zstyle -s :sticky-note maxnotes stickysize || stickysize=$STICKYSIZE

# Set up keybindings (adapted from "zed")
if ! bindkey -M sticky >& /dev/null
then
  bindkey -N sticky main
  bindkey -M sticky ^X^W accept-line
  bindkey -M sticky ^M^M accept-line	# Two quick RETs ends note
  bindkey -M sticky ^M self-insert-unmeta
fi
if ! bindkey -M sticky-vicmd >& /dev/null 
then
  bindkey -N sticky-vicmd vicmd
  bindkey -M sticky-vicmd ZZ accept-line
fi

[[ "$1" == -b ]] && return 0

# Look up color theme
local -A theme
(($+bg && $+fg)) || { autoload -Uz colors; colors }
zstyle -m :sticky-note theme '*' || {
    zstyle :sticky-note theme bg yellow fg black
}
zstyle -a :sticky-note theme theme
(( ${+bg[$theme[bg]]} )) && theme[bg]=$bg[$theme[bg]]
(( ${+fg[$theme[fg]]} )) && theme[fg]=$fg[$theme[fg]]
(( ${+theme[color]} )) || theme[color]=$theme[bg]$theme[fg]
(( ${+theme[reset]} )) || theme[reset]=$reset_color

# If invoked as a widget, behave a bit like run-help
if zle
then
  zmodload -i zsh/parameter
  if [[ $* == -*l* || $functrace == *zle-line-init:* ]]
  then
    fc -ap $stickyfile $stickysize $stickysize
    echoti sc
    echoti home
    print -nr "$theme[color]"
    fc -l "${@:--1}" | while read -r sticky; do print -- "$sticky"; done
    print -nr "$theme[reset]"
    echoti rc
  elif [[ $CONTEXT = (cont|select|vared) ]]
  then
    zle -M "No stickies during ${${(z)PREBUFFER}[1]:-$CONTEXT}, sorry"
    zle .beep
    zle -R
  else
    zle .push-line
    BUFFER=sticky-note
    zle .accept-line
  fi
  return 0
fi

# Invoked as a command, behave like zed, but write a history file
fc -ap $stickyfile $stickysize $stickysize

# With a -l option, list the existing sticky notes
if [[ "$*" == -*l* ]]
then
  print -nr "$theme[color]"
  # Use read/print loop to interpolate "\n" in history lines
  fc -f "$@" | while read -r sticky; do print -- "$sticky"; done
  print -nr "$theme[reset]"
  return 0
fi

# Edit a new sticky note and add it to the stickyfile
while vared -h -p "%{$theme[color]%}" -M sticky -m sticky-vicmd sticky
do
  {
    [[ -n "$sticky" ]] && print -s -- "$sticky"
  } always {
    (( TRY_BLOCK_ERROR = 0 ))
  } && break
  echo -n -e '\a'
done
return 0