├── README.md
├── autoload
└── colddeck.vim
├── doc
└── colddeck.txt
├── ftdetect
└── colddeck.vim
├── ftplugin
└── colddeck.vim
├── plugin
└── colddeck.vim
└── syntax
└── colddeck.vim
/README.md:
--------------------------------------------------------------------------------
1 | Vim-colddeck
2 | -------------
3 |
4 | > Vim meets Instacalc meets Hewlett-Packard calculators
5 |
6 | Colddeck ("Column dc") is a single-column spreadsheet using `dc` for
7 | computations. You jot down values and formulas, one per line, and the result
8 | is shown on the right.
9 |
10 | Extra features:
11 |
12 | - References to other rows (absolute and relative)
13 | - Ranges
14 | - Aggregates (sum, min/max, average...)
15 | - Vim expressions (experimental)
16 | - Value references (experimental)
17 |
18 | Example
19 | --------
20 |
21 | [](https://asciinema.org/a/0NgfyWgetZBIoXi6O3ikawkIE)
22 |
23 | Syntax in a nutshell
24 | ---------------------
25 |
26 | - `R3`: reference to row #3
27 | - `R-1`: relative reference to the row above
28 | - `R+2`: relative reference to the second row below
29 | - `R1:R3`: range of rows from #1 to #3 (insert values and number of elements)
30 | - `R1:R3 @sum`: sum of row #1 to #3 (other aggregates: `@min`, `@max`, `@avg`,
31 | `@prod`)
32 | - `42 # text`: add "text" as a comment, while passing the value '42' to `dc`
33 | - `42 ## Label`: add "Label" as a right-aligned comment and hide the value or
34 | formula on its left, that is still passed to `dc`
35 | - `log(2)`
: vim expression (evaluated before passing the
36 | line to `dc`)
37 | - `$2`: *result* of the evalutation of row #2 (must have been previously
38 | computed; evaluated before passing the line to `dc`)
39 |
40 | See [the documentation](doc/colddeck.txt) for full manual.
41 |
42 | FAQ
43 | ----
44 |
45 | *What is it?*
46 | A single-column spreadsheet, in Vim, with postfix operators.
47 | Look ma, no Excel.
48 |
49 | *"dc", WTF?*
50 | Who doesn't love rabid panda notation?
51 |
52 | Installation
53 | -------------
54 | Use your favorite method:
55 | * [Pathogen][1] - git clone https://github.com/fcpg/vim-colddeck ~/.vim/bundle/vim-colddeck
56 | * [NeoBundle][2] - NeoBundle 'fcpg/vim-colddeck'
57 | * [Vundle][3] - Plugin 'fcpg/vim-colddeck'
58 | * [Plug][4] - Plug 'fcpg/vim-colddeck'
59 | * manual - copy all files into your ~/.vim directory
60 |
61 | License
62 | --------
63 | [Attribution-ShareAlike 4.0 Int.](https://creativecommons.org/licenses/by-sa/4.0/)
64 |
65 | [1]: https://github.com/tpope/vim-pathogen
66 | [2]: https://github.com/Shougo/neobundle.vim
67 | [3]: https://github.com/gmarik/vundle
68 | [4]: https://github.com/junegunn/vim-plug
69 |
70 |
--------------------------------------------------------------------------------
/autoload/colddeck.vim:
--------------------------------------------------------------------------------
1 | " colddeck.vim - column-dc spreadsheet
2 |
3 | let s:save_cpo = &cpo
4 | set cpo&vim
5 |
6 | "------------
7 | " Debug {{{1
8 | "------------
9 |
10 | let g:cdeck_debug = 1
11 | if 0
12 | append
13 | " comment out all dbg calls
14 | :g,\c^\s*call Dbg(,s/call/"call/
15 | " uncomment
16 | :g,\c^\s*"call Dbg(,s/"call/call/
17 | .
18 | endif
19 |
20 |
21 | "--------------
22 | " Options {{{1
23 | "--------------
24 |
25 | " Defaults
26 | let s:def_rcol = 78
27 | let s:def_prec = 2
28 | let s:def_precmd = ''
29 | let s:def_autoahc = 1
30 | let s:def_dcerr = 0
31 |
32 | " Errors
33 | let s:err_notavail = get(g:, 'cdeck_err_notavail', '[N/A]')
34 | let s:err_valref_notfound = printf('[%s]',
35 | \ get(g:, 'cdeck_err_valref_notfound', 'value ref not found (yet)'))
36 | let s:err_vimexpr = printf('[%s]',
37 | \ get(g:, 'cdeck_err_vim_expr', 'vim expression error'))
38 |
39 | " Library of dc macros
40 | " - stored in '*' array
41 | " - input expected in '(' array
42 | " - output goes in ')' array (though these macros don't depend on it)
43 | "
44 | " 0: expand ranges
45 | " 1: pop number and execute 'Y' macro that many times ('fold', kinda)
46 | " 2: sum over stack with num of elems on top
47 | " 3: multiply over stack with num of elems on top
48 | " 4: find min over stack with num of elems on top
49 | " 5: find max over stack with num of elems on top
50 | " 6: compute average over stack with num of elems on top
51 | let s:dc_lib_cmd = join([
52 | \ '[SEdSSSI[lI;(xlI1+dsIlE!Rs-LAs-LBs-LRs-]SY1;*x]', '5:*',
58 | \ '[dSN[+]SY1;*xLN/]', '6:*',
59 | \])
60 |
61 | " Macros invocation
62 | let s:dc_range = ' 0;*x'
63 | let s:dc_sum = ' 2;*x'
64 | let s:dc_prod = ' 3;*x'
65 | let s:dc_min = ' 4;*x'
66 | let s:dc_max = ' 5;*x'
67 | let s:dc_avg = ' 6;*x'
68 |
69 | " Default value '[]' in 's' register
70 | let s:dc_defval_cmd = '[[]]s+'
71 |
72 | " '[True]' string in '?' (for user convenience, not used internally)
73 | let s:dc_truereg_cmd = '[[True]]s?'
74 |
75 |
76 | "----------------
77 | " Functions {{{1
78 | "----------------
79 |
80 | " colddeck#ParseLine()
81 | "
82 | " Parse a single line from current buffer
83 | "
84 | " Args:
85 | " - line number
86 | " Returns:
87 | " - dict:
88 | " - 'cmd': command
89 | " - 'rem': comment
90 | "
91 | function! colddeck#ParseLine(linenr) abort
92 | let ret = {'cmd': '', 'rem': ''}
93 | let rcol = get(b:, 'cdeck_rcol', get(g:, 'cdeck_rcol', s:def_rcol))
94 | let line = getline(a:linenr)
95 | " trim results
96 | let line_nores = substitute(strpart(line, 0, rcol), '\s*$', '', '')
97 | let mlist = matchlist(line_nores, '\v\c^([^#]*)(#%(.*\S)?)?\s*$')
98 | let cmdpart = substitute(get(mlist, 1, ''), '\s\+$', ' ', '')
99 | let ret['rem'] = get(mlist, 2, '')
100 | if cmdpart =~ '^\s*$'
101 | " store an empty string
102 | let tmpcmd = '[]'
103 | else
104 | let tmpcmd = cmdpart
105 | " expand `$+num` refs
106 | let tmpcmd = substitute(tmpcmd,
107 | \ '\$\(\d\+\)',
108 | \ '\=get(b:cdeck_results, submatch(1), "VALREF_ERROR")',
109 | \ 'g')
110 | if tmpcmd =~ 'VALREF_ERROR'
111 | " expansion error, ignore this line
112 | let tmpcmd = s:err_valref_notfound
113 | endif
114 | " expand backticks
115 | try
116 | let tmpcmd = substitute(tmpcmd,
117 | \ '`\([^`]*\)`',
118 | \ '\=string(eval(submatch(1)))',
119 | \ 'g')
120 | catch
121 | " eval error, ignore this line
122 | let tmpcmd = s:err_vimexpr
123 | endtry
124 | " expand `R+num:R+num` ref ranges
125 | let tmpcmd = substitute(tmpcmd,
126 | \ '\CR\(\d\+\):R\(\d\+\)',
127 | \ ' \1 \2 ' . s:dc_range,
128 | \ 'g')
129 | " expand `@sum`
130 | let tmpcmd = substitute(tmpcmd, '\C@sum', s:dc_sum, 'g')
131 | " expand `@prod`
132 | let tmpcmd = substitute(tmpcmd, '\C@prod', s:dc_prod, 'g')
133 | " expand `@min`
134 | let tmpcmd = substitute(tmpcmd, '\C@min', s:dc_min, 'g')
135 | " expand `@max`
136 | let tmpcmd = substitute(tmpcmd, '\C@max', s:dc_max, 'g')
137 | " expand `@avg`
138 | let tmpcmd = substitute(tmpcmd, '\C@avg', s:dc_avg, 'g')
139 | " expand `R+num` refs
140 | let tmpcmd = substitute(tmpcmd, '\C\vR(\d+)', ' \1;(x', 'g')
141 | " expand relative refs
142 | let tmpcmd = substitute(tmpcmd, '\C\vR([+-]\d+)',
143 | \ '\=" ".('.a:linenr.'+submatch(1)).";(x"', 'g')
144 | endif
145 | " store cmd as string into array '(', indexed by line num
146 | let ret['cmd'] = printf('[%s]%s:(', tmpcmd, a:linenr)
147 | "call Dbg("parsed line (#, cmd, rem):", a:linenr, ret['cmd'], ret['rem'])
148 | return ret
149 | endfun
150 |
151 |
152 | " colddeck#CalcBuffer()
153 | "
154 | " Evaluate values and commands, then insert results after rcol
155 | "
156 | function! colddeck#CalcBuffer() abort
157 | let rcol = get(b:, 'cdeck_rcol', get(g:, 'cdeck_rcol', s:def_rcol))
158 | let prec = get(b:, 'cdeck_prec', get(g:, 'cdeck_prec', s:def_prec))
159 | let precmd = get(b:, 'cdeck_precmd', get(g:, 'cdeck_precmd', s:def_precmd))
160 | let autoac = get(b:, 'cdeck_autoahc', get(g:, 'cdeck_autoahc', s:def_autoahc))
161 | let rchar = get(g:, 'cdeck_rchar', '>')
162 | let dcpath = get(g:, 'cdeck_dc_path', 'dc')
163 | let dc_init_cmd = join([
164 | \ prec."k",
165 | \ s:dc_defval_cmd,
166 | \ s:dc_truereg_cmd,
167 | \ precmd,
168 | \ "c",
169 | \], '')
170 | let dc_store_cmd = ""
171 | let dc_calc_cmd = ""
172 | let dc_show_cmd = ""
173 | let dc_cmd = ""
174 | let lastlinenr = line('$')
175 | let bufmodified = &modified
176 |
177 | let curpos = getcurpos()
178 |
179 | " clear previous results
180 | call colddeck#RemoveResults()
181 |
182 | " parse buffer and build dc cmdline
183 | let linenr = 1
184 | while linenr <= lastlinenr
185 | let parsedline = colddeck#ParseLine(linenr)
186 | let dc_store_cmd .= parsedline['cmd']
187 | let dc_calc_cmd .= "c".linenr.';(xz0=+'.linenr.':) '
188 | let dc_show_cmd = linenr.';)' . dc_show_cmd
189 | let linenr += 1
190 | endwhile
191 |
192 | " execute in dc
193 | let dc_cmd = join([
194 | \ s:dc_lib_cmd,
195 | \ dc_init_cmd,
196 | \ dc_store_cmd,
197 | \ dc_calc_cmd,
198 | \ "c",
199 | \ dc_show_cmd,
200 | \ "f",
201 | \])
202 | "call Dbg("dc_cmd:", dc_cmd)
203 | let dc = dcpath .
204 | \ (!get(b:, 'cdeck_dcerr', get(g:, 'cdeck_dcerr', s:def_dcerr))
205 | \ ? ' 2>/dev/null'
206 | \ : '')
207 | let dc_result = systemlist(dc, dc_cmd)
208 | "call Dbg("dc_result:", string(dc_result))
209 |
210 | " insert new results
211 | let linenr = 1
212 | let b:cdeck_results = {}
213 | while linenr <= lastlinenr
214 | let curline = getline(linenr)
215 | let linelen = strwidth(curline)
216 | let fillcount = max([rcol - linelen, 1])
217 | let lineresult = get(dc_result, linenr - 1, s:err_notavail)
218 | if !empty(lineresult)
219 | let updatedline = substitute(curline,
220 | \ '$',
221 | \ printf('\=repeat(" ", %d)."%s %s"',
222 | \ fillcount, rchar, escape(lineresult, '"')),
223 | \ "")
224 | call setline(linenr, updatedline)
225 | endif
226 | let b:cdeck_results[linenr] = lineresult
227 | let linenr += 1
228 | endwhile
229 |
230 | " auto-align 'hiding comments'
231 | if autoac
232 | call colddeck#AlignHidingComments()
233 | endif
234 |
235 | " restore cursor pos
236 | call setpos('.', curpos)
237 |
238 | " Ignore results insertion for modified status
239 | let &modified = bufmodified
240 | endfun
241 |
242 |
243 | " colddeck#RemoveResults()
244 | "
245 | " Remove results from buffer (text after rcol)
246 | "
247 | function! colddeck#RemoveResults() abort
248 | let bufmodified = &modified
249 | let curpos = getcurpos()
250 | let rcol = get(b:, 'cdeck_rcol', get(g:, 'cdeck_rcol', s:def_rcol))
251 | silent exe '%s/\v^.*\S\zs\s*%(%'.rcol.'v.*\S.*)$//e'
252 | call setpos('.', curpos)
253 | let &modified = bufmodified
254 | endfun
255 |
256 |
257 | " colddeck#MoveRcol()
258 | "
259 | " Move result column
260 | "
261 | " Args:
262 | " - number (absolute position), with '+/-' prefix for relative motion
263 | "
264 | function! colddeck#MoveRcol(col) abort
265 | call colddeck#RemoveResults()
266 | if a:col[0] =~ '[+-]'
267 | " relative motion
268 | let cur_rcol = get(b:, 'cdeck_rcol', get(g:, 'cdeck_rcol', s:def_rcol))
269 | let b:cdeck_rcol = cur_rcol + str2nr(a:col)
270 | else
271 | let b:cdeck_rcol = a:col
272 | endif
273 | call colddeck#CalcBuffer()
274 | endfun
275 |
276 |
277 | " colddeck#AlignHidingComments()
278 | "
279 | " Right-align 'hiding comments' near results
280 | "
281 | function! colddeck#AlignHidingComments() abort
282 | let bufmodified = &modified
283 | let rcol = get(b:, 'cdeck_rcol', get(g:, 'cdeck_rcol', s:def_rcol))
284 | silent exe '%s/\v(##.*\S)(\s+)\ze%'.rcol.'v./\2\1/e'
285 | let &modified = bufmodified
286 | endfun
287 |
288 |
289 | " Autocmds {{{2
290 | "---------------
291 |
292 | " colddeck#SetAutoCalc()
293 | "
294 | " Add events to insert results automatically
295 | " (currently, only on InsertLeave)
296 | "
297 | function! colddeck#SetAutoCalc() abort
298 | if !get(b:, 'cdeck_auto_', 0)
299 | autocmd InsertLeave call colddeck#CalcBuffer()
300 | let b:cdeck_auto_ = 1
301 | endif
302 | endfun
303 |
304 |
305 | " colddeck#UnsetAutoCalc()
306 | "
307 | " Delete events that inserted results automatically
308 | "
309 | function! colddeck#UnsetAutoCalc() abort
310 | if get(b:, 'cdeck_auto_', 0)
311 | autocmd! InsertLeave
312 | let b:cdeck_auto_ = 0
313 | endif
314 | endfun
315 |
316 |
317 | " Debug {{{2
318 | "------------
319 | function! s:Dbg(msg, ...) abort
320 | if g:cdeck_debug
321 | let m = a:msg
322 | if a:0
323 | let m .= " [".join(a:000, "] [")."]"
324 | endif
325 | echom m
326 | endif
327 | endfun
328 |
329 |
330 | let &cpo = s:save_cpo
331 |
--------------------------------------------------------------------------------
/doc/colddeck.txt:
--------------------------------------------------------------------------------
1 | *colddeck.txt* Column dc *colddeck*
2 |
3 | Colddeck MANUAL
4 |
5 | 1. About colddeck |colddeck-about|
6 | 2. Quick Start |colddeck-quickstart|
7 | 3. Syntax |colddeck-syntax|
8 | 4. Default Mappings |colddeck-default-mappings|
9 | 5. Commands |colddeck-commands|
10 | 6. Options |colddeck-options|
11 | 7. Changelog |colddeck-changelog|
12 | 8. Contribute |colddeck-contribute|
13 | 9. License |colddeck-license|
14 |
15 | =============================================================================
16 | ABOUT COLDDECK *colddeck-about*
17 |
18 | Colddeck turns Vim into a simple column-based spreadsheet, ala instacalc.com.
19 |
20 | All lines are fed into the `dc` program, that must be installed on your system.
21 |
22 | Features:
23 |
24 | - RPN-based computations
25 | - References to other rows
26 | - Ranges
27 | - Aggregates (sum, min/max, average...)
28 | - Vim expressions (experimental)
29 | - Value references (experimental)
30 |
31 | =============================================================================
32 | QUICK START *colddeck-quickstart*
33 |
34 | 1. Install the plugin Eg. with Pathogen:
35 | >
36 | cd ~/.vim/bundle && git clone https://github.com/fcpg/vim-colddeck
37 | <
38 | or using vim8 package management:
39 | >
40 | cd ~/.vim/pack/std/start && git clone https://github.com/fcpg/vim-colddeck
41 | <
42 | 2. Open a file with the `.cdeck` extension:
43 | >
44 | vim budget.cdeck
45 | <
46 | 3. Insert some lines on top (comments included):
47 | >
48 | 300 # food
49 | 800 # rent
50 | 50 # bills
51 | 250 # misc
52 | R1:R4@sum ## Total
53 | R5 12* ## Yearly
54 | <
55 | =============================================================================
56 | SYNTAX *colddeck-syntax*
57 |
58 | Each line is a `dc` command, that will be fed directly to `dc`, from top to
59 | bottom. Each command is run on an empty stack. Once the command is run, the
60 | result inserted into the buffer is the one at the top of the stack.
61 |
62 | Lines can include comments, starting with `#`. They are not passed to `dc`.
63 |
64 | Comments with double hash (`##`) hide the command part, and the comment text
65 | becomes right-aligned by default. Delete one hash to edit the command again.
66 |
67 | Commands can reference other lines with the `R+num` syntax, eg. `R1`, `R3` etc.
68 | Internally, commands are stored as macros, and they are executed each time
69 | they are referenced.
70 |
71 | Relative references are in the form `R+1` and `R-2`, to refer to the next row
72 | or the second row above, respectively.
73 |
74 | Several references can be used with ranges, using the syntax `ref:ref`, eg.
75 | `R1:R3`. This will insert the values from the range, with the total number
76 | of inserted elements at the top of the stack (so, `R1:R3` will insert the
77 | value of `R1`, `R2` and `R3`, with an extra `3` on top of the stack.
78 |
79 | A few aggregates are available, implemented internally with `dc` macros:
80 | - `@sum`
81 | - `@prod`
82 | - `@avg`
83 | - `@min`
84 | - `@max`
85 |
86 | They expected values on the stack, with the number of elements on top.
87 | This makes it easy to work with ranges:
88 | >
89 | R1:R3 @sum
90 | <
91 | will compute the sum from `R1` to `R3`.
92 |
93 | Experimental: vim expressions can be inserted on the line, before feeding
94 | the line to `dc`. It is thus a kind of vim preprocessor:
95 | >
96 | `log(2)` 2*
97 | <
98 | will double the natural log of 2.
99 |
100 | Experimental: the result of another line can be referenced with the `$+num`
101 | syntax eg. `$2`. This means the result must already be availble, ie.
102 | computations have at least be run once. This allows things like:
103 | >
104 | `sin($2)`
105 | <
106 | which can be convenient since good old `dc` does not offer much maths
107 | functions.
108 |
109 | A few notes:
110 | - dc registers under chr(48) are reserved for internal purposes.
111 | - The `?` register contains the string `True`, allowing things like `0 0=?` .
112 | This is for mere convenience, and can be overridden if need be.
113 | - Commands can return several values; only the last one will be shown on
114 | result, but all values will be used by other references.
115 |
116 | =============================================================================
117 | DEFAULT MAPPINGS *colddeck-default-mappings*
118 |
119 | x
120 | Compute results and insert them into buffer.
121 |
122 | c
123 | Clear results from buffer.
124 |
125 | a
126 | Toggle automatic insertion/updates of results.
127 |
128 | A
129 | Toggle automatic right-alignment of "hiding comments" (`## comment`).
130 |
131 | h
132 | Toggle normal and "hiding" comments (`## comment`).
133 |
134 | $
135 | Move cursor to end of line, ignoring the results part.
136 |
137 | <
138 | Move all results five chars to the left (also takes numeric argument).
139 |
140 | >
141 | Move all results five chars to the right (also takes numeric argument).
142 |
143 | =============================================================================
144 | COMMANDS *colddeck-commands*
145 |
146 | :CDCalc *:CDCalc*
147 | Compute results and insert them into buffer.
148 |
149 | :CDClear *:CDClear*
150 | Clear results from buffer.
151 |
152 | :CDToggleAutocalc *:CDToggleAutocalc*
153 | Toggle automatic insertion/updates of results.
154 |
155 | :CDAlignHidingComments *:CDAlignHidingComments*
156 | Toggle automatic right-alignment of "hiding comments" (`## comment`).
157 |
158 | :CDToggleHidingComments *:CDToggleHidingComments*
159 | Toggle norma / "hiding" comments" (`## comment`).
160 |
161 | :CDMoveRCol {col} *:CDMoveRCol*
162 | Move all results to the {col} column.
163 | If {col} starts with a -/+, it moves all results of that many columns
164 | to the left/right.
165 |
166 | =============================================================================
167 | OPTIONS *colddeck-options*
168 |
169 | g:cdeck_autocalc *g:cdeck_autocalc*
170 | Set to 0 to disable automatic computation and insertion
171 | of results.
172 | Default: 1
173 |
174 | g:cdeck_rcol *g:cdeck_rcol*
175 | Column where results will be inserted.
176 | Global or buffer-local.
177 | Default: 78
178 |
179 | g:cdeck_prec *g:cdeck_prec*
180 | Precision, for floats.
181 | Global or buffer-local.
182 | Default: 2
183 |
184 | g:cdeck_precmd *g:cdeck_precmd*
185 | User-defined dc commands to run at each invocation.
186 | Global or buffer-local.
187 | Default: none
188 |
189 | g:cdeck_autoahc *g:cdeck_autoahc*
190 | Set to 0 to disable automatic 'hidden comments' alignement.
191 | Global or buffer-local.
192 | Default: 1
193 |
194 | g:cdeck_rchar *g:cdeck_rchar*
195 | Char separating buffer content from results.
196 | Global or buffer-local.
197 | Default: `>`
198 |
199 | g:cdeck_saveresults *g:cdeck_saveresults*
200 | Set to 1 to include results when saving buffer.
201 | Global or buffer-local.
202 | Default: 0
203 |
204 | g:cdeck_nomaps *g:cdeck_nomaps*
205 | Set to 1 to disable buffer-local mappings creation in
206 | colddeck buffers.
207 | Default: 0
208 |
209 | g:cdeck_dcerr *g:cdeck_dcerr*
210 | Set to 1 to show dc error messages for debugging purposes.
211 | Warning: will mess with results.
212 | Global or buffer-local.
213 | Default: 0
214 |
215 | =============================================================================
216 | CHANGELOG *colddeck-changelog*
217 |
218 | [1.0] - 2019-03-19
219 | - Initial release
220 |
221 | =============================================================================
222 | CONTRIBUTE *colddeck-contribute*
223 |
224 | Contribute on [Github](https://github.com/fcpg/vim-colddeck)
225 |
226 | =============================================================================
227 | LICENSE *colddeck-license*
228 |
229 | [Attribution-ShareAlike 4.0 Int.](https://creativecommons.org/licenses/by-sa/4.0/)
230 |
231 | vim: set expandtab sts=2 ts=2 sw=2 tw=78 ft=help norl:
232 |
--------------------------------------------------------------------------------
/ftdetect/colddeck.vim:
--------------------------------------------------------------------------------
1 | autocmd BufNewFile,BufRead *.cdeck set filetype=colddeck
2 |
--------------------------------------------------------------------------------
/ftplugin/colddeck.vim:
--------------------------------------------------------------------------------
1 | " Vim filetype plugin file
2 | " Language: colddeck
3 |
4 | if exists("b:did_ftplugin")
5 | finish
6 | endif
7 | let b:did_ftplugin = 1
8 |
9 | let b:undo_ftplugin = "setl cc< nu< | unlet! b:cdeck_results"
10 |
11 | let &l:cc = get(g:, 'cdeck_rcol', 78)
12 | setl nu
13 |
14 | let b:cdeck_results = {}
15 |
16 | if get(b:, 'cdeck_autocalc', get(g:, 'cdeck_autocalc', 1))
17 | call colddeck#SetAutoCalc()
18 | endif
19 |
20 | "---------------
21 | " Mappings {{{1
22 | "---------------
23 |
24 | if !get(g:, 'cdeck_nomaps', 0)
25 | nnoremap x :CDCalc
26 | nnoremap c :CDClear
27 | nnoremap a :CDToggleAutocalc
28 | nnoremap A :CDAlignHidingComments
29 |
30 | nnoremap h :CDToggleHidingComments
31 | nnoremap <
32 | \ :CDMoveRCol =empty(v:count)? "-5" : v:count
33 | nnoremap >
34 | \ :CDMoveRCol =empty(v:count)? "+5" : v:count
35 | nnoremap $ :call search('\v^.*\zs\S\ze%<'.
36 | \ (get(b:, "cdeck_rcol", get(g:, "cdeck_rcol", 78))+1) . 'v.',
37 | \ '',
38 | \ line('.'))
39 | endif
40 |
--------------------------------------------------------------------------------
/plugin/colddeck.vim:
--------------------------------------------------------------------------------
1 | " colddeck.vim - column-dc spreadsheet
2 |
3 | let s:save_cpo = &cpo
4 | set cpo&vim
5 |
6 | "---------------
7 | " Commands {{{1
8 | "---------------
9 |
10 | " Re-calculate values and insert results
11 | command! -bar CDCalc
12 | \ call colddeck#CalcBuffer()
13 |
14 | " Clear results
15 | command! -bar CDClear
16 | \ call colddeck#RemoveResults()
17 |
18 | " Toggle autocalc (auto-insertion of results when leaving insert mode)
19 | command! -bar CDToggleAutocalc
20 | \ if !get(b:, 'cdeck_auto_', 0)
21 | \| call colddeck#SetAutoCalc()
22 | \| echo "AutoCalc ON"
23 | \| else
24 | \| call colddeck#UnsetAutoCalc()
25 | \| echo "AutoCalc OFF"
26 | \| endif
27 |
28 | " Move the result column (absolute pos, or relative with +/- prefix)
29 | command! -bar -nargs=1 CDMoveRCol
30 | \ call colddeck#MoveRcol()
31 |
32 | " Right-align 'hiding comments' near results
33 | command! -bar CDAlignHidingComments
34 | \ call colddeck#AlignHidingComments()
35 |
36 | " Toggle normal/hiding comments
37 | let s:keeppa = exists(':keeppattern') ? 'keeppa' : ''
38 | command! -bar CDToggleHidingComments
39 | \ if getline('.') =~ '##'
40 | \| silent exe s:keeppa 's/##/# /e'
41 | \| else
42 | \| silent exe s:keeppa 's/# /##/e'
43 | \| endif
44 |
45 |
46 |
47 | "---------------
48 | " Autocmds {{{1
49 | "---------------
50 |
51 | " Discard results before saving file, put them back afterwards
52 | " Can be global or buffer-locxl
53 | augroup CDeckSave
54 | au!
55 | autocmd BufWritePre *.cdeck
56 | \ if !get(b:, 'cdeck_saveresults', get(g:, 'cdeck_saveresults', 0))
57 | \| call colddeck#RemoveResults()
58 | \| endif
59 | autocmd BufWritePost *.cdeck
60 | \ if !get(b:, 'cdeck_saveresults', get(g:, 'cdeck_saveresults', 0))
61 | \| call colddeck#CalcBuffer()
62 | \| endif
63 | augroup END
64 |
65 | " Activate autocalc for cdeck filetype if option is set
66 | " Global only
67 | augroup CDeckFiletype
68 | au!
69 | if get(g:, 'cdeck_autocalc', 1)
70 | autocmd FileType colddeck call colddeck#CalcBuffer()
71 | endif
72 | augroup END
73 |
74 |
75 | let &cpo = s:save_cpo
76 |
--------------------------------------------------------------------------------
/syntax/colddeck.vim:
--------------------------------------------------------------------------------
1 | " Vim syntax file
2 | " FileType: colddeck
3 | " Author: fcpg
4 | " Version: 1.0
5 | " ---------------------------------------------------------------------
6 |
7 | syntax clear
8 | syntax case match
9 |
10 |
11 | " Syntax
12 |
13 | syn match cdeckLine /\v^.+$/ contains=cdeckCommand,cdeckComment
14 | syn match cdeckCommand /\v^[^#]+/ contains=cdeckCmdRef,cdeckCmdFunc,cdeckCmdOp,cdeckCmdStr,cdeckResult contained
15 | syn match cdeckCmdRef /\vR\d+/ contained
16 | syn match cdeckCmdFunc /\v\@%(sum|min|max|avg|prod)/ contained
17 | syn match cdeckCmdOp /[+*/%~|:^;<>=!?]/ contained
18 | syn region cdeckCmdStr matchgroup=cdeckCmdDelim start="\[" end="\]" contained contains=cdeckCmdStr keepend extend oneline
19 | syn match cdeckComment /\v#.*/ contains=cdeckResult contained
20 |
21 | syn match cdeckHiddenLine /\v^.+##.*$/ contains=cdeckHiddenCommand,cdeckHidingComment
22 | syn match cdeckHiddenCommand /\v^[^#]+/ contains=cdeckResult contained
23 | syn match cdeckHidingComment /\v##.*/ contains=cdeckResult,cdeckHidingCommentMark contained
24 | syn match cdeckHidingCommentMark /##/ contained
25 |
26 | exe 'syn match cdeckResult /\V\s\zs'.get(g:, 'cdeck_rchar', '>').'\.\+\$/ contains=cdeckResSep contained'
27 | exe 'syn match cdeckResSep /\V'.get(g:, 'cdeck_rchar', '>').'/ contained'
28 |
29 |
30 | " Highlights
31 |
32 | hi cdeckInvisible guifg=bg guibg=bg ctermbg=bg ctermfg=bg
33 |
34 | hi link cdeckCommand Normal
35 | hi link cdeckCmdRef Identifier
36 | hi link cdeckCmdFunc Function
37 | hi link cdeckCmdOp Operator
38 | hi link cdeckCmdStr String
39 | hi link cdeckCmdDelim Delimiter
40 | hi link cdeckComment Title
41 | hi link cdeckResult Special
42 | hi link cdeckResSep Comment
43 |
44 | hi link cdeckHiddenCommand cdeckInvisible
45 | hi link cdeckHidingComment cdeckComment
46 | hi link cdeckHidingCommentMark Comment
47 |
48 | let b:current_syntax = "colddeck"
49 |
--------------------------------------------------------------------------------