cell.vim 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. " Private Functions {{{1
  2. " function! s:ParseRange(range, ...) {{{2
  3. " range: A string representing range of cells.
  4. " - Can be row1:row2 for values in the current columns in those rows.
  5. " - Can be row1,col1:row2,col2 for range between row1,col1 till
  6. " row2,col2.
  7. function! s:ParseRange(range, ...)
  8. if a:0 < 1
  9. let default_col = tablemode#spreadsheet#ColumnNr('.')
  10. elseif a:0 < 2
  11. let default_col = a:1
  12. endif
  13. if type(a:range) != type('')
  14. let range = string(a:range)
  15. else
  16. let range = a:range
  17. endif
  18. let [rowcol1, rowcol2] = split(range, ':')
  19. let [rcs1, rcs2] = [map(split(rowcol1, ','), 'str2nr(v:val)'), map(split(rowcol2, ','), 'str2nr(v:val)')]
  20. if len(rcs1) == 2
  21. let [row1, col1] = rcs1
  22. else
  23. let [row1, col1] = [rcs1[0], default_col]
  24. endif
  25. if len(rcs2) == 2
  26. let [row2, col2] = rcs2
  27. else
  28. let [row2, col2] = [rcs2[0], default_col]
  29. endif
  30. return [row1, col1, row2, col2]
  31. endfunction
  32. " Public Functions {{{1
  33. " function! tablemode#spreadsheet#cell#GetCells() - Function to get values of cells in a table {{{2
  34. " tablemode#spreadsheet#GetCells(row) - Get values of all cells in a row as a List.
  35. " tablemode#spreadsheet#GetCells(0, col) - Get values of all cells in a column as a List.
  36. " tablemode#spreadsheet#GetCells(row, col) - Get the value of table cell by given row, col.
  37. function! tablemode#spreadsheet#cell#GetCells(line, ...) abort
  38. let line = tablemode#utils#line(a:line)
  39. if tablemode#table#IsRow(line)
  40. if a:0 < 1
  41. let [row, colm] = [line, 0]
  42. elseif a:0 < 2
  43. let [row, colm] = [a:1, 0]
  44. elseif a:0 < 3
  45. let [row, colm] = a:000
  46. endif
  47. let first_row = tablemode#spreadsheet#GetFirstRow(line)
  48. let last_row = tablemode#spreadsheet#GetLastRow(line)
  49. if row == 0
  50. let values = []
  51. let line = first_row
  52. while tablemode#table#IsTable(line)
  53. if tablemode#table#IsRow(line)
  54. let row_line = getline(line)[stridx(getline(line), g:table_mode_separator):strridx(getline(line), g:table_mode_separator)]
  55. call add(values, tablemode#utils#strip(get(split(row_line, g:table_mode_separator), colm>0?colm-1:colm, '')))
  56. endif
  57. let line += 1
  58. endwhile
  59. return values
  60. else
  61. let row_nr = 0
  62. let row_diff = row > 0 ? 1 : -1
  63. let line = row > 0 ? first_row : last_row
  64. while tablemode#table#IsTable(line)
  65. if tablemode#table#IsRow(line)
  66. let row_nr += row_diff
  67. if row ==# row_nr | break | endif
  68. endif
  69. let line += row_diff
  70. endwhile
  71. let row_line = getline(line)[stridx(getline(line), g:table_mode_separator):strridx(getline(line), g:table_mode_separator)]
  72. if colm == 0
  73. return map(split(row_line, g:table_mode_separator), 'tablemode#utils#strip(v:val)')
  74. else
  75. let split_line = split(row_line, g:table_mode_separator)
  76. return tablemode#utils#strip(get(split(row_line, g:table_mode_separator), colm>0?colm-1:colm, ''))
  77. endif
  78. endif
  79. endif
  80. endfunction
  81. function! tablemode#spreadsheet#cell#GetCell(...) "{{{2
  82. if a:0 == 0
  83. let [row, colm] = [tablemode#spreadsheet#RowNr('.'), tablemode#spreadsheet#ColumnNr('.')]
  84. elseif a:0 == 2
  85. let [row, colm] = [a:1, a:2]
  86. endif
  87. return tablemode#spreadsheet#cell#GetCells('.', row, colm)
  88. endfunction
  89. function! tablemode#spreadsheet#cell#GetRow(row, ...) abort "{{{2
  90. let line = a:0 ? a:1 : '.'
  91. return tablemode#spreadsheet#cell#GetCells(line, a:row)
  92. endfunction
  93. function! tablemode#spreadsheet#cell#GetRowColumn(col, ...) abort "{{{2
  94. let line = a:0 ? a:1 : '.'
  95. let row = tablemode#spreadsheet#RowNr('.')
  96. return tablemode#spreadsheet#cell#GetCells(line, row, a:col)
  97. endfunction
  98. function! tablemode#spreadsheet#cell#GetColumn(col, ...) abort "{{{2
  99. let line = a:0 ? a:1 : '.'
  100. return tablemode#spreadsheet#cell#GetCells(line, 0, a:col)
  101. endfunction
  102. function! tablemode#spreadsheet#cell#GetColumnRow(row, ...) abort "{{{2
  103. let line = a:0 ? a:1 : '.'
  104. let col = tablemode#spreadsheet#ColumnNr('.')
  105. return tablemode#spreadsheet#cell#GetCells(line, a:row, col)
  106. endfunction
  107. function! tablemode#spreadsheet#cell#GetCellRange(range, ...) abort "{{{2
  108. if a:0 < 1
  109. let [line, colm] = ['.', tablemode#spreadsheet#ColumnNr('.')]
  110. elseif a:0 < 2
  111. let [line, colm] = [a:1, tablemode#spreadsheet#ColumnNr('.')]
  112. elseif a:0 < 3
  113. let [line, colm] = [a:1, a:2]
  114. else
  115. call tablemode#utils#throw('Invalid Range')
  116. endif
  117. let values = []
  118. if tablemode#table#IsRow(line)
  119. let [row1, col1, row2, col2] = s:ParseRange(a:range, colm)
  120. if row1 == row2
  121. if col1 == col2
  122. call add(values, tablemode#spreadsheet#cell#GetCells(line, row1, col1))
  123. else
  124. let values = tablemode#spreadsheet#cell#GetRow(row1, line)[(col1-1):(col2-1)]
  125. endif
  126. else
  127. if col1 == col2
  128. let values = tablemode#spreadsheet#cell#GetColumn(col1, line)[(row1-1):(row2-1)]
  129. else
  130. let tcol = col1
  131. while tcol <= col2
  132. call add(values, tablemode#spreadsheet#cell#GetColumn(tcol, line)[(row1-1):(row2-1)])
  133. let tcol += 1
  134. endwhile
  135. endif
  136. endif
  137. endif
  138. return values
  139. endfunction
  140. function! tablemode#spreadsheet#cell#SetCell(val, ...) "{{{2
  141. if a:0 == 0
  142. let [line, row, colm] = ['.', tablemode#spreadsheet#RowNr('.'), tablemode#spreadsheet#ColumnNr('.')]
  143. elseif a:0 == 2
  144. let [line, row, colm] = ['.', a:1, a:2]
  145. elseif a:0 == 3
  146. let [line, row, colm] = a:000
  147. endif
  148. " Account for negative values to reference from relatively from the last
  149. if row < 0 | let row = tablemode#spreadsheet#RowCount(line) + row + 1 | endif
  150. if colm < 0 | let colm = tablemode#spreadsheet#ColumnCount(line) + colm + 1 | endif
  151. if tablemode#table#IsRow(line)
  152. let line = tablemode#spreadsheet#LineNr(line, row)
  153. let line_val = getline(line)
  154. let cstartexpr = tablemode#table#StartCommentExpr()
  155. let values = split(getline(line)[stridx(line_val, g:table_mode_separator):strridx(line_val, g:table_mode_separator)], g:table_mode_separator)
  156. if len(values) < colm | return | endif
  157. let values[colm-1] = a:val
  158. let line_value = g:table_mode_separator . join(values, g:table_mode_separator) . g:table_mode_separator
  159. if tablemode#utils#strlen(cstartexpr) > 0 && line_val =~# cstartexpr
  160. let sce = matchstr(line_val, tablemode#table#StartCommentExpr())
  161. let ece = matchstr(line_val, tablemode#table#EndCommentExpr())
  162. let line_value = sce . line_value . ece
  163. endif
  164. call setline(line, line_value)
  165. call tablemode#table#Realign(line)
  166. endif
  167. endfunction
  168. function! tablemode#spreadsheet#cell#TextObject(inner) "{{{2
  169. if tablemode#table#IsRow('.')
  170. call tablemode#spreadsheet#MoveToStartOfCell()
  171. if a:inner
  172. normal! v
  173. call search('[^' . g:table_mode_separator . ']\ze\s*' . g:table_mode_separator)
  174. else
  175. execute 'normal! vf' . g:table_mode_separator . 'l'
  176. endif
  177. endif
  178. endfunction
  179. function! tablemode#spreadsheet#cell#Motion(direction, ...) "{{{2
  180. let l:count = a:0 ? a:1 : v:count1
  181. if tablemode#table#IsRow('.')
  182. for ii in range(l:count)
  183. if a:direction ==# 'l'
  184. if tablemode#spreadsheet#IsLastCell()
  185. if !tablemode#table#IsRow(line('.') + 1) && (tablemode#table#IsBorder(line('.') + 1) && !tablemode#table#IsRow(line('.') + 2))
  186. return
  187. endif
  188. call tablemode#spreadsheet#cell#Motion('j', 1)
  189. normal! 0
  190. endif
  191. " If line starts with g:table_mode_separator
  192. if getline('.')[col('.')-1] ==# g:table_mode_separator
  193. normal! 2l
  194. else
  195. execute 'normal! f' . g:table_mode_separator . '2l'
  196. endif
  197. elseif a:direction ==# 'h'
  198. if tablemode#spreadsheet#IsFirstCell()
  199. if !tablemode#table#IsRow(line('.') - 1) && (tablemode#table#IsBorder(line('.') - 1) && !tablemode#table#IsRow(line('.') - 2))
  200. return
  201. endif
  202. call tablemode#spreadsheet#cell#Motion('k', 1)
  203. normal! $
  204. endif
  205. " If line ends with g:table_mode_separator
  206. if getline('.')[col('.')-1] ==# g:table_mode_separator
  207. execute 'normal! F' . g:table_mode_separator . '2l'
  208. else
  209. execute 'normal! 2F' . g:table_mode_separator . '2l'
  210. endif
  211. elseif a:direction ==# 'j'
  212. if tablemode#table#IsRow(line('.') + 1)
  213. " execute 'normal! ' . 1 . 'j'
  214. normal! j
  215. elseif tablemode#table#IsBorder(line('.') + 1) && tablemode#table#IsRow(line('.') + 2)
  216. " execute 'normal! ' . 2 . 'j'
  217. normal! 2j
  218. endif
  219. elseif a:direction ==# 'k'
  220. if tablemode#table#IsRow(line('.') - 1)
  221. " execute 'normal! ' . 1 . 'k'
  222. normal! k
  223. elseif tablemode#table#IsBorder(line('.') - 1) && tablemode#table#IsRow(line('.') - 2)
  224. " execute 'normal! ' . (1 + 1) . 'k'
  225. normal! 2k
  226. endif
  227. endif
  228. endfor
  229. endif
  230. endfunction
  231. " vim: sw=2 sts=2 fdl=0 fdm=marker