annotate vim/bundle/math/plugin/vmath.vim @ 22:b2c16cd71d95

Add math plugin
author zegervdv <zegervdv@me.com>
date Sun, 23 Mar 2014 18:08:34 +0100
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
22
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
1 " Vim global plugin for math on visual regions
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
2 " Maintainer: Damian Conway
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
3 " License: This file is placed in the public domain.
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
4
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
5 "######################################################################
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
6 "## ##
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
7 "## To use: ##
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
8 "## ##
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
9 "## vmap <expr> ++ VMATH_YankAndAnalyse() ##
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
10 "## nmap ++ vip++ ##
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
11 "## ##
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
12 "## (or whatever keys you prefer to remap these actions to) ##
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
13 "## ##
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
14 "######################################################################
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
15
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
16
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
17 " If already loaded, we're done...
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
18 if exists("loaded_vmath")
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
19 finish
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
20 endif
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
21 let loaded_vmath = 1
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
22
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
23 " Preserve external compatibility options, then enable full vim compatibility...
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
24 let s:save_cpo = &cpo
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
25 set cpo&vim
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
26
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
27 " Grab visual selection and do simple math on it...
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
28 function! VMATH_YankAndAnalyse ()
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
29 return "y:call VMATH_Analyse()\<CR>gv"
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
30 endfunction
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
31
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
32 " What to consider a number...
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
33 let s:NUM_PAT = '^[+-]\?\d\+\%([.]\d\+\)\?\([eE][+-]\?\d\+\)\?$'
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
34
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
35 " How widely to space the report components...
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
36 let s:REPORT_GAP = 5 "spaces between components
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
37
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
38 " Do simple math on current yank buffer...
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
39 function! VMATH_Analyse ()
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
40 " Extract data from selection...
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
41 let selection = getreg('')
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
42 let raw_numbers = filter(split(selection), 'v:val =~ s:NUM_PAT')
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
43 let numbers = map(copy(raw_numbers), 'str2float(v:val)')
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
44
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
45 " Results include a newline if original selection did...
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
46 let newline = selection =~ "\n" ? "\n" : ""
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
47
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
48 " Calculate and en-register various interesting metrics...
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
49 let summation = len(numbers) ? join( numbers, ' + ') : '0'
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
50 call setreg('s', s:tidy( eval( summation ) )) " Sum --> register s
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
51 call setreg('a', s:average(raw_numbers) ) " Average --> register a
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
52 call setreg('x', s:tidy( s:max(numbers) )) " Max --> register x
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
53 call setreg('n', s:tidy( s:min(numbers) )) " Min --> register n
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
54 call setreg('r', @n . ' to ' . @x ) " Range --> register r
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
55
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
56 " Default paste buffer should depend on original contents (TODO)
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
57 call setreg('', @s )
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
58
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
59 " Report...
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
60 let gap = repeat(" ", s:REPORT_GAP)
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
61 highlight NormalUnderlined term=underline cterm=underline gui=underline
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
62 echohl NormalUnderlined
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
63 echo 's'
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
64 echohl NONE
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
65 echon 'um: ' . @s . gap
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
66 echohl NormalUnderlined
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
67 echon 'a'
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
68 echohl NONE
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
69 echon 'vg: ' . @a . gap
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
70 echon 'mi'
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
71 echohl NormalUnderlined
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
72 echon 'n'
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
73 echohl NONE
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
74 echon ': ' . @n . gap
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
75 echon 'ma'
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
76 echohl NormalUnderlined
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
77 echon 'x'
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
78 echohl NONE
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
79 echon ': ' . @x . gap
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
80
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
81 endfunction
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
82
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
83 " Prettify numbers...
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
84 function! s:tidy (number)
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
85 let tidied = printf('%g', a:number)
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
86 return substitute(tidied, '[.]0\+$', '', '')
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
87 endfunction
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
88
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
89 " Compute average with meaningful number of decimal places...
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
90 function! s:average (numbers)
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
91 " Compute average...
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
92 let summation = eval( len(a:numbers) ? join( a:numbers, ' + ') : '0' )
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
93 let avg = 1.0 * summation / s:max([len(a:numbers), 1])
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
94
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
95 " Determine significant figures...
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
96 let min_decimals = 15
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
97 for num in a:numbers
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
98 let decimals = strlen(matchstr(num, '[.]\d\+$')) - 1
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
99 if decimals < min_decimals
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
100 let min_decimals = decimals
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
101 endif
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
102 endfor
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
103
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
104 " Adjust answer...
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
105 return min_decimals > 0 ? printf('%0.'.min_decimals.'f', avg)
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
106 \ : string(avg)
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
107 endfunction
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
108
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
109 " Reimplement these because the builtins don't handle floats (!!!)
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
110 function! s:max (numbers)
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
111 if !len(a:numbers)
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
112 return 0
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
113 endif
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
114 let numbers = copy(a:numbers)
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
115 let maxnum = numbers[0]
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
116 for nextnum in numbers[1:]
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
117 if nextnum > maxnum
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
118 let maxnum = nextnum
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
119 endif
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
120 endfor
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
121 return maxnum
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
122 endfunction
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
123
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
124 function! s:min (numbers)
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
125 if !len(a:numbers)
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
126 return 0
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
127 endif
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
128 let numbers = copy(a:numbers)
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
129 let minnum = numbers[0]
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
130 for nextnum in numbers[1:]
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
131 if nextnum < minnum
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
132 let minnum = nextnum
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
133 endif
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
134 endfor
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
135 return minnum
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
136 endfunction
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
137
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
138
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
139 " Restore previous external compatibility options
b2c16cd71d95 Add math plugin
zegervdv <zegervdv@me.com>
parents:
diff changeset
140 let &cpo = s:save_cpo